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