| /************************************************************** |
| * |
| * 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_dbaccess.hxx" |
| #ifndef DBAUI_GENERICCONTROLLER_HXX |
| #include "genericcontroller.hxx" |
| #endif |
| #ifndef _COMPHELPER_UNO3_HXX_ |
| #include <comphelper/uno3.hxx> |
| #endif |
| #ifndef _TOOLKIT_AWT_VCLXWINDOW_HXX_ |
| #include <toolkit/awt/vclxwindow.hxx> |
| #endif |
| #ifndef DBACCESS_UI_BROWSER_ID_HXX |
| #include "browserids.hxx" |
| #endif |
| #ifndef _SV_SVAPP_HXX //autogen |
| #include <vcl/svapp.hxx> |
| #endif |
| #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_ |
| #include <toolkit/helper/vclunohelper.hxx> |
| #endif |
| #ifndef DBAUI_DATAVIEW_HXX |
| #include "dataview.hxx" |
| #endif |
| #ifndef _TOOLS_DEBUG_HXX |
| #include <tools/debug.hxx> |
| #endif |
| #ifndef TOOLS_DIAGNOSE_EX_H |
| #include <tools/diagnose_ex.h> |
| #endif |
| #ifndef DBACCESS_SHARED_DBUSTRINGS_HRC |
| #include "dbustrings.hrc" |
| #endif |
| #ifndef _VCL_STDTEXT_HXX |
| #include <vcl/stdtext.hxx> |
| #endif |
| #ifndef _CPPUHELPER_TYPEPROVIDER_HXX_ |
| #include <cppuhelper/typeprovider.hxx> |
| #endif |
| #include <framework/titlehelper.hxx> |
| #ifndef _COMPHELPER_SEQUENCE_HXX_ |
| #include <comphelper/sequence.hxx> |
| #endif |
| #ifndef _COMPHELPER_EXTRACT_HXX_ |
| #include <comphelper/extract.hxx> |
| #endif |
| #ifndef _COM_SUN_STAR_SDBC_XDATASOURCE_HPP_ |
| #include <com/sun/star/sdbc/XDataSource.hpp> |
| #endif |
| #ifndef _COM_SUN_STAR_SDB_SQLCONTEXT_HPP_ |
| #include <com/sun/star/sdb/SQLContext.hpp> |
| #endif |
| #ifndef _COM_SUN_STAR_SDB_XCOMPLETEDCONNECTION_HPP_ |
| #include <com/sun/star/sdb/XCompletedConnection.hpp> |
| #endif |
| #ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_ |
| #include <com/sun/star/beans/XPropertySet.hpp> |
| #endif |
| #ifndef _COM_SUN_STAR_TASK_XINTERACTIONHANDLER_HPP_ |
| #include <com/sun/star/task/XInteractionHandler.hpp> |
| #endif |
| #ifndef _COM_SUN_STAR_UTIL_XCLOSEABLE_HPP_ |
| #include <com/sun/star/util/XCloseable.hpp> |
| #endif |
| #ifndef DBAUI_TOOLS_HXX |
| #include "UITools.hxx" |
| #endif |
| #ifndef _DBAUI_COMMON_TYPES_HXX_ |
| #include "commontypes.hxx" |
| #endif |
| |
| #ifndef _SV_WAITOBJ_HXX |
| #include <vcl/waitobj.hxx> |
| #endif |
| #ifndef _URLOBJ_HXX |
| #include <tools/urlobj.hxx> |
| #endif |
| #ifndef SVTOOLS_URIHELPER_HXX |
| #include <svl/urihelper.hxx> |
| #endif |
| #ifndef _DBAUI_DATASOURCECONNECTOR_HXX_ |
| #include "datasourceconnector.hxx" |
| #endif |
| #ifndef INCLUDED_SVTOOLS_MODULEOPTIONS_HXX |
| #include <unotools/moduleoptions.hxx> |
| #endif |
| #ifndef _COM_SUN_STAR_FRAME_FRAMESEARCHFLAG_HPP_ |
| #include <com/sun/star/frame/FrameSearchFlag.hpp> |
| #endif |
| #ifndef _COM_SUN_STAR_FRAME_STATUS_VISIBILITY_HPP_ |
| #include <com/sun/star/frame/status/Visibility.hpp> |
| #endif |
| #ifndef _COM_SUN_STAR_UTIL_XMODIFIABLE_HPP_ |
| #include <com/sun/star/util/XModifiable.hpp> |
| #endif |
| #ifndef _RTL_USTRING_HXX_ |
| #include <rtl/ustring.hxx> |
| #endif |
| #ifndef _RTL_LOGFILE_HXX_ |
| #include <rtl/logfile.hxx> |
| #endif |
| #include <algorithm> |
| #include <hash_map> |
| #include <cppuhelper/implbase1.hxx> |
| #include <limits> |
| |
| using namespace ::com::sun::star; |
| using namespace ::com::sun::star::uno; |
| using namespace ::com::sun::star::beans; |
| using namespace ::com::sun::star::frame; |
| using namespace ::com::sun::star::frame::status; |
| using namespace ::com::sun::star::util; |
| using namespace ::com::sun::star::lang; |
| using namespace ::com::sun::star::container; |
| using namespace ::com::sun::star::sdbc; |
| using namespace ::com::sun::star::sdb; |
| using namespace ::com::sun::star::task; |
| using namespace ::com::sun::star::awt; |
| using namespace ::com::sun::star; |
| using namespace ::dbtools; |
| using namespace ::comphelper; |
| |
| // ------------------------------------------------------------------------- |
| #define ALL_FEATURES -1 |
| #define FIRST_USER_DEFINED_FEATURE ( ::std::numeric_limits< sal_uInt16 >::max() - 1000 ) |
| #define LAST_USER_DEFINED_FEATURE ( ::std::numeric_limits< sal_uInt16 >::max() ) |
| |
| // ------------------------------------------------------------------------- |
| typedef ::std::hash_map< sal_Int16, sal_Int16 > CommandHashMap; |
| typedef ::std::list< DispatchInformation > DispatchInfoList; |
| |
| |
| // ------------------------------------------------------------------------- |
| const ::rtl::OUString& getConfirmDeletionURL() |
| { |
| static const ::rtl::OUString sConfirmDeletionURL( RTL_CONSTASCII_USTRINGPARAM( ".uno:FormSlots/ConfirmDeletion" ) ); |
| return sConfirmDeletionURL; |
| } |
| |
| namespace dbaui |
| { |
| |
| //========================================================================== |
| //= UserDefinedFeatures |
| //========================================================================== |
| class UserDefinedFeatures |
| { |
| public: |
| UserDefinedFeatures( const Reference< XController >& _rxController ); |
| |
| FeatureState getState( const URL& _rFeatureURL ); |
| void execute( const URL& _rFeatureURL, const Sequence< PropertyValue>& _rArgs ); |
| |
| private: |
| ::com::sun::star::uno::WeakReference< XController > m_aController; |
| }; |
| |
| //-------------------------------------------------------------------------- |
| UserDefinedFeatures::UserDefinedFeatures( const Reference< XController >& _rxController ) |
| :m_aController( _rxController ) |
| { |
| } |
| |
| //-------------------------------------------------------------------------- |
| FeatureState UserDefinedFeatures::getState( const URL& /*_rFeatureURL*/ ) |
| { |
| // for now, enable all the time |
| // TODO: we should ask the dispatcher. However, this is laborious, since you cannot ask a dispatcher |
| // directly, but need to add a status listener. |
| FeatureState aState; |
| aState.bEnabled = sal_True; |
| return aState; |
| } |
| |
| //-------------------------------------------------------------------------- |
| void UserDefinedFeatures::execute( const URL& _rFeatureURL, const Sequence< PropertyValue>& _rArgs ) |
| { |
| try |
| { |
| Reference< XController > xController( (Reference< XController >)m_aController, UNO_SET_THROW ); |
| Reference< XDispatchProvider > xDispatchProvider( xController->getFrame(), UNO_QUERY_THROW ); |
| Reference< XDispatch > xDispatch( xDispatchProvider->queryDispatch( |
| _rFeatureURL, |
| ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_self" ) ), |
| FrameSearchFlag::AUTO |
| ) ); |
| |
| if ( xDispatch == xController ) |
| { |
| OSL_ENSURE( false, "UserDefinedFeatures::execute: the controller shouldn't be the dispatcher here!" ); |
| xDispatch.clear(); |
| } |
| |
| if ( xDispatch.is() ) |
| xDispatch->dispatch( _rFeatureURL, _rArgs ); |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| |
| //========================================================================== |
| //= OGenericUnoController_Data |
| //========================================================================== |
| struct OGenericUnoController_Data |
| { |
| ::sfx2::UserInputInterception m_aUserInputInterception; |
| UserDefinedFeatures m_aUserDefinedFeatures; |
| |
| OGenericUnoController_Data( OGenericUnoController& _rController, ::osl::Mutex& _rMutex ) |
| :m_aUserInputInterception( _rController, _rMutex ) |
| ,m_aUserDefinedFeatures( _rController.getXController() ) |
| { |
| } |
| }; |
| |
| //========================================================================== |
| //= OGenericUnoController |
| //========================================================================== |
| DBG_NAME(OGenericUnoController) |
| // ------------------------------------------------------------------------- |
| OGenericUnoController::OGenericUnoController(const Reference< XMultiServiceFactory >& _rM) |
| :OGenericUnoController_Base( getMutex() ) |
| ,m_pView(NULL) |
| #ifdef DBG_UTIL |
| ,m_bDescribingSupportedFeatures( false ) |
| #endif |
| ,m_aAsyncInvalidateAll(LINK(this, OGenericUnoController, OnAsyncInvalidateAll)) |
| ,m_aAsyncCloseTask(LINK(this, OGenericUnoController, OnAsyncCloseTask)) |
| ,m_xServiceFactory(_rM) |
| ,m_aCurrentFrame( *this ) |
| ,m_bPreview(sal_False) |
| ,m_bReadOnly(sal_False) |
| ,m_bCurrentlyModified(sal_False) |
| ,m_bExternalTitle(sal_False) |
| { |
| osl_incrementInterlockedCount( &m_refCount ); |
| { |
| m_pData.reset( new OGenericUnoController_Data( *this, getMutex() ) ); |
| } |
| osl_decrementInterlockedCount( &m_refCount ); |
| |
| DBG_CTOR(OGenericUnoController,NULL); |
| |
| try |
| { |
| m_xUrlTransformer = Reference< XURLTransformer > (_rM->createInstance(::rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer")), UNO_QUERY); |
| } |
| catch(Exception&) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| |
| #ifdef WNT |
| // ----------------------------------------------------------------------------- |
| OGenericUnoController::OGenericUnoController() |
| :OGenericUnoController_Base( getMutex() ) |
| ,m_pView(NULL) |
| #ifdef DBG_UTIL |
| ,m_bDescribingSupportedFeatures( false ) |
| #endif |
| ,m_aAsyncInvalidateAll(LINK(this, OGenericUnoController, OnAsyncInvalidateAll)) |
| ,m_aAsyncCloseTask(LINK(this, OGenericUnoController, OnAsyncCloseTask)) |
| ,m_aCurrentFrame( *this ) |
| ,m_bPreview(sal_False) |
| ,m_bReadOnly(sal_False) |
| ,m_bCurrentlyModified(sal_False) |
| { |
| OSL_ENSURE( false, "OGenericUnoController::OGenericUnoController: illegal call!" ); |
| // This ctor only exists because the MSVC compiler complained about an unresolved external |
| // symbol. It should not be used at all. Since using it yields strange runtime problems, |
| // we simply abort here. |
| abort(); |
| } |
| #endif |
| |
| // ----------------------------------------------------------------------------- |
| OGenericUnoController::~OGenericUnoController() |
| { |
| |
| DBG_DTOR(OGenericUnoController,NULL); |
| } |
| |
| // ----------------------------------------------------------------------------- |
| sal_Bool OGenericUnoController::Construct(Window* /*pParent*/) |
| { |
| OSL_ENSURE( getView(), "the view is NULL!" ); |
| |
| if ( getView() ) |
| { |
| getView()->Construct(); |
| getView()->Show(); |
| } |
| |
| m_aSupportedFeatures.clear(); |
| fillSupportedFeatures(); |
| |
| // create the database context |
| DBG_ASSERT(getORB().is(), "OGenericUnoController::Construct need a service factory!"); |
| try |
| { |
| m_xDatabaseContext = Reference< XNameAccess >(getORB()->createInstance(SERVICE_SDB_DATABASECONTEXT), UNO_QUERY); |
| } |
| catch(Exception&) |
| { |
| DBG_ERROR("OGenericUnoController::Construct: could not create (or start listening at) the database context!"); |
| } |
| |
| if (!m_xDatabaseContext.is()) |
| { // at least notify the user. Though the whole component does not make any sense without the database context ... |
| ShowServiceNotAvailableError(getView(), String(SERVICE_SDB_DATABASECONTEXT), sal_True); |
| } |
| return sal_True; |
| } |
| //------------------------------------------------------------------------------ |
| IMPL_LINK(OGenericUnoController, OnAsyncInvalidateAll, void*, EMPTYARG) |
| { |
| if ( !OGenericUnoController_Base::rBHelper.bInDispose && !OGenericUnoController_Base::rBHelper.bDisposed ) |
| InvalidateFeature_Impl(); |
| return 0L; |
| } |
| // ----------------------------------------------------------------------------- |
| void OGenericUnoController::impl_initialize() |
| { |
| } |
| // ------------------------------------------------------------------------- |
| void SAL_CALL OGenericUnoController::initialize( const Sequence< Any >& aArguments ) throw(Exception, RuntimeException) |
| { |
| vos::OGuard aSolarGuard( Application::GetSolarMutex() ); |
| ::osl::MutexGuard aGuard( getMutex() ); |
| |
| Reference< XWindow > xParent; |
| Reference< XFrame > xFrame; |
| |
| PropertyValue aValue; |
| const Any* pIter = aArguments.getConstArray(); |
| const Any* pEnd = pIter + aArguments.getLength(); |
| |
| for ( ; pIter != pEnd; ++pIter ) |
| { |
| if ( ( *pIter >>= aValue ) && ( 0 == aValue.Name.compareToAscii( "Frame" ) ) ) |
| { |
| xFrame.set(aValue.Value,UNO_QUERY_THROW); |
| } |
| /* #i42316# |
| else if ( ( *pIter >>= aValue ) && ( 0 == aValue.Name.compareToAscii( "ReadOnly" ) ) ) |
| { |
| aValue.Value >>= m_bReadOnly; |
| } |
| */ |
| else if ( ( *pIter >>= aValue ) && ( 0 == aValue.Name.compareToAscii( "Preview" ) ) ) |
| { |
| aValue.Value >>= m_bPreview; |
| m_bReadOnly = sal_True; |
| } |
| } |
| try |
| { |
| if ( !xFrame.is() ) |
| throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "need a frame" ) ), *this, 1 ); |
| |
| xParent = xFrame->getContainerWindow(); |
| VCLXWindow* pParentComponent = VCLXWindow::GetImplementation(xParent); |
| Window* pParentWin = pParentComponent ? pParentComponent->GetWindow() : NULL; |
| if (!pParentWin) |
| { |
| throw IllegalArgumentException( ::rtl::OUString::createFromAscii( "Parent window is null" ), *this, 1 ); |
| } |
| |
| m_aInitParameters.assign( aArguments ); |
| Construct( pParentWin ); |
| |
| ODataView* pView = getView(); |
| if ( !pView ) |
| throw RuntimeException( ::rtl::OUString::createFromAscii( "unable to create a view" ), *this ); |
| |
| if ( m_bReadOnly || m_bPreview ) |
| pView->EnableInput( sal_False ); |
| |
| impl_initialize(); |
| } |
| catch(Exception& e) |
| { |
| // no one clears my view if I won't |
| ::std::auto_ptr<Window> aTemp(m_pView); |
| m_pView = NULL; |
| throw; |
| } |
| } |
| |
| //------------------------------------------------------------------------------ |
| void SAL_CALL OGenericUnoController::acquire( ) throw () |
| { |
| OGenericUnoController_Base::acquire(); |
| } |
| |
| //------------------------------------------------------------------------------ |
| void SAL_CALL OGenericUnoController::release( ) throw () |
| { |
| OGenericUnoController_Base::release(); |
| } |
| |
| // ------------------------------------------------------------------------- |
| void OGenericUnoController::startFrameListening( const Reference< XFrame >& _rxFrame ) |
| { |
| if ( _rxFrame.is() ) |
| _rxFrame->addFrameActionListener( this ); |
| } |
| |
| // ------------------------------------------------------------------------- |
| void OGenericUnoController::stopFrameListening( const Reference< XFrame >& _rxFrame ) |
| { |
| if ( _rxFrame.is() ) |
| _rxFrame->removeFrameActionListener( this ); |
| } |
| |
| // ------------------------------------------------------------------------- |
| void OGenericUnoController::disposing(const EventObject& Source) throw( RuntimeException ) |
| { |
| // our frame ? |
| if ( Source.Source == getFrame() ) |
| stopFrameListening( getFrame() ); |
| } |
| //------------------------------------------------------------------------ |
| void OGenericUnoController::modified(const EventObject& aEvent) throw( RuntimeException ) |
| { |
| ::osl::MutexGuard aGuard( getMutex() ); |
| if ( !isDataSourceReadOnly() ) |
| { |
| Reference<XModifiable> xModi(aEvent.Source,UNO_QUERY); |
| if ( xModi.is() ) |
| m_bCurrentlyModified = xModi->isModified(); // can only be reset by save |
| else |
| m_bCurrentlyModified = sal_True; |
| } |
| InvalidateFeature(ID_BROWSER_SAVEDOC); |
| InvalidateFeature(ID_BROWSER_UNDO); |
| } |
| // ----------------------------------------------------------------------- |
| Reference< XWindow > SAL_CALL OGenericUnoController::getComponentWindow() throw (RuntimeException) |
| { |
| return VCLUnoHelper::GetInterface( getView() ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| ::rtl::OUString SAL_CALL OGenericUnoController::getViewControllerName() throw (::com::sun::star::uno::RuntimeException) |
| { |
| return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Default" ) ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| Sequence< PropertyValue > SAL_CALL OGenericUnoController::getCreationArguments() throw (RuntimeException) |
| { |
| // currently we do not support any creation args, so anything passed to XModel2::createViewController would be |
| // lost, so we can equally return an empty sequence here |
| return Sequence< PropertyValue >(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| void OGenericUnoController::attachFrame( const Reference< XFrame >& _rxFrame ) throw( RuntimeException ) |
| { |
| vos::OGuard aSolarGuard( Application::GetSolarMutex() ); |
| ::osl::MutexGuard aGuard( getMutex() ); |
| |
| stopFrameListening( m_aCurrentFrame.getFrame() ); |
| Reference< XFrame > xFrame = m_aCurrentFrame.attachFrame( _rxFrame ); |
| startFrameListening( xFrame ); |
| |
| loadMenu( xFrame ); |
| |
| if ( getView() ) |
| getView()->attachFrame( xFrame ); |
| } |
| |
| // ----------------------------------------------------------------------------- |
| struct CommandCollector : public ::std::unary_function< SupportedFeatures::value_type, void> |
| { |
| sal_uInt16 m_nFeature; |
| StringBag& m_rFeatureCommands; |
| CommandCollector( sal_uInt16 _nFeature, StringBag& _rFeatureCommands ) |
| :m_nFeature ( _nFeature ) |
| ,m_rFeatureCommands( _rFeatureCommands ) |
| { |
| } |
| |
| void operator() ( const SupportedFeatures::value_type& lhs ) |
| { |
| if ( lhs.second.nFeatureId == m_nFeature ) |
| m_rFeatureCommands.insert( lhs.first ); |
| } |
| }; |
| |
| // ----------------------------------------------------------------------- |
| namespace |
| { |
| typedef ::std::vector< Any > States; |
| |
| // ................................................................... |
| void lcl_notifyMultipleStates( XStatusListener& _rListener, FeatureStateEvent& _rEvent, const States& _rStates ) |
| { |
| for ( States::const_iterator state = _rStates.begin(); |
| state != _rStates.end(); |
| ++state |
| ) |
| { |
| _rEvent.State = *state; |
| _rListener.statusChanged( _rEvent ); |
| } |
| } |
| |
| // ................................................................... |
| void lcl_collectStates( const FeatureState& _rFeatureState, States& _out_rStates ) |
| { |
| // order matters, due to a bug in framework which resets the check state when any non-boolean event |
| // arrives |
| // #i68215# is the bug to (re-)introduce this "ordered" notification here |
| // #i67882# is the bug which was caused by the real fix which we did in framework |
| // #i68216# is the bug which requests to fix the code in Draw which relies on |
| // framework's implementation details |
| // 2006-08-07 / frank.schoenheit@sun.com |
| if ( !!_rFeatureState.sTitle ) |
| _out_rStates.push_back( makeAny( *_rFeatureState.sTitle ) ); |
| if ( !!_rFeatureState.bChecked ) |
| _out_rStates.push_back( makeAny( (sal_Bool)*_rFeatureState.bChecked ) ); |
| if ( !!_rFeatureState.bInvisible ) |
| _out_rStates.push_back( makeAny( Visibility( !*_rFeatureState.bInvisible ) ) ); |
| if ( _rFeatureState.aValue.hasValue() ) |
| _out_rStates.push_back( _rFeatureState.aValue ); |
| if ( _out_rStates.empty() ) |
| _out_rStates.push_back( Any() ); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| void OGenericUnoController::ImplBroadcastFeatureState(const ::rtl::OUString& _rFeature, const Reference< XStatusListener > & xListener, sal_Bool _bIgnoreCache) |
| { |
| sal_uInt16 nFeat = m_aSupportedFeatures[ _rFeature ].nFeatureId; |
| FeatureState aFeatState( GetState( nFeat ) ); |
| |
| FeatureState& rCachedState = m_aStateCache[nFeat]; // creates if neccessary |
| if ( !_bIgnoreCache ) |
| { |
| // check if we really need to notify the listeners : this method may be called much more often than needed, so check |
| // the cached state of the feature |
| sal_Bool bAlreadyCached = ( m_aStateCache.find(nFeat) != m_aStateCache.end() ); |
| if ( bAlreadyCached ) |
| if ( ( rCachedState.bEnabled == aFeatState.bEnabled ) |
| && ( rCachedState.bChecked == aFeatState.bChecked ) |
| && ( rCachedState.bInvisible == aFeatState.bInvisible ) |
| && ( rCachedState.sTitle == aFeatState.sTitle ) |
| ) |
| return; |
| } |
| rCachedState = aFeatState; |
| |
| FeatureStateEvent aEvent; |
| aEvent.FeatureURL.Complete = _rFeature; |
| if (m_xUrlTransformer.is()) |
| m_xUrlTransformer->parseStrict(aEvent.FeatureURL); |
| aEvent.Source = (XDispatch*)this; |
| aEvent.IsEnabled = aFeatState.bEnabled; |
| |
| // collect all states to be notified |
| States aStates; |
| lcl_collectStates( aFeatState, aStates ); |
| |
| // a special listener ? |
| if ( xListener.is() ) |
| lcl_notifyMultipleStates( *xListener.get(), aEvent, aStates ); |
| else |
| { // no -> iterate through all listeners responsible for the URL |
| StringBag aFeatureCommands; |
| ::std::for_each( |
| m_aSupportedFeatures.begin(), |
| m_aSupportedFeatures.end(), |
| CommandCollector( nFeat, aFeatureCommands ) |
| ); |
| |
| // it is possible that listeners are registered or revoked while |
| // we are notifying them, so we must use a copy of m_arrStatusListener, not |
| // m_arrStatusListener itself |
| // #121276# / 2005-05-19 / frank.schoenheit@sun.com |
| Dispatch aNotifyLoop( m_arrStatusListener ); |
| DispatchIterator iterSearch = aNotifyLoop.begin(); |
| DispatchIterator iterEnd = aNotifyLoop.end(); |
| |
| while (iterSearch != iterEnd) |
| { |
| DispatchTarget& rCurrent = *iterSearch; |
| if ( aFeatureCommands.find( rCurrent.aURL.Complete ) != aFeatureCommands.end() ) |
| { |
| aEvent.FeatureURL = rCurrent.aURL; |
| lcl_notifyMultipleStates( *rCurrent.xListener.get(), aEvent, aStates ); |
| } |
| ++iterSearch; |
| } |
| } |
| |
| } |
| |
| //------------------------------------------------------------------------------ |
| sal_Bool OGenericUnoController::isFeatureSupported( sal_Int32 _nId ) |
| { |
| SupportedFeatures::iterator aFeaturePos = ::std::find_if( |
| m_aSupportedFeatures.begin(), |
| m_aSupportedFeatures.end(), |
| ::std::bind2nd( CompareFeatureById(), _nId ) |
| ); |
| |
| return ( m_aSupportedFeatures.end() != aFeaturePos && aFeaturePos->first.getLength()); |
| } |
| |
| // ----------------------------------------------------------------------- |
| void OGenericUnoController::InvalidateFeature(const ::rtl::OUString& _rURLPath, const Reference< XStatusListener > & _xListener, sal_Bool _bForceBroadcast) |
| { |
| ImplInvalidateFeature( m_aSupportedFeatures[ _rURLPath ].nFeatureId, _xListener, _bForceBroadcast ); |
| } |
| |
| // ----------------------------------------------------------------------------- |
| void OGenericUnoController::InvalidateFeature_Impl() |
| { |
| #ifdef DBG_UTIL |
| static sal_Int32 s_nRecursions = 0; |
| ++s_nRecursions; |
| #endif |
| |
| sal_Bool bEmpty = sal_True; |
| FeatureListener aNextFeature; |
| { |
| ::osl::MutexGuard aGuard( m_aFeatureMutex); |
| bEmpty = m_aFeaturesToInvalidate.empty(); |
| if (!bEmpty) |
| aNextFeature = m_aFeaturesToInvalidate.front(); |
| } |
| while(!bEmpty) |
| { |
| if ( ALL_FEATURES == aNextFeature.nId ) |
| { |
| InvalidateAll_Impl(); |
| break; |
| } |
| else |
| { |
| SupportedFeatures::iterator aFeaturePos = ::std::find_if( |
| m_aSupportedFeatures.begin(), |
| m_aSupportedFeatures.end(), |
| ::std::bind2nd( CompareFeatureById(), aNextFeature.nId ) |
| ); |
| |
| #if OSL_DEBUG_LEVEL > 0 |
| if ( m_aSupportedFeatures.end() == aFeaturePos ) |
| { |
| ::rtl::OString sMessage( "OGenericUnoController::InvalidateFeature_Impl: feature id " ); |
| sMessage += ::rtl::OString::valueOf( aNextFeature.nId ); |
| sMessage += ::rtl::OString( " has been invalidated, but is not supported!" ); |
| OSL_ENSURE( false, sMessage.getStr() ); |
| } |
| #endif |
| if ( m_aSupportedFeatures.end() != aFeaturePos ) |
| // we really know this feature |
| ImplBroadcastFeatureState( aFeaturePos->first, aNextFeature.xListener, aNextFeature.bForceBroadcast ); |
| } |
| |
| ::osl::MutexGuard aGuard( m_aFeatureMutex); |
| m_aFeaturesToInvalidate.pop_front(); |
| bEmpty = m_aFeaturesToInvalidate.empty(); |
| if (!bEmpty) |
| aNextFeature = m_aFeaturesToInvalidate.front(); |
| } |
| |
| #ifdef DBG_UTIL |
| --s_nRecursions; |
| #endif |
| } |
| |
| // ----------------------------------------------------------------------- |
| void OGenericUnoController::ImplInvalidateFeature( sal_Int32 _nId, const Reference< XStatusListener >& _xListener, sal_Bool _bForceBroadcast ) |
| { |
| #if OSL_DEBUG_LEVEL > 0 |
| if ( _nId != -1 ) |
| { |
| SupportedFeatures::iterator aFeaturePos = ::std::find_if( |
| m_aSupportedFeatures.begin(), |
| m_aSupportedFeatures.end(), |
| ::std::bind2nd( CompareFeatureById(), _nId ) |
| ); |
| OSL_ENSURE( aFeaturePos != m_aSupportedFeatures.end(), "OGenericUnoController::ImplInvalidateFeature: invalidating an unsupported feature is suspicious, at least!" ); |
| } |
| #endif |
| |
| FeatureListener aListener; |
| aListener.nId = _nId; |
| aListener.xListener = _xListener; |
| aListener.bForceBroadcast = _bForceBroadcast; |
| |
| sal_Bool bWasEmpty; |
| { |
| ::osl::MutexGuard aGuard( m_aFeatureMutex ); |
| bWasEmpty = m_aFeaturesToInvalidate.empty(); |
| m_aFeaturesToInvalidate.push_back( aListener ); |
| } |
| |
| if ( bWasEmpty ) |
| m_aAsyncInvalidateAll.Call(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| void OGenericUnoController::InvalidateFeature(sal_uInt16 _nId, const Reference< XStatusListener > & _xListener, sal_Bool _bForceBroadcast) |
| { |
| ImplInvalidateFeature( _nId, _xListener, _bForceBroadcast ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| void OGenericUnoController::InvalidateAll() |
| { |
| ImplInvalidateFeature( ALL_FEATURES, NULL, sal_True ); |
| } |
| |
| // ----------------------------------------------------------------------------- |
| void OGenericUnoController::InvalidateAll_Impl() |
| { |
| // --------------------------------- |
| // invalidate all aupported features |
| |
| for ( SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.begin(); |
| aIter != m_aSupportedFeatures.end(); |
| ++aIter |
| ) |
| ImplBroadcastFeatureState( aIter->first, NULL, sal_True ); |
| |
| { |
| ::osl::MutexGuard aGuard( m_aFeatureMutex); |
| DBG_ASSERT(m_aFeaturesToInvalidate.size(), "OGenericUnoController::InvalidateAll_Impl: to be called from within InvalidateFeature_Impl only!"); |
| m_aFeaturesToInvalidate.pop_front(); |
| if(!m_aFeaturesToInvalidate.empty()) |
| m_aAsyncInvalidateAll.Call(); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| Reference< XDispatch > OGenericUnoController::queryDispatch(const URL& aURL, const ::rtl::OUString& aTargetFrameName, sal_Int32 nSearchFlags) throw( RuntimeException ) |
| { |
| Reference< XDispatch > xReturn; |
| |
| OSL_PRECOND( !m_aSupportedFeatures.empty(), "OGenericUnoController::queryDispatch: shouldn't this be filled at construction time?" ); |
| if ( m_aSupportedFeatures.empty() ) |
| fillSupportedFeatures(); |
| |
| // URL's we can handle ourself? |
| if ( aURL.Complete.equals( getConfirmDeletionURL() ) |
| || ( ( m_aSupportedFeatures.find( aURL.Complete ) != m_aSupportedFeatures.end() ) |
| && !isUserDefinedFeature( aURL.Complete ) |
| ) |
| ) |
| { |
| xReturn = this; |
| } |
| // no? -> ask the slave dispatcher |
| else if ( m_xSlaveDispatcher.is() ) |
| { |
| xReturn = m_xSlaveDispatcher->queryDispatch(aURL, aTargetFrameName, nSearchFlags); |
| } |
| |
| // outta here |
| return xReturn; |
| } |
| |
| // ----------------------------------------------------------------------- |
| Sequence< Reference< XDispatch > > OGenericUnoController::queryDispatches(const Sequence< DispatchDescriptor >& aDescripts) throw( RuntimeException ) |
| { |
| Sequence< Reference< XDispatch > > aReturn; |
| sal_Int32 nLen = aDescripts.getLength(); |
| if ( nLen ) |
| { |
| aReturn.realloc( nLen ); |
| Reference< XDispatch >* pReturn = aReturn.getArray(); |
| const Reference< XDispatch >* pReturnEnd = aReturn.getArray() + nLen; |
| const DispatchDescriptor* pDescripts = aDescripts.getConstArray(); |
| |
| for ( ; pReturn != pReturnEnd; ++ pReturn, ++pDescripts ) |
| { |
| *pReturn = queryDispatch( pDescripts->FeatureURL, pDescripts->FrameName, pDescripts->SearchFlags ); |
| } |
| } |
| |
| return aReturn; |
| } |
| |
| // ----------------------------------------------------------------------- |
| Reference< XDispatchProvider > OGenericUnoController::getSlaveDispatchProvider(void) throw( RuntimeException ) |
| { |
| return m_xSlaveDispatcher; |
| } |
| |
| // ----------------------------------------------------------------------- |
| void OGenericUnoController::setSlaveDispatchProvider(const Reference< XDispatchProvider > & _xNewProvider) throw( RuntimeException ) |
| { |
| m_xSlaveDispatcher = _xNewProvider; |
| } |
| |
| // ----------------------------------------------------------------------- |
| Reference< XDispatchProvider > OGenericUnoController::getMasterDispatchProvider(void) throw( RuntimeException ) |
| { |
| return m_xMasterDispatcher; |
| } |
| |
| // ----------------------------------------------------------------------- |
| void OGenericUnoController::setMasterDispatchProvider(const Reference< XDispatchProvider > & _xNewProvider) throw( RuntimeException ) |
| { |
| m_xMasterDispatcher = _xNewProvider; |
| } |
| |
| // ----------------------------------------------------------------------- |
| void OGenericUnoController::dispatch(const URL& _aURL, const Sequence< PropertyValue >& aArgs) throw(RuntimeException) |
| { |
| ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); |
| // Since the fix for #123967#, the SolarMutex is not locked anymore when the framework calls into |
| // here. So, lock it ourself. The real solution would be to lock it only in the places |
| // where it's needed, but a) this might turn out difficult, since we then also need to care |
| // for locking in the proper order (SolarMutex and m_aMutex), and b) this would be too many places |
| // for the time frame of the fix. |
| // #i52602# / frank.schoenheit@sun.com / 2005-07-29 |
| |
| #ifdef TIMELOG |
| ::rtl::OString sLog( "OGenericUnoController::dispatch( '" ); |
| sLog += ::rtl::OString( _aURL.Main.getStr(), _aURL.Main.getLength(), osl_getThreadTextEncoding() ); |
| sLog += ::rtl::OString( "' )" ); |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "frank.schoenheit@sun.com", sLog.getStr() ); |
| #endif |
| |
| executeChecked(_aURL,aArgs); |
| } |
| |
| // ----------------------------------------------------------------------- |
| void OGenericUnoController::addStatusListener(const Reference< XStatusListener > & aListener, const URL& _rURL) throw(RuntimeException) |
| { |
| // parse the ULR now and here, this saves later parsing in each notification round |
| URL aParsedURL( _rURL ); |
| if ( m_xUrlTransformer.is() ) |
| m_xUrlTransformer->parseStrict( aParsedURL ); |
| |
| // remeber the listener together with the URL |
| m_arrStatusListener.insert( m_arrStatusListener.end(), DispatchTarget( aParsedURL, aListener ) ); |
| |
| // initially broadcast the state |
| ImplBroadcastFeatureState( aParsedURL.Complete, aListener, sal_True ); |
| // force the new state to be broadcasted to the new listener |
| } |
| |
| // ----------------------------------------------------------------------- |
| void OGenericUnoController::removeStatusListener(const Reference< XStatusListener > & aListener, const URL& _rURL) throw(RuntimeException) |
| { |
| DispatchIterator iterSearch = m_arrStatusListener.begin(); |
| |
| sal_Bool bRemoveForAll = (_rURL.Complete.getLength() == 0); |
| while ( iterSearch != m_arrStatusListener.end() ) |
| { |
| DispatchTarget& rCurrent = *iterSearch; |
| if ( (rCurrent.xListener == aListener) |
| && ( bRemoveForAll |
| || (rCurrent.aURL.Complete.equals(_rURL.Complete)) |
| ) |
| ) |
| { |
| m_arrStatusListener.erase( iterSearch ); |
| if (!bRemoveForAll) |
| // remove the listener only for the given URL, so we can exit the loop after deletion |
| break; |
| } |
| else |
| ++iterSearch; |
| } |
| |
| OSL_PRECOND( !m_aSupportedFeatures.empty(), "OGenericUnoController::removeStatusListener: shouldn't this be filled at construction time?" ); |
| if ( m_aSupportedFeatures.empty() ) |
| fillSupportedFeatures(); |
| |
| SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.find(_rURL.Complete); |
| if (aIter != m_aSupportedFeatures.end()) |
| { // clear the cache for that feature |
| StateCacheIterator aCachePos = m_aStateCache.find( aIter->second.nFeatureId ); |
| if ( aCachePos != m_aStateCache.end() ) |
| m_aStateCache.erase( aCachePos ); |
| } |
| |
| // now remove the listener from the deque |
| ::osl::MutexGuard aGuard( m_aFeatureMutex ); |
| m_aFeaturesToInvalidate.erase( |
| ::std::remove_if( m_aFeaturesToInvalidate.begin(), |
| m_aFeaturesToInvalidate.end(), |
| ::std::bind2nd(FindFeatureListener(),aListener)) |
| ,m_aFeaturesToInvalidate.end()); |
| } |
| // ----------------------------------------------------------------------------- |
| void OGenericUnoController::releaseNumberForComponent() |
| { |
| try |
| { |
| Reference< XUntitledNumbers > xUntitledProvider(getPrivateModel(), UNO_QUERY ); |
| if ( xUntitledProvider.is() ) |
| xUntitledProvider->releaseNumberForComponent(static_cast<XWeak*>(this)); |
| } |
| catch( const Exception& ) |
| { |
| // NII |
| } |
| } |
| // ----------------------------------------------------------------------- |
| void OGenericUnoController::disposing() |
| { |
| { |
| EventObject aDisposeEvent; |
| aDisposeEvent.Source = static_cast<XWeak*>(this); |
| Dispatch aStatusListener = m_arrStatusListener; |
| Dispatch::iterator aEnd = aStatusListener.end(); |
| for (Dispatch::iterator aIter = aStatusListener.begin(); aIter != aEnd; ++aIter) |
| { |
| aIter->xListener->disposing(aDisposeEvent); |
| } |
| m_arrStatusListener.clear(); |
| } |
| |
| m_xDatabaseContext = NULL; |
| { |
| ::osl::MutexGuard aGuard( m_aFeatureMutex); |
| m_aAsyncInvalidateAll.CancelCall(); |
| m_aFeaturesToInvalidate.clear(); |
| } |
| |
| releaseNumberForComponent(); |
| |
| // check out from all the objects we are listening |
| // the frame |
| stopFrameListening( m_aCurrentFrame.getFrame() ); |
| m_aCurrentFrame.attachFrame( NULL ); |
| |
| m_xMasterDispatcher = NULL; |
| m_xSlaveDispatcher = NULL; |
| m_xServiceFactory = NULL; |
| m_xTitleHelper.clear(); |
| m_xUrlTransformer.clear(); |
| m_aInitParameters.clear(); |
| } |
| |
| // ----------------------------------------------------------------------------- |
| void SAL_CALL OGenericUnoController::addEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException) |
| { |
| // disambiguate |
| OGenericUnoController_Base::WeakComponentImplHelperBase::addEventListener( xListener ); |
| } |
| |
| // ----------------------------------------------------------------------------- |
| void SAL_CALL OGenericUnoController::removeEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException) |
| { |
| // disambiguate |
| OGenericUnoController_Base::WeakComponentImplHelperBase::removeEventListener( xListener ); |
| } |
| |
| //------------------------------------------------------------------------------ |
| void OGenericUnoController::frameAction(const FrameActionEvent& aEvent) throw( RuntimeException ) |
| { |
| ::osl::MutexGuard aGuard( getMutex() ); |
| if ( aEvent.Frame == m_aCurrentFrame.getFrame() ) |
| m_aCurrentFrame.frameAction( aEvent.Action ); |
| } |
| |
| //------------------------------------------------------------------------------ |
| void OGenericUnoController::implDescribeSupportedFeature( const sal_Char* _pAsciiCommandURL, |
| sal_uInt16 _nFeatureId, sal_Int16 _nCommandGroup ) |
| { |
| #ifdef DBG_UTIL |
| DBG_ASSERT( m_bDescribingSupportedFeatures, "OGenericUnoController::implDescribeSupportedFeature: bad timing for this call!" ); |
| #endif |
| OSL_PRECOND( _nFeatureId < FIRST_USER_DEFINED_FEATURE, "OGenericUnoController::implDescribeSupportedFeature: invalid feature id!" ); |
| |
| ControllerFeature aFeature; |
| aFeature.Command = ::rtl::OUString::createFromAscii( _pAsciiCommandURL ); |
| aFeature.nFeatureId = _nFeatureId; |
| aFeature.GroupId = _nCommandGroup; |
| |
| #if OSL_DEBUG_LEVEL > 0 |
| OSL_ENSURE( m_aSupportedFeatures.find( aFeature.Command ) == m_aSupportedFeatures.end(), |
| "OGenericUnoController::implDescribeSupportedFeature: this feature is already there!" ); |
| #endif |
| m_aSupportedFeatures[ aFeature.Command ] = aFeature; |
| } |
| |
| //------------------------------------------------------------------------------ |
| void OGenericUnoController::describeSupportedFeatures() |
| { |
| // add all supported features |
| implDescribeSupportedFeature( ".uno:Copy", ID_BROWSER_COPY, CommandGroup::EDIT ); |
| implDescribeSupportedFeature( ".uno:Cut", ID_BROWSER_CUT, CommandGroup::EDIT ); |
| implDescribeSupportedFeature( ".uno:Paste", ID_BROWSER_PASTE, CommandGroup::EDIT ); |
| implDescribeSupportedFeature( ".uno:ClipboardFormatItems", ID_BROWSER_CLIPBOARD_FORMAT_ITEMS ); |
| implDescribeSupportedFeature( ".uno:DSBEditDoc", ID_BROWSER_EDITDOC, CommandGroup::DOCUMENT ); |
| } |
| |
| //------------------------------------------------------------------------------ |
| FeatureState OGenericUnoController::GetState( sal_uInt16 _nId ) const |
| { |
| FeatureState aReturn; |
| // (disabled automatically) |
| |
| switch ( _nId ) |
| { |
| case ID_BROWSER_UNDO: |
| case ID_BROWSER_SAVEDOC: |
| aReturn.bEnabled = sal_True; |
| break; |
| default: |
| aReturn = m_pData->m_aUserDefinedFeatures.getState( getURLForId( _nId ) ); |
| break; |
| } |
| |
| return aReturn; |
| } |
| |
| //------------------------------------------------------------------------------ |
| void OGenericUnoController::Execute( sal_uInt16 _nId, const Sequence< PropertyValue>& _rArgs ) |
| { |
| OSL_ENSURE( isUserDefinedFeature( _nId ), |
| "OGenericUnoController::Execute: responsible for user defined features only!" ); |
| |
| // user defined features can be handled by dispatch interceptors resp. protocol handlers only. |
| // So, we need to do a queryDispatch, and dispatch the URL |
| m_pData->m_aUserDefinedFeatures.execute( getURLForId( _nId ), _rArgs ); |
| } |
| |
| //------------------------------------------------------------------------------ |
| URL OGenericUnoController::getURLForId(sal_Int32 _nId) const |
| { |
| URL aReturn; |
| if ( m_xUrlTransformer.is() ) |
| { |
| SupportedFeatures::const_iterator aIter = ::std::find_if( |
| m_aSupportedFeatures.begin(), |
| m_aSupportedFeatures.end(), |
| ::std::bind2nd( CompareFeatureById(), _nId ) |
| ); |
| |
| if ( m_aSupportedFeatures.end() != aIter && aIter->first.getLength() ) |
| { |
| aReturn.Complete = aIter->first; |
| m_xUrlTransformer->parseStrict( aReturn ); |
| } |
| } |
| return aReturn; |
| } |
| |
| //------------------------------------------------------------------------- |
| bool OGenericUnoController::isUserDefinedFeature( const sal_uInt16 _nFeatureId ) const |
| { |
| return ( _nFeatureId >= FIRST_USER_DEFINED_FEATURE ) && ( _nFeatureId < LAST_USER_DEFINED_FEATURE ); |
| } |
| |
| //------------------------------------------------------------------------- |
| bool OGenericUnoController::isUserDefinedFeature( const ::rtl::OUString& _rFeatureURL ) const |
| { |
| SupportedFeatures::const_iterator pos = m_aSupportedFeatures.find( _rFeatureURL ); |
| OSL_PRECOND( pos != m_aSupportedFeatures.end(), |
| "OGenericUnoController::isUserDefinedFeature: this is no supported feature at all!" ); |
| |
| return ( pos != m_aSupportedFeatures.end() ) ? isUserDefinedFeature( pos->second.nFeatureId ) : false; |
| } |
| |
| //------------------------------------------------------------------------- |
| sal_Bool SAL_CALL OGenericUnoController::supportsService(const ::rtl::OUString& ServiceName) throw(RuntimeException) |
| { |
| Sequence< ::rtl::OUString > aSupported(getSupportedServiceNames()); |
| |
| const ::rtl::OUString* pArray = aSupported.getConstArray(); |
| const ::rtl::OUString* pArrayEnd = aSupported.getConstArray() + aSupported.getLength(); |
| |
| for ( ;( pArray != pArrayEnd ) && !pArray->equals( ServiceName ); ++pArray ) |
| ; |
| return pArray != pArrayEnd; |
| } |
| |
| // ----------------------------------------------------------------------------- |
| void OGenericUnoController::startConnectionListening(const Reference< XConnection >& _rxConnection) |
| { |
| // we have to remove ourself before dispoing the connection |
| Reference< XComponent > xComponent(_rxConnection, UNO_QUERY); |
| if (xComponent.is()) |
| xComponent->addEventListener(static_cast<XFrameActionListener*>(this)); |
| } |
| |
| // ----------------------------------------------------------------------------- |
| void OGenericUnoController::stopConnectionListening(const Reference< XConnection >& _rxConnection) |
| { |
| // we have to remove ourself before dispoing the connection |
| Reference< XComponent > xComponent(_rxConnection, UNO_QUERY); |
| if (xComponent.is()) |
| xComponent->removeEventListener(static_cast<XFrameActionListener*>(this)); |
| } |
| // ----------------------------------------------------------------------------- |
| Reference< XConnection > OGenericUnoController::connect( const Reference< XDataSource>& _xDataSource, |
| ::dbtools::SQLExceptionInfo* _pErrorInfo ) |
| { |
| WaitObject aWaitCursor( getView() ); |
| |
| ODatasourceConnector aConnector( getORB(), getView(), ::rtl::OUString() ); |
| Reference< XConnection > xConnection = aConnector.connect( _xDataSource, _pErrorInfo ); |
| startConnectionListening( xConnection ); |
| |
| return xConnection; |
| } |
| // ----------------------------------------------------------------------------- |
| Reference< XConnection > OGenericUnoController::connect( const ::rtl::OUString& _rDataSourceName, |
| const ::rtl::OUString& _rContextInformation, ::dbtools::SQLExceptionInfo* _pErrorInfo ) |
| { |
| WaitObject aWaitCursor( getView() ); |
| |
| ODatasourceConnector aConnector( getORB(), getView(), _rContextInformation ); |
| Reference<XConnection> xConnection = aConnector.connect( _rDataSourceName, _pErrorInfo ); |
| startConnectionListening( xConnection ); |
| |
| return xConnection; |
| } |
| |
| // ----------------------------------------------------------------------------- |
| void OGenericUnoController::showError(const SQLExceptionInfo& _rInfo) |
| { |
| ::dbaui::showError(_rInfo,getView(),getORB()); |
| } |
| // ----------------------------------------------------------------------------- |
| Reference< XLayoutManager > OGenericUnoController::getLayoutManager(const Reference< XFrame >& _xFrame) const |
| { |
| Reference< XPropertySet > xPropSet( _xFrame, UNO_QUERY ); |
| Reference< XLayoutManager > xLayoutManager; |
| if ( xPropSet.is() ) |
| { |
| try |
| { |
| xLayoutManager.set(xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ))),UNO_QUERY); |
| } |
| catch ( Exception& ) |
| { |
| } |
| } |
| return xLayoutManager; |
| } |
| // ----------------------------------------------------------------------------- |
| void OGenericUnoController::loadMenu(const Reference< XFrame >& _xFrame) |
| { |
| Reference< XLayoutManager > xLayoutManager = getLayoutManager(_xFrame); |
| if ( xLayoutManager.is() ) |
| { |
| xLayoutManager->lock(); |
| xLayoutManager->createElement( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/menubar/menubar" ))); |
| xLayoutManager->createElement( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/toolbar" ))); |
| xLayoutManager->unlock(); |
| xLayoutManager->doLayout(); |
| } |
| |
| onLoadedMenu( xLayoutManager ); |
| } |
| |
| // ----------------------------------------------------------------------------- |
| void OGenericUnoController::onLoadedMenu(const Reference< XLayoutManager >& /*_xLayoutManager*/) |
| { |
| // not interested in |
| } |
| |
| // ----------------------------------------------------------------------------- |
| void OGenericUnoController::closeTask() |
| { |
| m_aAsyncCloseTask.Call(); |
| } |
| // ----------------------------------------------------------------------------- |
| IMPL_LINK(OGenericUnoController, OnAsyncCloseTask, void*, EMPTYARG) |
| { |
| if ( !OGenericUnoController_Base::rBHelper.bInDispose ) |
| { |
| try |
| { |
| Reference< util::XCloseable > xCloseable( m_aCurrentFrame.getFrame(), UNO_QUERY_THROW ); |
| xCloseable->close( sal_False ); // false - holds the owner ship for this frame inside this object! |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| return 0L; |
| } |
| // ----------------------------------------------------------------------------- |
| Any SAL_CALL OGenericUnoController::getViewData(void) throw( RuntimeException ) |
| { |
| return Any(); |
| } |
| // ----------------------------------------------------------------------------- |
| void SAL_CALL OGenericUnoController::restoreViewData(const Any& /*Data*/) throw( RuntimeException ) |
| { |
| } |
| |
| // ----------------------------------------------------------------------------- |
| Reference< XModel > SAL_CALL OGenericUnoController::getModel(void) throw( RuntimeException ) |
| { |
| return Reference< XModel >(); |
| } |
| |
| // ----------------------------------------------------------------------------- |
| Reference< XFrame > SAL_CALL OGenericUnoController::getFrame(void) throw( RuntimeException ) |
| { |
| ::osl::MutexGuard aGuard( getMutex() ); |
| return m_aCurrentFrame.getFrame(); |
| } |
| |
| // ----------------------------------------------------------------------------- |
| sal_Bool SAL_CALL OGenericUnoController::attachModel(const Reference< XModel > & /*xModel*/) throw( RuntimeException ) |
| { |
| OSL_ENSURE( false, "OGenericUnoController::attachModel: not supported!" ); |
| return sal_False; |
| } |
| |
| // ----------------------------------------------------------------------------- |
| void OGenericUnoController::executeUnChecked(sal_uInt16 _nCommandId, const Sequence< PropertyValue >& aArgs) |
| { |
| Execute(_nCommandId, aArgs); |
| } |
| // ----------------------------------------------------------------------------- |
| void OGenericUnoController::executeUnChecked(const util::URL& _rCommand, const Sequence< PropertyValue >& aArgs) |
| { |
| OSL_PRECOND( !m_aSupportedFeatures.empty(), "OGenericUnoController::executeUnChecked: shouldn't this be filled at construction time?" ); |
| if ( m_aSupportedFeatures.empty() ) |
| fillSupportedFeatures(); |
| |
| SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.find( _rCommand.Complete ); |
| if (aIter != m_aSupportedFeatures.end()) |
| Execute( aIter->second.nFeatureId, aArgs ); |
| } |
| // ----------------------------------------------------------------------------- |
| void OGenericUnoController::executeChecked(const util::URL& _rCommand, const Sequence< PropertyValue >& aArgs) |
| { |
| OSL_PRECOND( !m_aSupportedFeatures.empty(), "OGenericUnoController::executeChecked: shouldn't this be filled at construction time?" ); |
| if ( m_aSupportedFeatures.empty() ) |
| fillSupportedFeatures(); |
| |
| SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.find( _rCommand.Complete ); |
| if ( aIter != m_aSupportedFeatures.end() ) |
| { |
| sal_uInt16 nFeatureId = aIter->second.nFeatureId; |
| if ( GetState( nFeatureId ).bEnabled ) |
| Execute( nFeatureId, aArgs ); |
| } |
| } |
| // ----------------------------------------------------------------------------- |
| //------------------------------------------------------------------------------ |
| namespace |
| { |
| ::rtl::OUString lcl_getModuleHelpModuleName( const Reference< XFrame >& _rxFrame ) |
| { |
| const sal_Char* pReturn = NULL; |
| |
| try |
| { |
| // get the model of the document in the given frame |
| Reference< XController > xController; |
| if ( _rxFrame.is() ) |
| xController = _rxFrame->getController(); |
| Reference< XModel > xModel; |
| if ( xController.is() ) |
| xModel = xController->getModel(); |
| Reference< XServiceInfo > xSI( xModel, UNO_QUERY ); |
| |
| if ( !xSI.is() ) |
| { // try to go up the frame hierarchy |
| |
| Reference< XFrame > xParentFrame; |
| if ( _rxFrame.is() ) |
| xParentFrame = xParentFrame.query( _rxFrame->getCreator() ); |
| // did we find a parent frame? Which is no top-level frame? |
| if ( xParentFrame.is() && !_rxFrame->isTop() ) |
| // TODO: to prevent framework assertions, re-insert this "isTop" once 98303 is fixed |
| return lcl_getModuleHelpModuleName( xParentFrame ); |
| } |
| else |
| { |
| #if OSL_DEBUG_LEVEL > 0 |
| Sequence< ::rtl::OUString > sServiceNames = xSI->getSupportedServiceNames(); |
| const ::rtl::OUString* pLoop = sServiceNames.getConstArray(); |
| for ( sal_Int32 i=0; i<sServiceNames.getLength(); ++i, ++pLoop ) |
| { |
| sal_Int32 nDummy = 0; |
| (void)nDummy; |
| } |
| #endif |
| |
| // check which service we know .... |
| static const sal_Char* pTransTable[] = { |
| "com.sun.star.sdb.OfficeDatabaseDocument","sdatabase", |
| "com.sun.star.report.ReportDefinition","sdatabase", |
| "com.sun.star.text.TextDocument", "swriter", |
| "com.sun.star.sheet.SpreadsheetDocument", "scalc", |
| "com.sun.star.presentation.PresentationDocument", "simpress", |
| "com.sun.star.drawing.DrawingDocument", "sdraw", |
| "com.sun.star.formula.FormularProperties", "smath", |
| "com.sun.star.chart.ChartDocument", "schart" |
| }; |
| OSL_ENSURE( ( sizeof( pTransTable ) / sizeof( pTransTable[0] ) ) % 2 == 0, |
| "lcl_getModuleHelpModuleName: odd size of translation table!" ); |
| |
| // loop through the table |
| sal_Int32 nTableEntries = ( sizeof( pTransTable ) / sizeof( pTransTable[0] ) ) / 2; |
| const sal_Char** pDocumentService = pTransTable; |
| const sal_Char** pHelpModuleName = pTransTable + 1; |
| for ( sal_Int32 j=0; j<nTableEntries; ++j ) |
| { |
| if ( xSI->supportsService( ::rtl::OUString::createFromAscii( *pDocumentService ) ) ) |
| { // found a table entry which matches the model's services |
| pReturn = *pHelpModuleName; |
| break; |
| } |
| |
| ++pDocumentService; ++pDocumentService; |
| ++pHelpModuleName; ++pHelpModuleName; |
| } |
| } |
| |
| if ( !pReturn ) |
| { |
| // could not determine the document type we're living in |
| // ->fallback |
| SvtModuleOptions aModOpt; |
| if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) ) |
| pReturn = "swriter"; |
| else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) ) |
| pReturn = "sdatabase"; |
| else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) ) |
| pReturn = "scalc"; |
| else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) ) |
| pReturn = "simpress"; |
| else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) ) |
| pReturn = "sdraw"; |
| else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SMATH ) ) |
| pReturn = "smath"; |
| else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SCHART ) ) |
| pReturn = "schart"; |
| else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SBASIC ) ) |
| pReturn = "sbasic"; |
| else |
| { |
| OSL_ENSURE( sal_False, "lcl_getModuleHelpModuleName: no installed module found" ); |
| } |
| } |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| |
| if ( !pReturn ) |
| pReturn = "swriter"; |
| |
| return ::rtl::OUString::createFromAscii( pReturn ); |
| } |
| } |
| |
| // ----------------------------------------------------------------------------- |
| |
| void OGenericUnoController::openHelpAgent(rtl::OUString const& _suHelpStringURL ) |
| { |
| rtl::OUString suURL(_suHelpStringURL); |
| rtl::OUString sLanguage = rtl::OUString::createFromAscii("Language="); |
| if (suURL.indexOf(sLanguage) == -1) |
| { |
| AppendConfigToken(suURL, sal_False /* sal_False := add '&' */ ); |
| } |
| URL aURL; |
| aURL.Complete = suURL; |
| |
| openHelpAgent( aURL ); |
| } |
| |
| void OGenericUnoController::openHelpAgent(const rtl::OString& _sHelpId) |
| { |
| openHelpAgent( createHelpAgentURL( lcl_getModuleHelpModuleName( getFrame() ), _sHelpId ) ); |
| } |
| |
| void OGenericUnoController::openHelpAgent( const URL& _rURL ) |
| { |
| try |
| { |
| URL aURL( _rURL ); |
| |
| if ( m_xUrlTransformer.is() ) |
| m_xUrlTransformer->parseStrict(aURL); |
| |
| Reference< XDispatchProvider > xDispProv( m_aCurrentFrame.getFrame(), UNO_QUERY ); |
| Reference< XDispatch > xHelpDispatch; |
| if ( xDispProv.is() ) |
| xHelpDispatch = xDispProv->queryDispatch(aURL, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_helpagent")), FrameSearchFlag::PARENT | FrameSearchFlag::SELF); |
| OSL_ENSURE(xHelpDispatch.is(), "SbaTableQueryBrowser::openHelpAgent: could not get a dispatcher!"); |
| if (xHelpDispatch.is()) |
| { |
| xHelpDispatch->dispatch(aURL, Sequence< PropertyValue >()); |
| } |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| // ----------------------------------------------------------------------------- |
| Reference< awt::XWindow> OGenericUnoController::getTopMostContainerWindow() const |
| { |
| Reference< ::com::sun::star::awt::XWindow> xWindow; |
| |
| // get the top most window |
| Reference< XFrame > xFrame( m_aCurrentFrame.getFrame() ); |
| if ( xFrame.is() ) |
| { |
| xWindow = xFrame->getContainerWindow(); |
| |
| while ( xFrame.is() && !xFrame->isTop() ) |
| { |
| xFrame.set( xFrame->getCreator(), UNO_QUERY ); |
| } |
| if ( xFrame.is() ) |
| xWindow = xFrame->getContainerWindow(); |
| } |
| return xWindow; |
| } |
| // ----------------------------------------------------------------------------- |
| Reference< XTitle > OGenericUnoController::impl_getTitleHelper_throw() |
| { |
| ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); |
| ::osl::MutexGuard aGuard( getMutex() ); |
| |
| if ( ! m_xTitleHelper.is ()) |
| { |
| Reference< XUntitledNumbers > xUntitledProvider(getPrivateModel(), UNO_QUERY ); |
| Reference< XController > xThis(static_cast< XController* >(this), UNO_QUERY_THROW); |
| |
| ::framework::TitleHelper* pHelper = new ::framework::TitleHelper(m_xServiceFactory); |
| m_xTitleHelper.set( static_cast< ::cppu::OWeakObject* >(pHelper), UNO_QUERY_THROW); |
| |
| pHelper->setOwner (xThis ); |
| pHelper->connectWithUntitledNumbers (xUntitledProvider); |
| } |
| |
| return m_xTitleHelper; |
| } |
| |
| //============================================================================= |
| // XTitle |
| ::rtl::OUString SAL_CALL OGenericUnoController::getTitle() |
| throw (RuntimeException) |
| { |
| ::osl::MutexGuard aGuard( getMutex() ); |
| if ( m_bExternalTitle ) |
| return impl_getTitleHelper_throw()->getTitle (); |
| return getPrivateTitle() + impl_getTitleHelper_throw()->getTitle (); |
| } |
| |
| //============================================================================= |
| // XTitle |
| void SAL_CALL OGenericUnoController::setTitle(const ::rtl::OUString& sTitle) |
| throw (RuntimeException) |
| { |
| vos::OGuard aSolarGuard( Application::GetSolarMutex() ); |
| ::osl::MutexGuard aGuard( getMutex() ); |
| m_bExternalTitle = sal_True; |
| impl_getTitleHelper_throw()->setTitle (sTitle); |
| } |
| |
| //============================================================================= |
| // XTitleChangeBroadcaster |
| void SAL_CALL OGenericUnoController::addTitleChangeListener(const Reference< XTitleChangeListener >& xListener) |
| throw (RuntimeException) |
| { |
| Reference< XTitleChangeBroadcaster > xBroadcaster(impl_getTitleHelper_throw(), UNO_QUERY); |
| if (xBroadcaster.is ()) |
| xBroadcaster->addTitleChangeListener (xListener); |
| } |
| |
| // ----------------------------------------------------------------------------- |
| void SAL_CALL OGenericUnoController::removeTitleChangeListener(const Reference< XTitleChangeListener >& xListener) |
| throw (RuntimeException) |
| { |
| Reference< XTitleChangeBroadcaster > xBroadcaster(impl_getTitleHelper_throw(), UNO_QUERY); |
| if (xBroadcaster.is ()) |
| xBroadcaster->removeTitleChangeListener (xListener); |
| } |
| |
| // ============================================================================= |
| // XUserInputInterception |
| // ----------------------------------------------------------------------------- |
| void SAL_CALL OGenericUnoController::addKeyHandler( const Reference< XKeyHandler >& _rxHandler ) throw (RuntimeException) |
| { |
| if ( _rxHandler.is() ) |
| m_pData->m_aUserInputInterception.addKeyHandler( _rxHandler ); |
| } |
| |
| // ----------------------------------------------------------------------------- |
| void SAL_CALL OGenericUnoController::removeKeyHandler( const Reference< XKeyHandler >& _rxHandler ) throw (RuntimeException) |
| { |
| m_pData->m_aUserInputInterception.removeKeyHandler( _rxHandler ); |
| } |
| |
| // ----------------------------------------------------------------------------- |
| void SAL_CALL OGenericUnoController::addMouseClickHandler( const Reference< XMouseClickHandler >& _rxHandler ) throw (RuntimeException) |
| { |
| if ( _rxHandler.is() ) |
| m_pData->m_aUserInputInterception.addMouseClickHandler( _rxHandler ); |
| } |
| |
| // ----------------------------------------------------------------------------- |
| void SAL_CALL OGenericUnoController::removeMouseClickHandler( const Reference< XMouseClickHandler >& _rxHandler ) throw (RuntimeException) |
| { |
| m_pData->m_aUserInputInterception.removeMouseClickHandler( _rxHandler ); |
| } |
| |
| // ============================================================================= |
| // ----------------------------------------------------------------------------- |
| void OGenericUnoController::executeChecked(sal_uInt16 _nCommandId, const Sequence< PropertyValue >& aArgs) |
| { |
| if ( isCommandEnabled(_nCommandId) ) |
| Execute(_nCommandId, aArgs); |
| } |
| |
| // ----------------------------------------------------------------------------- |
| sal_Bool OGenericUnoController::isCommandEnabled(sal_uInt16 _nCommandId) const |
| { |
| return GetState( _nCommandId ).bEnabled; |
| } |
| |
| // ----------------------------------------------------------------------------- |
| sal_uInt16 OGenericUnoController::registerCommandURL( const ::rtl::OUString& _rCompleteCommandURL ) |
| { |
| if ( !_rCompleteCommandURL.getLength() ) |
| return 0; |
| |
| SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.find( _rCompleteCommandURL ); |
| if ( aIter != m_aSupportedFeatures.end() ) |
| return aIter->second.nFeatureId; |
| |
| // this is a previously unkwnon command |
| sal_uInt16 nFeatureId = FIRST_USER_DEFINED_FEATURE; |
| while ( isFeatureSupported( nFeatureId ) && ( nFeatureId < LAST_USER_DEFINED_FEATURE ) ) |
| ++nFeatureId; |
| if ( nFeatureId == LAST_USER_DEFINED_FEATURE ) |
| { |
| OSL_ENSURE( false, "OGenericUnoController::registerCommandURL: no more space for user defined features!" ); |
| return 0L; |
| } |
| |
| ControllerFeature aFeature; |
| aFeature.Command = _rCompleteCommandURL; |
| aFeature.nFeatureId = nFeatureId; |
| aFeature.GroupId = CommandGroup::INTERNAL; |
| m_aSupportedFeatures[ aFeature.Command ] = aFeature; |
| |
| return nFeatureId; |
| } |
| |
| // ----------------------------------------------------------------------------- |
| void OGenericUnoController::notifyHiContrastChanged() |
| { |
| } |
| |
| // ----------------------------------------------------------------------------- |
| sal_Bool OGenericUnoController::isDataSourceReadOnly() const |
| { |
| return sal_False; |
| } |
| |
| // ----------------------------------------------------------------------------- |
| Reference< XController > OGenericUnoController::getXController() throw( RuntimeException ) |
| { |
| return this; |
| } |
| |
| // ----------------------------------------------------------------------------- |
| bool OGenericUnoController::interceptUserInput( const NotifyEvent& _rEvent ) |
| { |
| return m_pData->m_aUserInputInterception.handleNotifyEvent( _rEvent ); |
| } |
| |
| // ----------------------------------------------------------------------------- |
| sal_Bool OGenericUnoController::isCommandChecked(sal_uInt16 _nCommandId) const |
| { |
| FeatureState aState = GetState( _nCommandId ); |
| |
| return aState.bChecked && (sal_Bool)*aState.bChecked; |
| } |
| // ----------------------------------------------------------------------------- |
| sal_Bool OGenericUnoController::isCommandEnabled( const ::rtl::OUString& _rCompleteCommandURL ) const |
| { |
| OSL_ENSURE( _rCompleteCommandURL.getLength(), "OGenericUnoController::isCommandEnabled: Empty command url!" ); |
| |
| sal_Bool bIsEnabled = sal_False; |
| SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.find( _rCompleteCommandURL ); |
| if ( aIter != m_aSupportedFeatures.end() ) |
| bIsEnabled = isCommandEnabled( aIter->second.nFeatureId ); |
| |
| return bIsEnabled; |
| } |
| |
| // ----------------------------------------------------------------------------- |
| Sequence< ::sal_Int16 > SAL_CALL OGenericUnoController::getSupportedCommandGroups() throw (RuntimeException) |
| { |
| CommandHashMap aCmdHashMap; |
| for ( SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.begin(); |
| aIter != m_aSupportedFeatures.end(); |
| ++aIter |
| ) |
| if ( aIter->second.GroupId != CommandGroup::INTERNAL ) |
| aCmdHashMap.insert( CommandHashMap::value_type( aIter->second.GroupId, 0 )); |
| |
| Sequence< sal_Int16 > aCommandGroups( aCmdHashMap.size() ); |
| ::std::transform( aCmdHashMap.begin(), |
| aCmdHashMap.end(), |
| aCommandGroups.getArray(), |
| ::std::select1st< CommandHashMap::value_type >() |
| ); |
| |
| return aCommandGroups; |
| } |
| |
| // ----------------------------------------------------------------------------- |
| Sequence< DispatchInformation > SAL_CALL OGenericUnoController::getConfigurableDispatchInformation( ::sal_Int16 CommandGroup ) throw (RuntimeException) |
| { |
| DispatchInfoList aInformationList; |
| DispatchInformation aDispatchInfo; |
| for ( SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.begin(); |
| aIter != m_aSupportedFeatures.end(); |
| ++aIter |
| ) |
| { |
| if ( sal_Int16( aIter->second.GroupId ) == CommandGroup ) |
| { |
| aDispatchInfo = aIter->second; |
| aInformationList.push_back( aDispatchInfo ); |
| } |
| } |
| |
| Sequence< DispatchInformation > aInformation( aInformationList.size() ); |
| ::std::transform( aInformationList.begin(), |
| aInformationList.end(), |
| aInformation.getArray(), |
| ::std::identity< DispatchInformation >() |
| ); |
| |
| return aInformation; |
| } |
| // ----------------------------------------------------------------------------- |
| void OGenericUnoController::fillSupportedFeatures() |
| { |
| #ifdef DBG_UTIL |
| m_bDescribingSupportedFeatures = true; |
| #endif |
| describeSupportedFeatures(); |
| // ----------------------------------------------------------------------------- |
| #ifdef DBG_UTIL |
| m_bDescribingSupportedFeatures = false; |
| #endif |
| } |
| |
| |
| void SAL_CALL OGenericUnoController::dispose() throw(::com::sun::star::uno::RuntimeException) |
| { |
| ::vos::OGuard aSolarGuard(Application::GetSolarMutex()); |
| OGenericUnoController_Base::dispose(); |
| } |
| } // namespace dbaui |
| |