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_forms.hxx" 30 #include "EventThread.hxx" 31 #include <comphelper/guarding.hxx> 32 #include <tools/debug.hxx> 33 34 //......................................................................... 35 namespace frm 36 { 37 //......................................................................... 38 using namespace ::com::sun::star::uno; 39 using namespace ::com::sun::star::awt; 40 using namespace ::com::sun::star::lang; 41 42 DBG_NAME( OComponentEventThread ) 43 OComponentEventThread::OComponentEventThread( ::cppu::OComponentHelper* pCompImpl ) : 44 m_pCompImpl( pCompImpl ) 45 { 46 DBG_CTOR( OComponentEventThread, NULL ); 47 48 increment(m_refCount); 49 50 // Eine Referenz des Controls halten 51 { 52 InterfaceRef xIFace(static_cast<XWeak*>(pCompImpl)); 53 query_interface(xIFace, m_xComp); 54 } 55 56 // und uns an dem Control anmelden 57 { 58 Reference<XEventListener> xEvtLstnr = static_cast<XEventListener*>(this); 59 m_xComp->addEventListener( xEvtLstnr ); 60 } 61 62 decrement(m_refCount); 63 } 64 65 OComponentEventThread::~OComponentEventThread() 66 { 67 DBG_DTOR( OComponentEventThread, NULL ); 68 69 DBG_ASSERT( m_aEvents.size() == 0, 70 "OComponentEventThread::~OComponentEventThread: Kein dispose gerufen?" ); 71 72 impl_clearEventQueue(); 73 } 74 75 Any SAL_CALL OComponentEventThread::queryInterface(const Type& _rType) throw (RuntimeException) 76 { 77 Any aReturn; 78 79 aReturn = OWeakObject::queryInterface(_rType); 80 81 if (!aReturn.hasValue()) 82 aReturn = ::cppu::queryInterface(_rType, 83 static_cast<XEventListener*>(this) 84 ); 85 86 return aReturn; 87 } 88 89 void OComponentEventThread::impl_clearEventQueue() 90 { 91 while ( m_aEvents.size() ) 92 { 93 delete *m_aEvents.begin(); 94 m_aEvents.erase( m_aEvents.begin() ); 95 } 96 m_aControls.erase( m_aControls.begin(), m_aControls.end() ); 97 m_aFlags.erase( m_aFlags.begin(), m_aFlags.end() ); 98 } 99 100 void OComponentEventThread::disposing( const EventObject& evt ) throw ( ::com::sun::star::uno::RuntimeException) 101 { 102 if( evt.Source == m_xComp ) 103 { 104 ::osl::MutexGuard aGuard( m_aMutex ); 105 106 // Event-Listener abmelden 107 Reference<XEventListener> xEvtLstnr = static_cast<XEventListener*>(this); 108 m_xComp->removeEventListener( xEvtLstnr ); 109 110 // Event-Queue loeschen 111 impl_clearEventQueue(); 112 113 // Das Control loslassen und pCompImpl auf 0 setzen, damit der 114 // Thread weiss, dass er sich beenden soll. 115 m_xComp = 0; 116 m_pCompImpl = 0; 117 118 // Den Thread aufwecken und beenden. 119 m_aCond.set(); 120 terminate(); 121 } 122 } 123 124 void OComponentEventThread::addEvent( const EventObject* _pEvt, sal_Bool bFlag ) 125 { 126 Reference<XControl> xTmp; 127 addEvent( _pEvt, xTmp, bFlag ); 128 } 129 130 void OComponentEventThread::addEvent( const EventObject* _pEvt, 131 const Reference<XControl>& rControl, 132 sal_Bool bFlag ) 133 { 134 ::osl::MutexGuard aGuard( m_aMutex ); 135 136 // Daten in die Queue stellen 137 m_aEvents.push_back( cloneEvent( _pEvt ) ); 138 139 Reference<XWeak> xWeakControl(rControl, UNO_QUERY); 140 Reference<XAdapter> xControlAdapter = xWeakControl.is() ? xWeakControl->queryAdapter() : Reference<XAdapter>(); 141 m_aControls.push_back( xControlAdapter ); 142 143 m_aFlags.push_back( bFlag ); 144 145 // Thread aufwecken 146 m_aCond.set(); 147 } 148 149 //--------------------------------------------------------------------- 150 //--- 22.08.01 15:48:15 ----------------------------------------------- 151 152 void OComponentEventThread::implStarted( ) 153 { 154 acquire( ); 155 } 156 157 //--------------------------------------------------------------------- 158 //--- 22.08.01 15:48:16 ----------------------------------------------- 159 160 void OComponentEventThread::implTerminated( ) 161 { 162 release( ); 163 } 164 165 //--------------------------------------------------------------------- 166 //--- 22.08.01 15:47:31 ----------------------------------------------- 167 168 void SAL_CALL OComponentEventThread::kill() 169 { 170 OComponentEventThread_TBASE::kill(); 171 172 implTerminated( ); 173 } 174 175 //--------------------------------------------------------------------- 176 //--- 22.08.01 15:47:33 ----------------------------------------------- 177 178 void SAL_CALL OComponentEventThread::onTerminated() 179 { 180 OComponentEventThread_TBASE::onTerminated(); 181 182 implTerminated( ); 183 } 184 185 void OComponentEventThread::run() 186 { 187 implStarted( ); 188 189 // uns selbst festhalten, damit wir nicht geloescht werden, 190 // wenn zwischendrinne mal ein dispose gerufen wird. 191 InterfaceRef xThis(static_cast<XWeak*>(this)); 192 193 do 194 { 195 ::osl::MutexGuard aGuard(m_aMutex); 196 197 while( m_aEvents.size() > 0 ) 198 { 199 // Das Control holen und festhalten, damit es waehrend des 200 // actionPerformed nicht geloescht werden kann. 201 Reference<XComponent> xComp = m_xComp; 202 ::cppu::OComponentHelper *pCompImpl = m_pCompImpl; 203 204 ThreadEvents::iterator firstEvent( m_aEvents.begin() ); 205 EventObject* pEvt = *firstEvent; 206 m_aEvents.erase( firstEvent ); 207 208 ThreadObjects::iterator firstControl( m_aControls.begin() ); 209 Reference<XAdapter> xControlAdapter = *firstControl; 210 m_aControls.erase( firstControl ); 211 212 ThreadBools::iterator firstFlag( m_aFlags.begin() ); 213 sal_Bool bFlag = *firstFlag; 214 m_aFlags.erase( firstFlag ); 215 216 { 217 MutexRelease aReleaseOnce(m_aMutex); 218 // Weil ein queryHardRef eine Exception schmeissen kann sollte 219 // es nicht bei gelocktem Mutex aufgerufen werden. 220 Reference<XControl> xControl; 221 if ( xControlAdapter.is() ) 222 query_interface(xControlAdapter->queryAdapted(), xControl); 223 224 if( xComp.is() ) 225 processEvent( pCompImpl, pEvt, xControl, bFlag ); 226 } 227 228 delete pEvt; 229 }; 230 231 // Nach einem dispose kennen wir das Control nicht mehr. Dann darf 232 // auch nicht gewartet werden. 233 if( !m_xComp.is() ) 234 return; 235 236 // Warte-Bedingung zuruecksetzen 237 m_aCond.reset(); 238 { 239 MutexRelease aReleaseOnce(m_aMutex); 240 // und warten ... falls nicht zwischenzeitlich doch noch ein 241 // Event eingetroffen ist. 242 m_aCond.wait(); 243 } 244 } 245 while( sal_True ); 246 } 247 248 //......................................................................... 249 } // namespace frm 250 //......................................................................... 251 252