| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_extensions.hxx" |
| #include "sqlcommanddesign.hxx" |
| #include "formstrings.hxx" |
| #ifndef _EXTENSIONS_FORMCTRLR_PROPRESID_HRC_ |
| #include "formresid.hrc" |
| #endif |
| #ifndef _EXTENSIONS_PROPCTRLR_MODULEPRC_HXX_ |
| #include "modulepcr.hxx" |
| #endif |
| #include "unourl.hxx" |
| |
| /** === begin UNO includes === **/ |
| #include <com/sun/star/awt/XWindow.hpp> |
| #include <com/sun/star/awt/XTopWindow.hpp> |
| #include <com/sun/star/uno/Sequence.hxx> |
| #include <com/sun/star/frame/XTitle.hpp> |
| #include <com/sun/star/frame/XComponentLoader.hpp> |
| #include <com/sun/star/frame/XController.hpp> |
| #include <com/sun/star/lang/NullPointerException.hpp> |
| #include <com/sun/star/lang/DisposedException.hpp> |
| #include <com/sun/star/frame/FrameSearchFlag.hpp> |
| #include <com/sun/star/frame/XFramesSupplier.hpp> |
| #include <com/sun/star/sdbc/XConnection.hpp> |
| #include <com/sun/star/util/XCloseable.hpp> |
| #include <com/sun/star/frame/XDispatchProvider.hpp> |
| #include <com/sun/star/beans/XPropertySetInfo.hpp> |
| #include <com/sun/star/sdb/CommandType.hpp> |
| /** === end UNO includes === **/ |
| |
| #include <svtools/localresaccess.hxx> |
| #include <tools/diagnose_ex.h> |
| #include <osl/diagnose.h> |
| |
| //........................................................................ |
| namespace pcr |
| { |
| //........................................................................ |
| |
| /** === begin UNO using === **/ |
| using ::com::sun::star::uno::Reference; |
| using ::com::sun::star::lang::XMultiComponentFactory; |
| using ::com::sun::star::beans::PropertyChangeEvent; |
| using ::com::sun::star::uno::RuntimeException; |
| using ::com::sun::star::frame::XFrame; |
| using ::com::sun::star::awt::XTopWindow; |
| using ::com::sun::star::awt::XWindow; |
| using ::com::sun::star::uno::Exception; |
| using ::com::sun::star::uno::UNO_QUERY_THROW; |
| using ::com::sun::star::uno::UNO_QUERY; |
| using ::com::sun::star::beans::PropertyValue; |
| using ::com::sun::star::uno::Sequence; |
| using ::com::sun::star::lang::XComponent; |
| using ::com::sun::star::frame::XComponentLoader; |
| using ::com::sun::star::beans::XPropertySet; |
| using ::com::sun::star::beans::XPropertySetInfo; |
| using ::com::sun::star::frame::XController; |
| using ::com::sun::star::frame::XTitle; |
| using ::com::sun::star::lang::EventObject; |
| using ::com::sun::star::lang::NullPointerException; |
| using ::com::sun::star::lang::DisposedException; |
| using ::com::sun::star::uno::makeAny; |
| using ::com::sun::star::uno::XComponentContext; |
| using ::com::sun::star::frame::XFramesSupplier; |
| using ::com::sun::star::frame::XFrames; |
| using ::com::sun::star::util::XCloseable; |
| using ::com::sun::star::uno::TypeClass_STRING; |
| using ::com::sun::star::lang::XMultiServiceFactory; |
| using ::com::sun::star::frame::XDispatchProvider; |
| using ::com::sun::star::frame::XDispatch; |
| using ::com::sun::star::uno::Any; |
| /** === end UNO using === **/ |
| namespace FrameSearchFlag = ::com::sun::star::frame::FrameSearchFlag; |
| namespace CommandType = ::com::sun::star::sdb::CommandType; |
| |
| //==================================================================== |
| //= ISQLCommandAdapter |
| //==================================================================== |
| //-------------------------------------------------------------------- |
| ISQLCommandAdapter::~ISQLCommandAdapter() |
| { |
| } |
| |
| //==================================================================== |
| //= SQLCommandDesigner |
| //==================================================================== |
| //-------------------------------------------------------------------- |
| SQLCommandDesigner::SQLCommandDesigner( const Reference< XComponentContext >& _rxContext, |
| const ::rtl::Reference< ISQLCommandAdapter >& _rxPropertyAdapter, |
| const ::dbtools::SharedConnection& _rConnection, const Link& _rCloseLink ) |
| :m_xContext( _rxContext ) |
| ,m_xConnection( _rConnection ) |
| ,m_xObjectAdapter( _rxPropertyAdapter ) |
| ,m_aCloseLink( _rCloseLink ) |
| { |
| if ( m_xContext.is() ) |
| m_xORB = m_xContext->getServiceManager(); |
| if ( !m_xORB.is() || !_rxPropertyAdapter.is() || !m_xConnection.is() ) |
| throw NullPointerException(); |
| |
| impl_doOpenDesignerFrame_nothrow(); |
| } |
| |
| //-------------------------------------------------------------------- |
| SQLCommandDesigner::~SQLCommandDesigner() |
| { |
| } |
| |
| //-------------------------------------------------------------------- |
| void SAL_CALL SQLCommandDesigner::propertyChange( const PropertyChangeEvent& Event ) throw (RuntimeException) |
| { |
| OSL_ENSURE( m_xDesigner.is() && ( Event.Source == m_xDesigner ), "SQLCommandDesigner::propertyChange: where did this come from?" ); |
| |
| if ( m_xDesigner.is() && ( Event.Source == m_xDesigner ) ) |
| { |
| try |
| { |
| if ( PROPERTY_ACTIVECOMMAND == Event.PropertyName ) |
| { |
| ::rtl::OUString sCommand; |
| OSL_VERIFY( Event.NewValue >>= sCommand ); |
| m_xObjectAdapter->setSQLCommand( sCommand ); |
| } |
| else if ( PROPERTY_ESCAPE_PROCESSING == Event.PropertyName ) |
| { |
| sal_Bool bEscapeProcessing( sal_False ); |
| OSL_VERIFY( Event.NewValue >>= bEscapeProcessing ); |
| m_xObjectAdapter->setEscapeProcessing( bEscapeProcessing ); |
| } |
| } |
| catch( const RuntimeException& ) { throw; } |
| catch( const Exception& ) |
| { |
| // not allowed to leave, so silence it |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| } |
| |
| //-------------------------------------------------------------------- |
| void SAL_CALL SQLCommandDesigner::disposing( const EventObject& Source ) throw (RuntimeException) |
| { |
| if ( m_xDesigner.is() && ( Source.Source == m_xDesigner ) ) |
| { |
| impl_designerClosed_nothrow(); |
| m_xDesigner.clear(); |
| } |
| } |
| |
| //-------------------------------------------------------------------- |
| void SQLCommandDesigner::dispose() |
| { |
| if ( impl_isDisposed() ) |
| return; |
| |
| if ( isActive() ) |
| impl_closeDesigner_nothrow(); |
| |
| m_xConnection.clear(); |
| m_xContext.clear(); |
| m_xORB.clear(); |
| } |
| |
| //-------------------------------------------------------------------- |
| void SQLCommandDesigner::impl_checkDisposed_throw() const |
| { |
| if ( impl_isDisposed() ) |
| throw DisposedException(); |
| } |
| |
| //-------------------------------------------------------------------- |
| void SQLCommandDesigner::raise() const |
| { |
| impl_checkDisposed_throw(); |
| impl_raise_nothrow(); |
| } |
| |
| //------------------------------------------------------------------------ |
| bool SQLCommandDesigner::suspend() const |
| { |
| impl_checkDisposed_throw(); |
| return impl_trySuspendDesigner_nothrow(); |
| } |
| |
| //-------------------------------------------------------------------- |
| void SQLCommandDesigner::impl_raise_nothrow() const |
| { |
| OSL_PRECOND( isActive(), "SQLCommandDesigner::impl_raise_nothrow: not active!" ); |
| if ( !isActive() ) |
| return; |
| |
| try |
| { |
| // activate the frame for this component |
| Reference< XFrame > xFrame( m_xDesigner->getFrame(), UNO_QUERY_THROW ); |
| Reference< XWindow > xWindow( xFrame->getContainerWindow(), UNO_QUERY_THROW ); |
| Reference< XTopWindow > xTopWindow( xWindow, UNO_QUERY_THROW ); |
| |
| xTopWindow->toFront(); |
| xWindow->setFocus(); |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| |
| //-------------------------------------------------------------------- |
| void SQLCommandDesigner::impl_doOpenDesignerFrame_nothrow() |
| { |
| OSL_PRECOND( !isActive(), |
| "SQLCommandDesigner::impl_doOpenDesignerFrame_nothrow: already active!" ); |
| OSL_PRECOND( m_xConnection.is(), "SQLCommandDesigner::impl_doOpenDesignerFrame_nothrow: this will crash!" ); |
| osl_incrementInterlockedCount(&m_refCount); |
| |
| try |
| { |
| // for various reasons, we don't want the new frame to appear in the desktop's frame list |
| // thus, we create a blank frame at the desktop, remove it from the desktop's frame list |
| // immediately, and then load the component into this blank (and now parent-less) frame |
| Reference< XComponentLoader > xLoader( impl_createEmptyParentlessTask_nothrow(), UNO_QUERY_THROW ); |
| Sequence< PropertyValue > aArgs( 5 ); |
| aArgs[0].Name = PROPERTY_ACTIVE_CONNECTION; |
| aArgs[0].Value <<= m_xConnection.getTyped(); |
| |
| aArgs[1].Name = PROPERTY_COMMAND; |
| aArgs[1].Value <<= m_xObjectAdapter->getSQLCommand(); |
| aArgs[2].Name = PROPERTY_COMMANDTYPE; |
| aArgs[2].Value <<= (sal_Int32)CommandType::COMMAND; |
| aArgs[3].Name = PROPERTY_ESCAPE_PROCESSING; |
| aArgs[3].Value <<= m_xObjectAdapter->getEscapeProcessing(); |
| |
| aArgs[4].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "GraphicalDesign" ) ); |
| aArgs[4].Value <<= m_xObjectAdapter->getEscapeProcessing(); |
| |
| Reference< XComponent > xQueryDesign = xLoader->loadComponentFromURL( |
| ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".component:DB/QueryDesign" ) ), |
| ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_self" ) ), |
| FrameSearchFlag::TASKS | FrameSearchFlag::CREATE, |
| aArgs |
| ); |
| |
| // remember this newly loaded component - we need to care for it e.g. when we're suspended |
| m_xDesigner = m_xDesigner.query( xQueryDesign ); |
| OSL_ENSURE( m_xDesigner.is() || !xQueryDesign.is(), "SQLCommandDesigner::impl_doOpenDesignerFrame_nothrow: the component is expected to be a controller!" ); |
| if ( m_xDesigner.is() ) |
| { |
| Reference< XPropertySet > xQueryDesignProps( m_xDesigner, UNO_QUERY ); |
| OSL_ENSURE( xQueryDesignProps.is(), "SQLCommandDesigner::impl_doOpenDesignerFrame_nothrow: the controller should have properties!" ); |
| if ( xQueryDesignProps.is() ) |
| { |
| xQueryDesignProps->addPropertyChangeListener( PROPERTY_ACTIVECOMMAND, this ); |
| xQueryDesignProps->addPropertyChangeListener( PROPERTY_ESCAPE_PROCESSING, this ); |
| } |
| } |
| |
| // get the frame which we just opened and set it's title |
| Reference< XTitle> xTitle(xQueryDesign,UNO_QUERY); |
| if ( xTitle.is() ) |
| { |
| ::svt::OLocalResourceAccess aEnumStrings( PcrRes( RID_RSC_ENUM_COMMAND_TYPE ), RSC_RESOURCE ); |
| ::rtl::OUString sDisplayName = String( PcrRes( CommandType::COMMAND + 1 ) ); |
| xTitle->setTitle( sDisplayName ); |
| } |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| m_xDesigner.clear(); |
| } |
| osl_decrementInterlockedCount(&m_refCount); |
| } |
| |
| //------------------------------------------------------------------------ |
| Reference< XFrame > SQLCommandDesigner::impl_createEmptyParentlessTask_nothrow( ) const |
| { |
| OSL_PRECOND( m_xORB.is(), "SQLCommandDesigner::impl_createEmptyParentlessTask_nothrow: this will crash!" ); |
| |
| Reference< XFrame > xFrame; |
| try |
| { |
| Reference< XInterface > xDesktop ( m_xORB->createInstanceWithContext( SERVICE_DESKTOP, m_xContext ) ); |
| Reference< XFrame > xDesktopFrame ( xDesktop, UNO_QUERY_THROW ); |
| Reference< XFramesSupplier > xSuppDesktopFrames( xDesktopFrame, UNO_QUERY_THROW ); |
| |
| Reference< XFrames > xDesktopFramesCollection( xSuppDesktopFrames->getFrames(), UNO_QUERY_THROW ); |
| xFrame = xDesktopFrame->findFrame( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_blank" ) ), FrameSearchFlag::CREATE ); |
| OSL_ENSURE( xFrame.is(), "SQLCommandDesigner::impl_createEmptyParentlessTask_nothrow: could not create an empty frame!" ); |
| xDesktopFramesCollection->remove( xFrame ); |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| return xFrame; |
| } |
| |
| //------------------------------------------------------------------------ |
| void SQLCommandDesigner::impl_designerClosed_nothrow() |
| { |
| if ( m_aCloseLink.IsSet() ) |
| m_aCloseLink.Call( this ); |
| } |
| |
| //------------------------------------------------------------------------ |
| void SQLCommandDesigner::impl_closeDesigner_nothrow() |
| { |
| OSL_PRECOND( isActive(), "SQLCommandDesigner::impl_closeDesigner_nothrow: invalid calle!" ); |
| // close it |
| try |
| { |
| // do not listen anymore .... |
| Reference< XPropertySet > xProps( m_xDesigner, UNO_QUERY ); |
| if ( xProps.is() ) |
| xProps->removePropertyChangeListener( PROPERTY_ACTIVECOMMAND, this ); |
| |
| // we need to close the frame via the "user interface", by dispatching a close command, |
| // instead of calling XCloseable::close directly. The latter method would also close |
| // the frame, but not care for things like shutting down the office when the last |
| // frame is gone ... |
| const UnoURL aCloseURL( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:CloseDoc" ) ), |
| Reference< XMultiServiceFactory >( m_xORB, UNO_QUERY ) ); |
| |
| Reference< XDispatchProvider > xProvider( m_xDesigner->getFrame(), UNO_QUERY_THROW ); |
| Reference< XDispatch > xDispatch( xProvider->queryDispatch( aCloseURL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_top" ) ), FrameSearchFlag::SELF ) ); |
| OSL_ENSURE( xDispatch.is(), "SQLCommandDesigner::impl_closeDesigner_nothrow: no dispatcher for the CloseDoc command!" ); |
| if ( xDispatch.is() ) |
| { |
| xDispatch->dispatch( aCloseURL, Sequence< PropertyValue >( ) ); |
| } |
| else |
| { |
| // fallback: use the XCloseable::close (with all possible disadvantages) |
| Reference< XCloseable > xClose( m_xDesigner->getFrame(), UNO_QUERY ); |
| if ( xClose.is() ) |
| xClose->close( sal_True ); |
| } |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| |
| m_xDesigner.clear(); |
| } |
| |
| //------------------------------------------------------------------------ |
| bool SQLCommandDesigner::impl_trySuspendDesigner_nothrow() const |
| { |
| OSL_PRECOND( isActive(), "SQLCommandDesigner::impl_trySuspendDesigner_nothrow: no active designer, this will crash!" ); |
| sal_Bool bAllow = sal_True; |
| try |
| { |
| bAllow = m_xDesigner->suspend( sal_True ); |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| return bAllow; |
| } |
| |
| //........................................................................ |
| } // namespace pcr |
| //........................................................................ |
| |