1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_svx.hxx" 30 31 #include "formfeaturedispatcher.hxx" 32 33 #include <comphelper/namedvaluecollection.hxx> 34 #include <tools/diagnose_ex.h> 35 36 //........................................................................ 37 namespace svx 38 { 39 //........................................................................ 40 41 using namespace ::com::sun::star::uno; 42 using namespace ::com::sun::star::lang; 43 using namespace ::com::sun::star::frame; 44 using namespace ::com::sun::star::beans; 45 using namespace ::com::sun::star::util; 46 using namespace ::com::sun::star::form::runtime; 47 48 //==================================================================== 49 //= OSingleFeatureDispatcher 50 //==================================================================== 51 //-------------------------------------------------------------------- 52 OSingleFeatureDispatcher::OSingleFeatureDispatcher( const URL& _rFeatureURL, const sal_Int16 _nFormFeature, 53 const Reference< XFormOperations >& _rxFormOperations, ::osl::Mutex& _rMutex ) 54 :m_rMutex( _rMutex ) 55 ,m_aStatusListeners( _rMutex ) 56 ,m_xFormOperations( _rxFormOperations ) 57 ,m_aFeatureURL( _rFeatureURL ) 58 ,m_nFormFeature( _nFormFeature ) 59 ,m_bLastKnownEnabled( sal_False ) 60 ,m_bDisposed( sal_False ) 61 { 62 } 63 64 //-------------------------------------------------------------------- 65 void OSingleFeatureDispatcher::dispose() 66 { 67 { 68 ::osl::MutexGuard aGuard( m_rMutex ); 69 if ( m_bDisposed ) 70 return; 71 } 72 73 EventObject aDisposeEvent( *this ); 74 m_aStatusListeners.disposeAndClear( aDisposeEvent ); 75 76 { 77 ::osl::MutexGuard aGuard( m_rMutex ); 78 m_bDisposed = sal_True; 79 } 80 } 81 82 //-------------------------------------------------------------------- 83 void OSingleFeatureDispatcher::getUnoState( FeatureStateEvent& /* [out] */ _rState ) const 84 { 85 _rState.Source = *const_cast< OSingleFeatureDispatcher* >( this ); 86 87 FeatureState aState( m_xFormOperations->getState( m_nFormFeature ) ); 88 89 _rState.FeatureURL = m_aFeatureURL; 90 _rState.IsEnabled = aState.Enabled; 91 _rState.Requery = sal_False; 92 _rState.State = aState.State; 93 } 94 95 //-------------------------------------------------------------------- 96 void OSingleFeatureDispatcher::updateAllListeners() 97 { 98 ::osl::ClearableMutexGuard aGuard( m_rMutex ); 99 100 FeatureStateEvent aUnoState; 101 getUnoState( aUnoState ); 102 103 if ( ( m_aLastKnownState == aUnoState.State ) && ( m_bLastKnownEnabled == aUnoState.IsEnabled ) ) 104 return; 105 106 m_aLastKnownState = aUnoState.State; 107 m_bLastKnownEnabled = aUnoState.IsEnabled; 108 109 notifyStatus( NULL, aGuard ); 110 } 111 112 //-------------------------------------------------------------------- 113 void OSingleFeatureDispatcher::notifyStatus( const Reference< XStatusListener >& _rxListener, ::osl::ClearableMutexGuard& _rFreeForNotification ) 114 { 115 FeatureStateEvent aUnoState; 116 getUnoState( aUnoState ); 117 118 if ( _rxListener.is() ) 119 { 120 try 121 { 122 _rFreeForNotification.clear(); 123 _rxListener->statusChanged( aUnoState ); 124 } 125 catch( const Exception& ) 126 { 127 OSL_ENSURE( sal_False, "OSingleFeatureDispatcher::notifyStatus: caught an exception!" ); 128 } 129 } 130 else 131 { 132 ::cppu::OInterfaceIteratorHelper aIter( m_aStatusListeners ); 133 _rFreeForNotification.clear(); 134 135 while ( aIter.hasMoreElements() ) 136 { 137 try 138 { 139 static_cast< XStatusListener* >( aIter.next() )->statusChanged( aUnoState ); 140 } 141 catch( const DisposedException& ) 142 { 143 OSL_ENSURE( sal_False, "OSingleFeatureDispatcher::notifyStatus: caught a DisposedException - removing the listener!" ); 144 aIter.remove( ); 145 } 146 catch( const Exception& ) 147 { 148 OSL_ENSURE( sal_False, "OSingleFeatureDispatcher::notifyStatus: caught a generic exception while notifying a single listener!" ); 149 } 150 } 151 } 152 } 153 154 //-------------------------------------------------------------------- 155 void SAL_CALL OSingleFeatureDispatcher::dispatch( const URL& _rURL, const Sequence< PropertyValue >& _rArguments ) throw (RuntimeException) 156 { 157 ::osl::ClearableMutexGuard aGuard( m_rMutex ); 158 checkAlive(); 159 160 OSL_ENSURE( _rURL.Complete == m_aFeatureURL.Complete, "OSingleFeatureDispatcher::dispatch: not responsible for this URL!" ); 161 (void)_rURL; 162 163 if ( !m_xFormOperations->isEnabled( m_nFormFeature ) ) 164 return; 165 166 // release our mutex before executing the command 167 sal_Int16 nFormFeature( m_nFormFeature ); 168 Reference< XFormOperations > xFormOperations( m_xFormOperations ); 169 aGuard.clear(); 170 171 try 172 { 173 if ( !_rArguments.getLength() ) 174 { 175 xFormOperations->execute( nFormFeature ); 176 } 177 else 178 { // at the moment we only support one parameter 179 ::comphelper::NamedValueCollection aArgs( _rArguments ); 180 xFormOperations->executeWithArguments( nFormFeature, aArgs.getNamedValues() ); 181 } 182 } 183 catch( const RuntimeException& ) 184 { 185 throw; 186 } 187 catch( const Exception& ) 188 { 189 DBG_UNHANDLED_EXCEPTION(); 190 } 191 } 192 193 //-------------------------------------------------------------------- 194 void SAL_CALL OSingleFeatureDispatcher::addStatusListener( const Reference< XStatusListener >& _rxControl, const URL& _rURL ) throw (RuntimeException) 195 { 196 (void)_rURL; 197 OSL_ENSURE( _rURL.Complete == m_aFeatureURL.Complete, "OSingleFeatureDispatcher::addStatusListener: unexpected URL!" ); 198 OSL_ENSURE( _rxControl.is(), "OSingleFeatureDispatcher::addStatusListener: senseless call!" ); 199 if ( !_rxControl.is() ) 200 return; 201 202 ::osl::ClearableMutexGuard aGuard( m_rMutex ); 203 if ( m_bDisposed ) 204 { 205 EventObject aDisposeEvent( *this ); 206 aGuard.clear(); 207 _rxControl->disposing( aDisposeEvent ); 208 return; 209 } 210 211 m_aStatusListeners.addInterface( _rxControl ); 212 213 // initially update the status 214 notifyStatus( _rxControl, aGuard ); 215 } 216 217 //-------------------------------------------------------------------- 218 void SAL_CALL OSingleFeatureDispatcher::removeStatusListener( const Reference< XStatusListener >& _rxControl, const URL& _rURL ) throw (RuntimeException) 219 { 220 (void)_rURL; 221 OSL_ENSURE( _rURL.Complete == m_aFeatureURL.Complete, "OSingleFeatureDispatcher::removeStatusListener: unexpected URL!" ); 222 OSL_ENSURE( _rxControl.is(), "OSingleFeatureDispatcher::removeStatusListener: senseless call!" ); 223 if ( !_rxControl.is() ) 224 return; 225 226 ::osl::MutexGuard aGuard( m_rMutex ); 227 checkAlive(); 228 229 m_aStatusListeners.removeInterface( _rxControl ); 230 } 231 232 //-------------------------------------------------------------------- 233 void OSingleFeatureDispatcher::checkAlive() const SAL_THROW((DisposedException)) 234 { 235 if ( m_bDisposed ) 236 throw DisposedException( ::rtl::OUString(), *const_cast< OSingleFeatureDispatcher* >( this ) ); 237 } 238 239 //........................................................................ 240 } // namespace svx 241 //........................................................................ 242