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_unotools.hxx" 30 #include <unotools/sharedunocomponent.hxx> 31 #include <com/sun/star/lang/XComponent.hpp> 32 #include <com/sun/star/util/XCloseable.hpp> 33 #include <cppuhelper/implbase1.hxx> 34 #include <tools/debug.hxx> 35 36 //............................................................................ 37 namespace utl 38 { 39 //............................................................................ 40 41 using ::com::sun::star::uno::XInterface; 42 using ::com::sun::star::uno::Reference; 43 using ::com::sun::star::uno::Exception; 44 using ::com::sun::star::uno::UNO_QUERY; 45 using ::com::sun::star::uno::RuntimeException; 46 using ::com::sun::star::lang::XComponent; 47 using ::com::sun::star::lang::EventObject; 48 using ::com::sun::star::util::XCloseable; 49 using ::com::sun::star::util::XCloseListener; 50 using ::com::sun::star::util::CloseVetoException; 51 52 //======================================================================== 53 //= DisposableComponent 54 //======================================================================== 55 //------------------------------------------------------------------------ 56 DisposableComponent::DisposableComponent( const Reference< XInterface >& _rxComponent ) 57 :m_xComponent( _rxComponent, UNO_QUERY ) 58 { 59 DBG_ASSERT( m_xComponent.is() || !_rxComponent.is(), "DisposableComponent::DisposableComponent: should be an XComponent!" ); 60 } 61 62 //------------------------------------------------------------------------ 63 DisposableComponent::~DisposableComponent() 64 { 65 if ( m_xComponent.is() ) 66 { 67 try 68 { 69 m_xComponent->dispose(); 70 } 71 catch( const Exception& ) 72 { 73 OSL_ENSURE( sal_False, "DisposableComponent::~DisposableComponent: caught an exception!" ); 74 } 75 m_xComponent.clear(); 76 } 77 } 78 79 //======================================================================== 80 //= CloseableComponentImpl 81 //======================================================================== 82 DBG_NAME( CloseableComponentImpl ) 83 typedef ::cppu::WeakImplHelper1 < XCloseListener 84 > CloseableComponentImpl_Base; 85 class CloseableComponentImpl : public CloseableComponentImpl_Base 86 { 87 private: 88 Reference< XCloseable > m_xCloseable; 89 90 public: 91 CloseableComponentImpl( const Reference< XInterface >& _rxComponent ); 92 93 /** closes the component 94 95 @nofail 96 */ 97 void nf_closeComponent(); 98 99 protected: 100 virtual ~CloseableComponentImpl(); 101 102 // XCloseListener overridables 103 virtual void SAL_CALL queryClosing( const EventObject& Source, ::sal_Bool GetsOwnership ) throw (CloseVetoException, RuntimeException); 104 virtual void SAL_CALL notifyClosing( const EventObject& Source ) throw (RuntimeException); 105 106 // XEventListener overridables 107 virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException); 108 109 private: 110 /** starts or stops being a CloseListener at the component 111 112 Only to be called upon construction of the instance, or when the component 113 is to be closed. 114 115 @nofail 116 */ 117 void impl_nf_switchListening( bool _bListen ); 118 119 120 private: 121 CloseableComponentImpl(); // never implemented 122 CloseableComponentImpl( const CloseableComponentImpl& ); // never implemented 123 CloseableComponentImpl& operator=( const CloseableComponentImpl& ); // never implemented 124 }; 125 126 //------------------------------------------------------------------------ 127 CloseableComponentImpl::CloseableComponentImpl( const Reference< XInterface >& _rxComponent ) 128 :m_xCloseable( _rxComponent, UNO_QUERY ) 129 { 130 DBG_CTOR( CloseableComponentImpl, NULL ); 131 DBG_ASSERT( m_xCloseable.is() || !_rxComponent.is(), "CloseableComponentImpl::CloseableComponentImpl: component is not an XCloseable!" ); 132 impl_nf_switchListening( true ); 133 } 134 //------------------------------------------------------------------------ 135 CloseableComponentImpl::~CloseableComponentImpl() 136 { 137 nf_closeComponent(); 138 DBG_DTOR( CloseableComponentImpl, NULL ); 139 } 140 141 //------------------------------------------------------------------------ 142 void CloseableComponentImpl::nf_closeComponent() 143 { 144 if ( !m_xCloseable.is() ) 145 // nothing to do 146 return; 147 148 // stop listening 149 impl_nf_switchListening( false ); 150 151 // close 152 try 153 { 154 m_xCloseable->close( sal_True ); 155 } 156 catch( const CloseVetoException& ) { /* fine */ } 157 catch( const Exception& ) 158 { 159 OSL_ENSURE( sal_False, "CloseableComponentImpl::nf_closeComponent: caught an unexpected exception!" ); 160 } 161 162 // reset 163 m_xCloseable.clear(); 164 } 165 166 //------------------------------------------------------------------------ 167 void CloseableComponentImpl::impl_nf_switchListening( bool _bListen ) 168 { 169 if ( !m_xCloseable.is() ) 170 return; 171 172 try 173 { 174 if ( _bListen ) 175 m_xCloseable->addCloseListener( this ); 176 else 177 m_xCloseable->removeCloseListener( this ); 178 } 179 catch( const Exception& ) 180 { 181 OSL_ENSURE( sal_False, "CloseableComponentImpl::impl_nf_switchListening: caught an exception!" ); 182 } 183 } 184 185 //-------------------------------------------------------------------- 186 void SAL_CALL CloseableComponentImpl::queryClosing( const EventObject& 187 #ifdef DBG_UTIL 188 Source 189 #endif 190 , ::sal_Bool /*GetsOwnership*/ ) throw (CloseVetoException, RuntimeException) 191 { 192 // as long as we live, somebody wants to keep the object alive. So, veto the 193 // closing 194 DBG_ASSERT( Source.Source == m_xCloseable, "CloseableComponentImpl::queryClosing: where did this come from?" ); 195 throw CloseVetoException(); 196 } 197 198 //-------------------------------------------------------------------- 199 void SAL_CALL CloseableComponentImpl::notifyClosing( const EventObject& 200 #ifdef DBG_UTIL 201 Source 202 #endif 203 ) throw (RuntimeException) 204 { 205 DBG_ASSERT( Source.Source == m_xCloseable, "CloseableComponentImpl::notifyClosing: where did this come from?" ); 206 207 // this should be unreachable: As long as we're a CloseListener, we veto the closing. If we're going 208 // to close the component ourself, then we revoke ourself as listener *before* the close call. So, 209 // if this here fires, something went definately wrong. 210 DBG_ERROR( "CloseableComponentImpl::notifyClosing: unreachable!" ); 211 } 212 213 //-------------------------------------------------------------------- 214 void SAL_CALL CloseableComponentImpl::disposing( const EventObject& 215 #ifdef DBG_UTIL 216 Source 217 #endif 218 ) throw (RuntimeException) 219 { 220 DBG_ASSERT( Source.Source == m_xCloseable, "CloseableComponentImpl::disposing: where did this come from?" ); 221 DBG_ERROR( "CloseableComponentImpl::disposing: unreachable!" ); 222 // same reasoning for this assertion as in ->notifyClosing 223 } 224 225 //======================================================================== 226 //= CloseableComponentImpl 227 //======================================================================== 228 DBG_NAME( CloseableComponent ) 229 //------------------------------------------------------------------------ 230 CloseableComponent::CloseableComponent( const Reference< XInterface >& _rxComponent ) 231 :m_pImpl( new CloseableComponentImpl( _rxComponent ) ) 232 { 233 DBG_CTOR( CloseableComponent, NULL ); 234 } 235 236 //------------------------------------------------------------------------ 237 CloseableComponent::~CloseableComponent() 238 { 239 // close the component, deliver ownership to anybody who wants to veto the close 240 m_pImpl->nf_closeComponent(); 241 DBG_DTOR( CloseableComponent, NULL ); 242 } 243 244 //............................................................................ 245 } // namespace utl 246 //............................................................................ 247