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_extensions.hxx" 30 #include "sqlcommanddesign.hxx" 31 #include "formstrings.hxx" 32 #ifndef _EXTENSIONS_FORMCTRLR_PROPRESID_HRC_ 33 #include "formresid.hrc" 34 #endif 35 #ifndef _EXTENSIONS_PROPCTRLR_MODULEPRC_HXX_ 36 #include "modulepcr.hxx" 37 #endif 38 #include "unourl.hxx" 39 40 /** === begin UNO includes === **/ 41 #include <com/sun/star/awt/XWindow.hpp> 42 #include <com/sun/star/awt/XTopWindow.hpp> 43 #include <com/sun/star/uno/Sequence.hxx> 44 #include <com/sun/star/frame/XTitle.hpp> 45 #include <com/sun/star/frame/XComponentLoader.hpp> 46 #include <com/sun/star/frame/XController.hpp> 47 #include <com/sun/star/lang/NullPointerException.hpp> 48 #include <com/sun/star/lang/DisposedException.hpp> 49 #include <com/sun/star/frame/FrameSearchFlag.hpp> 50 #include <com/sun/star/frame/XFramesSupplier.hpp> 51 #include <com/sun/star/sdbc/XConnection.hpp> 52 #include <com/sun/star/util/XCloseable.hpp> 53 #include <com/sun/star/frame/XDispatchProvider.hpp> 54 #include <com/sun/star/beans/XPropertySetInfo.hpp> 55 #include <com/sun/star/sdb/CommandType.hpp> 56 /** === end UNO includes === **/ 57 58 #include <svtools/localresaccess.hxx> 59 #include <tools/diagnose_ex.h> 60 #include <osl/diagnose.h> 61 62 //........................................................................ 63 namespace pcr 64 { 65 //........................................................................ 66 67 /** === begin UNO using === **/ 68 using ::com::sun::star::uno::Reference; 69 using ::com::sun::star::lang::XMultiComponentFactory; 70 using ::com::sun::star::beans::PropertyChangeEvent; 71 using ::com::sun::star::uno::RuntimeException; 72 using ::com::sun::star::frame::XFrame; 73 using ::com::sun::star::awt::XTopWindow; 74 using ::com::sun::star::awt::XWindow; 75 using ::com::sun::star::uno::Exception; 76 using ::com::sun::star::uno::UNO_QUERY_THROW; 77 using ::com::sun::star::uno::UNO_QUERY; 78 using ::com::sun::star::beans::PropertyValue; 79 using ::com::sun::star::uno::Sequence; 80 using ::com::sun::star::lang::XComponent; 81 using ::com::sun::star::frame::XComponentLoader; 82 using ::com::sun::star::beans::XPropertySet; 83 using ::com::sun::star::beans::XPropertySetInfo; 84 using ::com::sun::star::frame::XController; 85 using ::com::sun::star::frame::XTitle; 86 using ::com::sun::star::lang::EventObject; 87 using ::com::sun::star::lang::NullPointerException; 88 using ::com::sun::star::lang::DisposedException; 89 using ::com::sun::star::uno::makeAny; 90 using ::com::sun::star::uno::XComponentContext; 91 using ::com::sun::star::frame::XFramesSupplier; 92 using ::com::sun::star::frame::XFrames; 93 using ::com::sun::star::util::XCloseable; 94 using ::com::sun::star::uno::TypeClass_STRING; 95 using ::com::sun::star::lang::XMultiServiceFactory; 96 using ::com::sun::star::frame::XDispatchProvider; 97 using ::com::sun::star::frame::XDispatch; 98 using ::com::sun::star::uno::Any; 99 /** === end UNO using === **/ 100 namespace FrameSearchFlag = ::com::sun::star::frame::FrameSearchFlag; 101 namespace CommandType = ::com::sun::star::sdb::CommandType; 102 103 //==================================================================== 104 //= ISQLCommandAdapter 105 //==================================================================== 106 //-------------------------------------------------------------------- 107 ISQLCommandAdapter::~ISQLCommandAdapter() 108 { 109 } 110 111 //==================================================================== 112 //= SQLCommandDesigner 113 //==================================================================== 114 //-------------------------------------------------------------------- 115 SQLCommandDesigner::SQLCommandDesigner( const Reference< XComponentContext >& _rxContext, 116 const ::rtl::Reference< ISQLCommandAdapter >& _rxPropertyAdapter, 117 const ::dbtools::SharedConnection& _rConnection, const Link& _rCloseLink ) 118 :m_xContext( _rxContext ) 119 ,m_xConnection( _rConnection ) 120 ,m_xObjectAdapter( _rxPropertyAdapter ) 121 ,m_aCloseLink( _rCloseLink ) 122 { 123 if ( m_xContext.is() ) 124 m_xORB = m_xContext->getServiceManager(); 125 if ( !m_xORB.is() || !_rxPropertyAdapter.is() || !m_xConnection.is() ) 126 throw NullPointerException(); 127 128 impl_doOpenDesignerFrame_nothrow(); 129 } 130 131 //-------------------------------------------------------------------- 132 SQLCommandDesigner::~SQLCommandDesigner() 133 { 134 } 135 136 //-------------------------------------------------------------------- 137 void SAL_CALL SQLCommandDesigner::propertyChange( const PropertyChangeEvent& Event ) throw (RuntimeException) 138 { 139 OSL_ENSURE( m_xDesigner.is() && ( Event.Source == m_xDesigner ), "SQLCommandDesigner::propertyChange: where did this come from?" ); 140 141 if ( m_xDesigner.is() && ( Event.Source == m_xDesigner ) ) 142 { 143 try 144 { 145 if ( PROPERTY_ACTIVECOMMAND == Event.PropertyName ) 146 { 147 ::rtl::OUString sCommand; 148 OSL_VERIFY( Event.NewValue >>= sCommand ); 149 m_xObjectAdapter->setSQLCommand( sCommand ); 150 } 151 else if ( PROPERTY_ESCAPE_PROCESSING == Event.PropertyName ) 152 { 153 sal_Bool bEscapeProcessing( sal_False ); 154 OSL_VERIFY( Event.NewValue >>= bEscapeProcessing ); 155 m_xObjectAdapter->setEscapeProcessing( bEscapeProcessing ); 156 } 157 } 158 catch( const RuntimeException& ) { throw; } 159 catch( const Exception& ) 160 { 161 // not allowed to leave, so silence it 162 DBG_UNHANDLED_EXCEPTION(); 163 } 164 } 165 } 166 167 //-------------------------------------------------------------------- 168 void SAL_CALL SQLCommandDesigner::disposing( const EventObject& Source ) throw (RuntimeException) 169 { 170 if ( m_xDesigner.is() && ( Source.Source == m_xDesigner ) ) 171 { 172 impl_designerClosed_nothrow(); 173 m_xDesigner.clear(); 174 } 175 } 176 177 //-------------------------------------------------------------------- 178 void SQLCommandDesigner::dispose() 179 { 180 if ( impl_isDisposed() ) 181 return; 182 183 if ( isActive() ) 184 impl_closeDesigner_nothrow(); 185 186 m_xConnection.clear(); 187 m_xContext.clear(); 188 m_xORB.clear(); 189 } 190 191 //-------------------------------------------------------------------- 192 void SQLCommandDesigner::impl_checkDisposed_throw() const 193 { 194 if ( impl_isDisposed() ) 195 throw DisposedException(); 196 } 197 198 //-------------------------------------------------------------------- 199 void SQLCommandDesigner::raise() const 200 { 201 impl_checkDisposed_throw(); 202 impl_raise_nothrow(); 203 } 204 205 //------------------------------------------------------------------------ 206 bool SQLCommandDesigner::suspend() const 207 { 208 impl_checkDisposed_throw(); 209 return impl_trySuspendDesigner_nothrow(); 210 } 211 212 //-------------------------------------------------------------------- 213 void SQLCommandDesigner::impl_raise_nothrow() const 214 { 215 OSL_PRECOND( isActive(), "SQLCommandDesigner::impl_raise_nothrow: not active!" ); 216 if ( !isActive() ) 217 return; 218 219 try 220 { 221 // activate the frame for this component 222 Reference< XFrame > xFrame( m_xDesigner->getFrame(), UNO_QUERY_THROW ); 223 Reference< XWindow > xWindow( xFrame->getContainerWindow(), UNO_QUERY_THROW ); 224 Reference< XTopWindow > xTopWindow( xWindow, UNO_QUERY_THROW ); 225 226 xTopWindow->toFront(); 227 xWindow->setFocus(); 228 } 229 catch( const Exception& ) 230 { 231 DBG_UNHANDLED_EXCEPTION(); 232 } 233 } 234 235 //-------------------------------------------------------------------- 236 void SQLCommandDesigner::impl_doOpenDesignerFrame_nothrow() 237 { 238 OSL_PRECOND( !isActive(), 239 "SQLCommandDesigner::impl_doOpenDesignerFrame_nothrow: already active!" ); 240 OSL_PRECOND( m_xConnection.is(), "SQLCommandDesigner::impl_doOpenDesignerFrame_nothrow: this will crash!" ); 241 osl_incrementInterlockedCount(&m_refCount); 242 243 try 244 { 245 // for various reasons, we don't want the new frame to appear in the desktop's frame list 246 // thus, we create a blank frame at the desktop, remove it from the desktop's frame list 247 // immediately, and then load the component into this blank (and now parent-less) frame 248 Reference< XComponentLoader > xLoader( impl_createEmptyParentlessTask_nothrow(), UNO_QUERY_THROW ); 249 Sequence< PropertyValue > aArgs( 5 ); 250 aArgs[0].Name = PROPERTY_ACTIVE_CONNECTION; 251 aArgs[0].Value <<= m_xConnection.getTyped(); 252 253 aArgs[1].Name = PROPERTY_COMMAND; 254 aArgs[1].Value <<= m_xObjectAdapter->getSQLCommand(); 255 aArgs[2].Name = PROPERTY_COMMANDTYPE; 256 aArgs[2].Value <<= (sal_Int32)CommandType::COMMAND; 257 aArgs[3].Name = PROPERTY_ESCAPE_PROCESSING; 258 aArgs[3].Value <<= m_xObjectAdapter->getEscapeProcessing(); 259 260 aArgs[4].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "GraphicalDesign" ) ); 261 aArgs[4].Value <<= m_xObjectAdapter->getEscapeProcessing(); 262 263 Reference< XComponent > xQueryDesign = xLoader->loadComponentFromURL( 264 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".component:DB/QueryDesign" ) ), 265 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_self" ) ), 266 FrameSearchFlag::TASKS | FrameSearchFlag::CREATE, 267 aArgs 268 ); 269 270 // remember this newly loaded component - we need to care for it e.g. when we're suspended 271 m_xDesigner = m_xDesigner.query( xQueryDesign ); 272 OSL_ENSURE( m_xDesigner.is() || !xQueryDesign.is(), "SQLCommandDesigner::impl_doOpenDesignerFrame_nothrow: the component is expected to be a controller!" ); 273 if ( m_xDesigner.is() ) 274 { 275 Reference< XPropertySet > xQueryDesignProps( m_xDesigner, UNO_QUERY ); 276 OSL_ENSURE( xQueryDesignProps.is(), "SQLCommandDesigner::impl_doOpenDesignerFrame_nothrow: the controller should have properties!" ); 277 if ( xQueryDesignProps.is() ) 278 { 279 xQueryDesignProps->addPropertyChangeListener( PROPERTY_ACTIVECOMMAND, this ); 280 xQueryDesignProps->addPropertyChangeListener( PROPERTY_ESCAPE_PROCESSING, this ); 281 } 282 } 283 284 // get the frame which we just opened and set it's title 285 Reference< XTitle> xTitle(xQueryDesign,UNO_QUERY); 286 if ( xTitle.is() ) 287 { 288 ::svt::OLocalResourceAccess aEnumStrings( PcrRes( RID_RSC_ENUM_COMMAND_TYPE ), RSC_RESOURCE ); 289 ::rtl::OUString sDisplayName = String( PcrRes( CommandType::COMMAND + 1 ) ); 290 xTitle->setTitle( sDisplayName ); 291 } 292 } 293 catch( const Exception& ) 294 { 295 DBG_UNHANDLED_EXCEPTION(); 296 m_xDesigner.clear(); 297 } 298 osl_decrementInterlockedCount(&m_refCount); 299 } 300 301 //------------------------------------------------------------------------ 302 Reference< XFrame > SQLCommandDesigner::impl_createEmptyParentlessTask_nothrow( ) const 303 { 304 OSL_PRECOND( m_xORB.is(), "SQLCommandDesigner::impl_createEmptyParentlessTask_nothrow: this will crash!" ); 305 306 Reference< XFrame > xFrame; 307 try 308 { 309 Reference< XInterface > xDesktop ( m_xORB->createInstanceWithContext( SERVICE_DESKTOP, m_xContext ) ); 310 Reference< XFrame > xDesktopFrame ( xDesktop, UNO_QUERY_THROW ); 311 Reference< XFramesSupplier > xSuppDesktopFrames( xDesktopFrame, UNO_QUERY_THROW ); 312 313 Reference< XFrames > xDesktopFramesCollection( xSuppDesktopFrames->getFrames(), UNO_QUERY_THROW ); 314 xFrame = xDesktopFrame->findFrame( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_blank" ) ), FrameSearchFlag::CREATE ); 315 OSL_ENSURE( xFrame.is(), "SQLCommandDesigner::impl_createEmptyParentlessTask_nothrow: could not create an empty frame!" ); 316 xDesktopFramesCollection->remove( xFrame ); 317 } 318 catch( const Exception& ) 319 { 320 DBG_UNHANDLED_EXCEPTION(); 321 } 322 return xFrame; 323 } 324 325 //------------------------------------------------------------------------ 326 void SQLCommandDesigner::impl_designerClosed_nothrow() 327 { 328 if ( m_aCloseLink.IsSet() ) 329 m_aCloseLink.Call( this ); 330 } 331 332 //------------------------------------------------------------------------ 333 void SQLCommandDesigner::impl_closeDesigner_nothrow() 334 { 335 OSL_PRECOND( isActive(), "SQLCommandDesigner::impl_closeDesigner_nothrow: invalid calle!" ); 336 // close it 337 try 338 { 339 // do not listen anymore .... 340 Reference< XPropertySet > xProps( m_xDesigner, UNO_QUERY ); 341 if ( xProps.is() ) 342 xProps->removePropertyChangeListener( PROPERTY_ACTIVECOMMAND, this ); 343 344 // we need to close the frame via the "user interface", by dispatching a close command, 345 // instead of calling XCloseable::close directly. The latter method would also close 346 // the frame, but not care for things like shutting down the office when the last 347 // frame is gone ... 348 const UnoURL aCloseURL( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:CloseDoc" ) ), 349 Reference< XMultiServiceFactory >( m_xORB, UNO_QUERY ) ); 350 351 Reference< XDispatchProvider > xProvider( m_xDesigner->getFrame(), UNO_QUERY_THROW ); 352 Reference< XDispatch > xDispatch( xProvider->queryDispatch( aCloseURL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_top" ) ), FrameSearchFlag::SELF ) ); 353 OSL_ENSURE( xDispatch.is(), "SQLCommandDesigner::impl_closeDesigner_nothrow: no dispatcher for the CloseDoc command!" ); 354 if ( xDispatch.is() ) 355 { 356 xDispatch->dispatch( aCloseURL, Sequence< PropertyValue >( ) ); 357 } 358 else 359 { 360 // fallback: use the XCloseable::close (with all possible disadvantages) 361 Reference< XCloseable > xClose( m_xDesigner->getFrame(), UNO_QUERY ); 362 if ( xClose.is() ) 363 xClose->close( sal_True ); 364 } 365 } 366 catch( const Exception& ) 367 { 368 DBG_UNHANDLED_EXCEPTION(); 369 } 370 371 m_xDesigner.clear(); 372 } 373 374 //------------------------------------------------------------------------ 375 bool SQLCommandDesigner::impl_trySuspendDesigner_nothrow() const 376 { 377 OSL_PRECOND( isActive(), "SQLCommandDesigner::impl_trySuspendDesigner_nothrow: no active designer, this will crash!" ); 378 sal_Bool bAllow = sal_True; 379 try 380 { 381 bAllow = m_xDesigner->suspend( sal_True ); 382 } 383 catch( const Exception& ) 384 { 385 DBG_UNHANDLED_EXCEPTION(); 386 } 387 return bAllow; 388 } 389 390 //........................................................................ 391 } // namespace pcr 392 //........................................................................ 393 394