1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_dbaccess.hxx" 30 31 #include "databaseobjectview.hxx" 32 #include "dbustrings.hrc" 33 #include "asyncmodaldialog.hxx" 34 35 /** === begin UNO includes === **/ 36 #include <com/sun/star/lang/XSingleServiceFactory.hpp> 37 #include <com/sun/star/frame/XDispatchProvider.hpp> 38 #include <com/sun/star/frame/XFrame.hpp> 39 #include <com/sun/star/frame/XFrames.hpp> 40 #include <com/sun/star/frame/FrameSearchFlag.hpp> 41 #include <com/sun/star/sdb/CommandType.hpp> 42 #include <com/sun/star/sdb/application/XTableUIProvider.hpp> 43 #include <com/sun/star/beans/NamedValue.hpp> 44 #include <com/sun/star/awt/Rectangle.hpp> 45 /** === end UNO includes === **/ 46 47 #include <comphelper/extract.hxx> 48 #include <comphelper/sequence.hxx> 49 #include <connectivity/dbtools.hxx> 50 #include <osl/diagnose.h> 51 #include <toolkit/helper/vclunohelper.hxx> 52 #include <tools/diagnose_ex.h> 53 #include <vcl/window.hxx> 54 55 // ......................................................................... 56 namespace dbaui 57 { 58 // ......................................................................... 59 60 using namespace ::com::sun::star::uno; 61 using namespace ::com::sun::star::sdbc; 62 using namespace ::com::sun::star::sdb; 63 using namespace ::com::sun::star::sdb::application; 64 using namespace ::com::sun::star::ui::dialogs; 65 using namespace ::com::sun::star::frame; 66 using namespace ::com::sun::star::lang; 67 using namespace ::com::sun::star::beans; 68 using namespace ::com::sun::star::awt; 69 70 //====================================================================== 71 //= DatabaseObjectView 72 //====================================================================== 73 DatabaseObjectView::DatabaseObjectView( const Reference< XMultiServiceFactory >& _rxORB, 74 const Reference< XDatabaseDocumentUI >& _rxApplication, 75 const Reference< XFrame >& _rxParentFrame, 76 const ::rtl::OUString& _rComponentURL ) 77 :m_xORB ( _rxORB ) 78 ,m_xParentFrame ( _rxParentFrame ) 79 ,m_xFrameLoader ( ) 80 ,m_xApplication ( _rxApplication ) 81 ,m_sComponentURL ( _rComponentURL ) 82 { 83 OSL_ENSURE( m_xORB.is(), "DatabaseObjectView::DatabaseObjectView: invalid service factory!" ); 84 OSL_ENSURE( m_xApplication.is(), "DatabaseObjectView::DatabaseObjectView: invalid connection!" ); 85 } 86 87 //---------------------------------------------------------------------- 88 Reference< XConnection > DatabaseObjectView::getConnection() const 89 { 90 Reference< XConnection > xConnection; 91 if ( m_xApplication.is() ) 92 xConnection = m_xApplication->getActiveConnection(); 93 return xConnection; 94 } 95 96 //---------------------------------------------------------------------- 97 Reference< XComponent > DatabaseObjectView::createNew( const Reference< XDataSource >& _xDataSource, const ::comphelper::NamedValueCollection& i_rDispatchArgs ) 98 { 99 return doCreateView( makeAny( _xDataSource ), ::rtl::OUString(), i_rDispatchArgs ); 100 } 101 102 //---------------------------------------------------------------------- 103 Reference< XComponent > DatabaseObjectView::openExisting( const Any& _rDataSource, const ::rtl::OUString& _rName, 104 const ::comphelper::NamedValueCollection& i_rDispatchArgs ) 105 { 106 return doCreateView( _rDataSource, _rName, i_rDispatchArgs ); 107 } 108 109 //---------------------------------------------------------------------- 110 Reference< XComponent > DatabaseObjectView::doCreateView( const Any& _rDataSource, const ::rtl::OUString& _rObjectName, 111 const ::comphelper::NamedValueCollection& i_rCreationArgs ) 112 { 113 ::comphelper::NamedValueCollection aDispatchArgs; 114 115 aDispatchArgs.merge( i_rCreationArgs, false ); // false => do not overwrite 116 fillDispatchArgs( aDispatchArgs, _rDataSource, _rObjectName ); 117 aDispatchArgs.merge( i_rCreationArgs, true ); // true => do overwrite 118 119 return doDispatch( aDispatchArgs ); 120 } 121 122 //---------------------------------------------------------------------- 123 Reference< XComponent > DatabaseObjectView::doDispatch( const ::comphelper::NamedValueCollection& i_rDispatchArgs ) 124 { 125 Reference< XComponent > xReturn; 126 if ( m_xORB.is() ) 127 { 128 try 129 { 130 // if we have no externally provided frame, create one 131 if ( !m_xFrameLoader.is() ) 132 { 133 Reference< XSingleServiceFactory > xFact(m_xORB->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.TaskCreator")), UNO_QUERY_THROW); 134 Sequence< Any > lArgs(2); 135 NamedValue aProp; 136 sal_Int32 nArg = 0; 137 138 aProp.Name = ::rtl::OUString::createFromAscii("ParentFrame"); 139 aProp.Value <<= m_xParentFrame; 140 lArgs[nArg++] <<= aProp; 141 142 aProp.Name = ::rtl::OUString::createFromAscii("TopWindow"); 143 aProp.Value <<= sal_True; 144 lArgs[nArg++] <<= aProp; 145 146 m_xFrameLoader.set(xFact->createInstanceWithArguments(lArgs), UNO_QUERY_THROW); 147 148 // everything we load can be considered a "top level document", so set the respective bit at the window. 149 // This, amongst other things, triggers that the component in this task participates in the 150 // "ThisComponent"-game for the global application Basic. 151 const Reference< XFrame > xFrame( m_xFrameLoader, UNO_QUERY_THROW ); 152 const Reference< XWindow > xFrameWindow( xFrame->getContainerWindow(), UNO_SET_THROW ); 153 Window* pContainerWindow = VCLUnoHelper::GetWindow( xFrameWindow ); 154 ENSURE_OR_THROW( pContainerWindow, "no implementation access to the frame's container window!" ); 155 pContainerWindow->SetExtendedStyle( pContainerWindow->GetExtendedStyle() | WB_EXT_DOCUMENT ); 156 } 157 158 Reference< XComponentLoader > xFrameLoader( m_xFrameLoader, UNO_QUERY_THROW ); 159 xReturn = xFrameLoader->loadComponentFromURL( 160 m_sComponentURL, 161 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_self")), 162 0, 163 i_rDispatchArgs.getPropertyValues() 164 ); 165 } 166 catch( const Exception& ) 167 { 168 DBG_UNHANDLED_EXCEPTION(); 169 } 170 } 171 return xReturn; 172 } 173 174 //---------------------------------------------------------------------- 175 void DatabaseObjectView::fillDispatchArgs( 176 ::comphelper::NamedValueCollection& i_rDispatchArgs, 177 const Any& _aDataSource, 178 const ::rtl::OUString& /* _rName */ 179 ) 180 { 181 ::rtl::OUString sDataSource; 182 Reference<XDataSource> xDataSource; 183 if ( _aDataSource >>= sDataSource ) 184 { 185 i_rDispatchArgs.put( (::rtl::OUString)PROPERTY_DATASOURCENAME, sDataSource ); 186 } 187 else if ( _aDataSource >>= xDataSource ) 188 { 189 i_rDispatchArgs.put( (::rtl::OUString)PROPERTY_DATASOURCE, xDataSource ); 190 } 191 192 i_rDispatchArgs.put( (::rtl::OUString)PROPERTY_ACTIVE_CONNECTION, getConnection() ); 193 } 194 195 //====================================================================== 196 //= QueryDesigner 197 //====================================================================== 198 //---------------------------------------------------------------------- 199 QueryDesigner::QueryDesigner( const Reference< XMultiServiceFactory >& _rxORB, const Reference< XDatabaseDocumentUI >& _rxApplication, 200 const Reference< XFrame >& _rxParentFrame, bool _bCreateView ) 201 :DatabaseObjectView( _rxORB, _rxApplication, _rxParentFrame, _bCreateView ? URL_COMPONENT_VIEWDESIGN : URL_COMPONENT_QUERYDESIGN ) 202 ,m_nCommandType( _bCreateView ? CommandType::TABLE : CommandType::QUERY ) 203 { 204 } 205 206 //---------------------------------------------------------------------- 207 void QueryDesigner::fillDispatchArgs( ::comphelper::NamedValueCollection& i_rDispatchArgs, const Any& _aDataSource, 208 const ::rtl::OUString& _rObjectName ) 209 { 210 DatabaseObjectView::fillDispatchArgs( i_rDispatchArgs, _aDataSource, _rObjectName ); 211 212 const bool bIncludeQueryName = 0 != _rObjectName.getLength(); 213 const bool bGraphicalDesign = i_rDispatchArgs.getOrDefault( (::rtl::OUString)PROPERTY_GRAPHICAL_DESIGN, sal_True ); 214 const bool bEditViewAsSQLCommand = ( m_nCommandType == CommandType::TABLE ) && !bGraphicalDesign; 215 216 i_rDispatchArgs.put( (::rtl::OUString)PROPERTY_COMMAND_TYPE, m_nCommandType ); 217 218 if ( bIncludeQueryName ) 219 { 220 i_rDispatchArgs.put( (::rtl::OUString)PROPERTY_COMMAND, _rObjectName ); 221 } 222 223 if ( bEditViewAsSQLCommand ) 224 { 225 i_rDispatchArgs.put( (::rtl::OUString)PROPERTY_ESCAPE_PROCESSING, sal_False ); 226 } 227 } 228 229 //====================================================================== 230 //= TableDesigner 231 //====================================================================== 232 //---------------------------------------------------------------------- 233 TableDesigner::TableDesigner( const Reference< XMultiServiceFactory >& _rxORB, const Reference< XDatabaseDocumentUI >& _rxApplication, const Reference< XFrame >& _rxParentFrame ) 234 :DatabaseObjectView( _rxORB, _rxApplication, _rxParentFrame, static_cast< ::rtl::OUString >( URL_COMPONENT_TABLEDESIGN ) ) 235 { 236 } 237 238 //---------------------------------------------------------------------- 239 void TableDesigner::fillDispatchArgs( ::comphelper::NamedValueCollection& i_rDispatchArgs, const Any& _aDataSource, 240 const ::rtl::OUString& _rObjectName ) 241 { 242 DatabaseObjectView::fillDispatchArgs( i_rDispatchArgs, _aDataSource, _rObjectName ); 243 244 if ( 0 != _rObjectName.getLength() ) 245 { 246 i_rDispatchArgs.put( (::rtl::OUString)PROPERTY_CURRENTTABLE, _rObjectName ); 247 } 248 } 249 250 //---------------------------------------------------------------------- 251 Reference< XComponent > TableDesigner::doCreateView( const Any& _rDataSource, const ::rtl::OUString& _rObjectName, 252 const ::comphelper::NamedValueCollection& i_rCreationArgs ) 253 { 254 bool bIsNewDesign = ( _rObjectName.getLength() == 0 ); 255 256 // let's see whether the connection can provide a dedicated table desginer 257 Reference< XInterface > xDesigner; 258 if ( !bIsNewDesign ) 259 xDesigner = impl_getConnectionProvidedDesigner_nothrow( _rObjectName ); 260 261 if ( !xDesigner.is() ) 262 return DatabaseObjectView::doCreateView( _rDataSource, _rObjectName, i_rCreationArgs ); 263 264 // try whether the designer is a dialog 265 Reference< XExecutableDialog > xDialog( xDesigner, UNO_QUERY_THROW ); 266 if ( xDialog.is() ) 267 { 268 try { AsyncDialogExecutor::executeModalDialogAsync( xDialog ); } 269 catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); } 270 return NULL; 271 } 272 273 Reference< XComponent > xDesignerComponent( xDesigner, UNO_QUERY ); 274 OSL_ENSURE( xDesignerComponent.is(), "TableDesigner::doCreateView: a designer which is no dialog and no component?" ); 275 return xDesignerComponent; 276 } 277 278 //---------------------------------------------------------------------- 279 Reference< XInterface > TableDesigner::impl_getConnectionProvidedDesigner_nothrow( const ::rtl::OUString& _rTableName ) 280 { 281 Reference< XInterface > xDesigner; 282 try 283 { 284 Reference< XTableUIProvider > xTableUIProv( getConnection(), UNO_QUERY ); 285 if ( xTableUIProv.is() ) 286 xDesigner = xTableUIProv->getTableEditor( getApplicationUI(), _rTableName ); 287 } 288 catch( const Exception& ) 289 { 290 DBG_UNHANDLED_EXCEPTION(); 291 } 292 return xDesigner; 293 } 294 295 //====================================================================== 296 //= ResultSetBrowser 297 //====================================================================== 298 //---------------------------------------------------------------------- 299 ResultSetBrowser::ResultSetBrowser( const Reference< XMultiServiceFactory >& _rxORB, const Reference< XDatabaseDocumentUI >& _rxApplication, const Reference< XFrame >& _rxParentFrame, 300 sal_Bool _bTable ) 301 :DatabaseObjectView( _rxORB, _rxApplication, _rxParentFrame, static_cast < ::rtl::OUString >( URL_COMPONENT_DATASOURCEBROWSER ) ) 302 ,m_bTable(_bTable) 303 { 304 } 305 306 //---------------------------------------------------------------------- 307 void ResultSetBrowser::fillDispatchArgs( ::comphelper::NamedValueCollection& i_rDispatchArgs, const Any& _aDataSource, 308 const ::rtl::OUString& _rQualifiedName) 309 { 310 DatabaseObjectView::fillDispatchArgs( i_rDispatchArgs, _aDataSource, _rQualifiedName ); 311 OSL_ENSURE( 0 != _rQualifiedName.getLength(),"A Table name must be set"); 312 ::rtl::OUString sCatalog; 313 ::rtl::OUString sSchema; 314 ::rtl::OUString sTable; 315 if ( m_bTable ) 316 ::dbtools::qualifiedNameComponents( getConnection()->getMetaData(), _rQualifiedName, sCatalog, sSchema, sTable, ::dbtools::eInDataManipulation ); 317 318 i_rDispatchArgs.put( (::rtl::OUString)PROPERTY_COMMAND_TYPE, (m_bTable ? CommandType::TABLE : CommandType::QUERY) ); 319 i_rDispatchArgs.put( (::rtl::OUString)PROPERTY_COMMAND, _rQualifiedName ); 320 i_rDispatchArgs.put( (::rtl::OUString)PROPERTY_ENABLE_BROWSER, sal_False ); 321 322 if ( m_bTable ) 323 { 324 i_rDispatchArgs.put( (::rtl::OUString)PROPERTY_UPDATE_CATALOGNAME, sCatalog ); 325 i_rDispatchArgs.put( (::rtl::OUString)PROPERTY_UPDATE_SCHEMANAME, sSchema ); 326 i_rDispatchArgs.put( (::rtl::OUString)PROPERTY_UPDATE_TABLENAME, sTable ); 327 } 328 } 329 330 //====================================================================== 331 //= RelationDesigner 332 //====================================================================== 333 //---------------------------------------------------------------------- 334 RelationDesigner::RelationDesigner( const Reference< XMultiServiceFactory >& _rxORB, const Reference< XDatabaseDocumentUI >& _rxApplication, const Reference< XFrame >& _rxParentFrame ) 335 :DatabaseObjectView( _rxORB, _rxApplication, _rxParentFrame, static_cast< ::rtl::OUString >( URL_COMPONENT_RELATIONDESIGN ) ) 336 { 337 } 338 // ......................................................................... 339 } // namespace dbaui 340 // ......................................................................... 341 342