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