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 "dbu_reghelper.hxx" 28 #include "dbustrings.hrc" 29 #include "UITools.hxx" 30 31 /** === begin UNO includes === **/ 32 #include <com/sun/star/container/XChild.hpp> 33 #include <com/sun/star/container/XNameAccess.hpp> 34 #include <com/sun/star/container/XSet.hpp> 35 #include <com/sun/star/document/XEventListener.hpp> 36 #include <com/sun/star/frame/XController2.hpp> 37 #include <com/sun/star/frame/XFrame.hpp> 38 #include <com/sun/star/frame/XFrameLoader.hpp> 39 #include <com/sun/star/frame/XLoadEventListener.hpp> 40 #include <com/sun/star/lang/XInitialization.hpp> 41 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 42 #include <com/sun/star/lang/XServiceInfo.hpp> 43 #include <com/sun/star/lang/XSingleServiceFactory.hpp> 44 #include <com/sun/star/registry/XRegistryKey.hpp> 45 #include <com/sun/star/sdbc/XConnection.hpp> 46 #include <com/sun/star/frame/XModule.hpp> 47 /** === end UNO includes === **/ 48 49 #include <com/sun/star/sdbc/XDataSource.hpp> 50 #include <comphelper/namedvaluecollection.hxx> 51 #include <comphelper/componentcontext.hxx> 52 #include <cppuhelper/implbase2.hxx> 53 #include <toolkit/awt/vclxwindow.hxx> 54 #include <toolkit/helper/vclunohelper.hxx> 55 #include <tools/diagnose_ex.h> 56 #include <tools/urlobj.hxx> 57 #include <vcl/svapp.hxx> 58 59 using namespace ::com::sun::star; 60 using namespace ::com::sun::star::uno; 61 using namespace ::com::sun::star::frame; 62 using namespace ::com::sun::star::beans; 63 using namespace ::com::sun::star::sdbc; 64 using namespace ::com::sun::star::container; 65 using namespace ::com::sun::star::lang; 66 using namespace ::com::sun::star::registry; 67 using ::com::sun::star::sdbc::XDataSource; 68 using namespace dbaui; 69 70 class DBContentLoader : public ::cppu::WeakImplHelper2< XFrameLoader, XServiceInfo> 71 { 72 private: 73 ::rtl::OUString m_aURL; 74 Sequence< PropertyValue> m_aArgs; 75 Reference< XLoadEventListener > m_xListener; 76 Reference< XFrame > m_xFrame; 77 Reference< XMultiServiceFactory > m_xServiceFactory; 78 public: 79 DBContentLoader(const Reference< XMultiServiceFactory >&); 80 ~DBContentLoader(); 81 82 // XServiceInfo 83 ::rtl::OUString SAL_CALL getImplementationName() throw( ); 84 sal_Bool SAL_CALL supportsService(const ::rtl::OUString& ServiceName) throw( ); 85 Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(void) throw( ); 86 87 // static methods 88 static ::rtl::OUString getImplementationName_Static() throw( ) 89 { 90 return ::rtl::OUString::createFromAscii("org.openoffice.comp.dbu.DBContentLoader"); 91 } 92 static Sequence< ::rtl::OUString> getSupportedServiceNames_Static(void) throw( ); 93 static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > 94 SAL_CALL Create(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&); 95 96 // XLoader 97 virtual void SAL_CALL load( const Reference< XFrame > & _rFrame, const ::rtl::OUString& _rURL, 98 const Sequence< PropertyValue >& _rArgs, 99 const Reference< XLoadEventListener > & _rListener) throw(::com::sun::star::uno::RuntimeException); 100 virtual void SAL_CALL cancel(void) throw(); 101 }; 102 DBG_NAME(DBContentLoader) 103 104 DBContentLoader::DBContentLoader(const Reference< XMultiServiceFactory >& _rxFactory) 105 :m_xServiceFactory(_rxFactory) 106 { 107 DBG_CTOR(DBContentLoader,NULL); 108 109 } 110 // ------------------------------------------------------------------------- 111 112 DBContentLoader::~DBContentLoader() 113 { 114 115 DBG_DTOR(DBContentLoader,NULL); 116 } 117 // ------------------------------------------------------------------------- 118 // ------------------------------------------------------------------------- 119 extern "C" void SAL_CALL createRegistryInfo_DBContentLoader() 120 { 121 static ::dbaui::OMultiInstanceAutoRegistration< DBContentLoader > aAutoRegistration; 122 } 123 // ------------------------------------------------------------------------- 124 Reference< XInterface > SAL_CALL DBContentLoader::Create( const Reference< XMultiServiceFactory > & rSMgr ) 125 { 126 return *(new DBContentLoader(rSMgr)); 127 } 128 // ------------------------------------------------------------------------- 129 // XServiceInfo 130 ::rtl::OUString SAL_CALL DBContentLoader::getImplementationName() throw( ) 131 { 132 return getImplementationName_Static(); 133 } 134 // ------------------------------------------------------------------------- 135 136 // XServiceInfo 137 sal_Bool SAL_CALL DBContentLoader::supportsService(const ::rtl::OUString& ServiceName) throw( ) 138 { 139 Sequence< ::rtl::OUString > aSNL = getSupportedServiceNames(); 140 const ::rtl::OUString * pBegin = aSNL.getConstArray(); 141 const ::rtl::OUString * pEnd = pBegin + aSNL.getLength(); 142 for( ; pBegin != pEnd; ++pBegin) 143 if( *pBegin == ServiceName ) 144 return sal_True; 145 return sal_False; 146 } 147 // ------------------------------------------------------------------------- 148 // XServiceInfo 149 Sequence< ::rtl::OUString > SAL_CALL DBContentLoader::getSupportedServiceNames(void) throw( ) 150 { 151 return getSupportedServiceNames_Static(); 152 } 153 // ------------------------------------------------------------------------- 154 // ORegistryServiceManager_Static 155 Sequence< ::rtl::OUString > DBContentLoader::getSupportedServiceNames_Static(void) throw( ) 156 { 157 Sequence< ::rtl::OUString > aSNS( 2 ); 158 aSNS.getArray()[0] = ::rtl::OUString::createFromAscii("com.sun.star.frame.FrameLoader"); 159 aSNS.getArray()[1] = ::rtl::OUString::createFromAscii("com.sun.star.sdb.ContentLoader"); 160 return aSNS; 161 } 162 // ------------------------------------------------------------------------- 163 extern "C" void SAL_CALL writeDBLoaderInfo(void* pRegistryKey) 164 { 165 Reference< XRegistryKey> xKey(reinterpret_cast< XRegistryKey*>(pRegistryKey)); 166 167 // register content loader for dispatch 168 ::rtl::OUString aImpl = ::rtl::OUString::createFromAscii("/"); 169 aImpl += DBContentLoader::getImplementationName_Static(); 170 171 ::rtl::OUString aImpltwo = aImpl; 172 aImpltwo += ::rtl::OUString::createFromAscii("/UNO/Loader"); 173 Reference< XRegistryKey> xNewKey = xKey->createKey( aImpltwo ); 174 aImpltwo = aImpl; 175 aImpltwo += ::rtl::OUString::createFromAscii("/Loader"); 176 Reference< XRegistryKey > xLoaderKey = xKey->createKey( aImpltwo ); 177 xNewKey = xLoaderKey->createKey( ::rtl::OUString::createFromAscii("Pattern") ); 178 xNewKey->setAsciiValue( ::rtl::OUString::createFromAscii(".component:DB*") ); 179 } 180 181 // ----------------------------------------------------------------------- 182 void SAL_CALL DBContentLoader::load(const Reference< XFrame > & rFrame, const ::rtl::OUString& rURL, 183 const Sequence< PropertyValue >& rArgs, 184 const Reference< XLoadEventListener > & rListener) throw(::com::sun::star::uno::RuntimeException) 185 { 186 m_xFrame = rFrame; 187 m_xListener = rListener; 188 m_aURL = rURL; 189 m_aArgs = rArgs; 190 191 ::comphelper::ComponentContext aContext( m_xServiceFactory ); 192 193 struct ServiceNameToImplName 194 { 195 const sal_Char* pAsciiServiceName; 196 const sal_Char* pAsciiImplementationName; 197 ServiceNameToImplName( const sal_Char* _pService, const sal_Char* _pImpl ) 198 :pAsciiServiceName( _pService ) 199 ,pAsciiImplementationName( _pImpl ) 200 { 201 } 202 } aImplementations[] = { 203 ServiceNameToImplName( URL_COMPONENT_FORMGRIDVIEW, "org.openoffice.comp.dbu.OFormGridView" ), 204 ServiceNameToImplName( URL_COMPONENT_DATASOURCEBROWSER, "org.openoffice.comp.dbu.ODatasourceBrowser" ), 205 ServiceNameToImplName( URL_COMPONENT_QUERYDESIGN, "org.openoffice.comp.dbu.OQueryDesign" ), 206 ServiceNameToImplName( URL_COMPONENT_TABLEDESIGN, "org.openoffice.comp.dbu.OTableDesign" ), 207 ServiceNameToImplName( URL_COMPONENT_RELATIONDESIGN, "org.openoffice.comp.dbu.ORelationDesign" ), 208 ServiceNameToImplName( URL_COMPONENT_VIEWDESIGN, "org.openoffice.comp.dbu.OViewDesign" ) 209 }; 210 211 INetURLObject aParser( rURL ); 212 Reference< XController2 > xController; 213 214 const ::rtl::OUString sComponentURL( aParser.GetMainURL( INetURLObject::DECODE_TO_IURI ) ); 215 for ( size_t i=0; i < sizeof( aImplementations ) / sizeof( aImplementations[0] ); ++i ) 216 { 217 if ( sComponentURL.equalsAscii( aImplementations[i].pAsciiServiceName ) ) 218 { 219 aContext.createComponent( aImplementations[i].pAsciiImplementationName, xController ); 220 break; 221 } 222 } 223 224 // if a data source browser is loaded without its tree pane, then we assume it to be a 225 // table data view, effectively. In this case, we need to adjust the module identifier. 226 // 2008-02-05 / i85879 / frank.schoenheit@sun.com 227 ::comphelper::NamedValueCollection aLoadArgs( rArgs ); 228 229 if ( sComponentURL == URL_COMPONENT_DATASOURCEBROWSER ) 230 { 231 sal_Bool bDisableBrowser = ( sal_False == aLoadArgs.getOrDefault( "ShowTreeViewButton", sal_True ) ) // compatibility name 232 || ( sal_False == aLoadArgs.getOrDefault( (::rtl::OUString)PROPERTY_ENABLE_BROWSER, sal_True ) ); 233 234 if ( bDisableBrowser ) 235 { 236 try 237 { 238 Reference< XModule > xModule( xController, UNO_QUERY_THROW ); 239 xModule->setIdentifier( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.TableDataView" ) ) ); 240 } 241 catch( const Exception& ) 242 { 243 DBG_UNHANDLED_EXCEPTION(); 244 } 245 } 246 } 247 248 if ( sComponentURL == URL_COMPONENT_REPORTDESIGN ) 249 { 250 sal_Bool bPreview = aLoadArgs.getOrDefault( "Preview", sal_False ); 251 if ( bPreview ) 252 { // report designs cannot be previewed 253 if ( rListener.is() ) 254 rListener->loadCancelled( this ); 255 return; 256 } 257 Reference< XModel > xReportModel( aLoadArgs.getOrDefault( "Model", Reference< XModel >() ) ); 258 if ( xReportModel.is() ) 259 { 260 xController.set( m_xServiceFactory->createInstance( 261 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.ReportDesign" ) ) ), UNO_QUERY ); 262 if ( xController.is() ) 263 { 264 xController->attachModel( xReportModel ); 265 xReportModel->connectController( xController.get() ); 266 xReportModel->setCurrentController( xController.get() ); 267 } 268 } 269 } 270 271 sal_Bool bSuccess = xController.is(); 272 Reference< XModel > xDatabaseDocument; 273 if ( bSuccess ) 274 { 275 Reference< XDataSource > xDataSource ( aLoadArgs.getOrDefault( "DataSource", Reference< XDataSource >() ) ); 276 ::rtl::OUString sDataSourceName( aLoadArgs.getOrDefault( "DataSourceName", ::rtl::OUString() ) ); 277 Reference< XConnection > xConnection ( aLoadArgs.getOrDefault( "ActiveConnection", Reference< XConnection >() ) ); 278 if ( xDataSource.is() ) 279 { 280 xDatabaseDocument.set( getDataSourceOrModel( xDataSource ), UNO_QUERY ); 281 } 282 else if ( sDataSourceName.getLength() ) 283 { 284 ::dbtools::SQLExceptionInfo aError; 285 xDataSource.set( getDataSourceByName( sDataSourceName, NULL, m_xServiceFactory, &aError ) ); 286 xDatabaseDocument.set( getDataSourceOrModel( xDataSource ), UNO_QUERY ); 287 } 288 else if ( xConnection.is() ) 289 { 290 Reference< XChild > xAsChild( xConnection, UNO_QUERY ); 291 if ( xAsChild.is() ) 292 { 293 OSL_ENSURE( Reference< XDataSource >( xAsChild->getParent(), UNO_QUERY ).is(), 294 "DBContentLoader::load: a connection whose parent is no data source?" ); 295 xDatabaseDocument.set( getDataSourceOrModel( xAsChild->getParent() ), UNO_QUERY ); 296 } 297 } 298 299 // init controller 300 ::vos::OGuard aGuard(Application::GetSolarMutex()); 301 try 302 { 303 Reference<XInitialization > xIni(xController,UNO_QUERY); 304 PropertyValue aFrame(::rtl::OUString::createFromAscii("Frame"),0,makeAny(rFrame),PropertyState_DIRECT_VALUE); 305 Sequence< Any > aInitArgs(m_aArgs.getLength()+1); 306 307 Any* pBegin = aInitArgs.getArray(); 308 Any* pEnd = pBegin + aInitArgs.getLength(); 309 *pBegin <<= aFrame; 310 const PropertyValue* pIter = m_aArgs.getConstArray(); 311 for(++pBegin;pBegin != pEnd;++pBegin,++pIter) 312 { 313 *pBegin <<= *pIter; 314 } 315 316 xIni->initialize(aInitArgs); 317 } 318 catch(const Exception&) 319 { 320 // Does this need to be shown to the user? 321 bSuccess = false; 322 try 323 { 324 ::comphelper::disposeComponent( xController ); 325 } 326 catch( const Exception& ) 327 { 328 DBG_UNHANDLED_EXCEPTION(); 329 } 330 } 331 } 332 333 // assign controller and frame 334 if ( bSuccess ) 335 { 336 if ( xController.is() && rFrame.is() ) 337 { 338 rFrame->setComponent( xController->getComponentWindow(), xController.get() ); 339 xController->attachFrame(rFrame); 340 } 341 342 if ( rListener.is() ) 343 rListener->loadFinished( this ); 344 } 345 else 346 if ( rListener.is() ) 347 rListener->loadCancelled( this ); 348 } 349 350 // ----------------------------------------------------------------------- 351 void DBContentLoader::cancel(void) throw() 352 { 353 } 354 355