| /************************************************************** | |
| * | |
| * 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_forms.hxx" | |
| #include "EventThread.hxx" | |
| #include <comphelper/guarding.hxx> | |
| #include <tools/debug.hxx> | |
| //......................................................................... | |
| namespace frm | |
| { | |
| //......................................................................... | |
| using namespace ::com::sun::star::uno; | |
| using namespace ::com::sun::star::awt; | |
| using namespace ::com::sun::star::lang; | |
| DBG_NAME( OComponentEventThread ) | |
| OComponentEventThread::OComponentEventThread( ::cppu::OComponentHelper* pCompImpl ) : | |
| m_pCompImpl( pCompImpl ) | |
| { | |
| DBG_CTOR( OComponentEventThread, NULL ); | |
| increment(m_refCount); | |
| // Eine Referenz des Controls halten | |
| { | |
| InterfaceRef xIFace(static_cast<XWeak*>(pCompImpl)); | |
| query_interface(xIFace, m_xComp); | |
| } | |
| // und uns an dem Control anmelden | |
| { | |
| Reference<XEventListener> xEvtLstnr = static_cast<XEventListener*>(this); | |
| m_xComp->addEventListener( xEvtLstnr ); | |
| } | |
| decrement(m_refCount); | |
| } | |
| OComponentEventThread::~OComponentEventThread() | |
| { | |
| DBG_DTOR( OComponentEventThread, NULL ); | |
| DBG_ASSERT( m_aEvents.size() == 0, | |
| "OComponentEventThread::~OComponentEventThread: Kein dispose gerufen?" ); | |
| impl_clearEventQueue(); | |
| } | |
| Any SAL_CALL OComponentEventThread::queryInterface(const Type& _rType) throw (RuntimeException) | |
| { | |
| Any aReturn; | |
| aReturn = OWeakObject::queryInterface(_rType); | |
| if (!aReturn.hasValue()) | |
| aReturn = ::cppu::queryInterface(_rType, | |
| static_cast<XEventListener*>(this) | |
| ); | |
| return aReturn; | |
| } | |
| void OComponentEventThread::impl_clearEventQueue() | |
| { | |
| while ( m_aEvents.size() ) | |
| { | |
| delete *m_aEvents.begin(); | |
| m_aEvents.erase( m_aEvents.begin() ); | |
| } | |
| m_aControls.erase( m_aControls.begin(), m_aControls.end() ); | |
| m_aFlags.erase( m_aFlags.begin(), m_aFlags.end() ); | |
| } | |
| void OComponentEventThread::disposing( const EventObject& evt ) throw ( ::com::sun::star::uno::RuntimeException) | |
| { | |
| if( evt.Source == m_xComp ) | |
| { | |
| ::osl::MutexGuard aGuard( m_aMutex ); | |
| // Event-Listener abmelden | |
| Reference<XEventListener> xEvtLstnr = static_cast<XEventListener*>(this); | |
| m_xComp->removeEventListener( xEvtLstnr ); | |
| // Event-Queue loeschen | |
| impl_clearEventQueue(); | |
| // Das Control loslassen und pCompImpl auf 0 setzen, damit der | |
| // Thread weiss, dass er sich beenden soll. | |
| m_xComp = 0; | |
| m_pCompImpl = 0; | |
| // Den Thread aufwecken und beenden. | |
| m_aCond.set(); | |
| terminate(); | |
| } | |
| } | |
| void OComponentEventThread::addEvent( const EventObject* _pEvt, sal_Bool bFlag ) | |
| { | |
| Reference<XControl> xTmp; | |
| addEvent( _pEvt, xTmp, bFlag ); | |
| } | |
| void OComponentEventThread::addEvent( const EventObject* _pEvt, | |
| const Reference<XControl>& rControl, | |
| sal_Bool bFlag ) | |
| { | |
| ::osl::MutexGuard aGuard( m_aMutex ); | |
| // Daten in die Queue stellen | |
| m_aEvents.push_back( cloneEvent( _pEvt ) ); | |
| Reference<XWeak> xWeakControl(rControl, UNO_QUERY); | |
| Reference<XAdapter> xControlAdapter = xWeakControl.is() ? xWeakControl->queryAdapter() : Reference<XAdapter>(); | |
| m_aControls.push_back( xControlAdapter ); | |
| m_aFlags.push_back( bFlag ); | |
| // Thread aufwecken | |
| m_aCond.set(); | |
| } | |
| //--------------------------------------------------------------------- | |
| //--- 22.08.01 15:48:15 ----------------------------------------------- | |
| void OComponentEventThread::implStarted( ) | |
| { | |
| acquire( ); | |
| } | |
| //--------------------------------------------------------------------- | |
| //--- 22.08.01 15:48:16 ----------------------------------------------- | |
| void OComponentEventThread::implTerminated( ) | |
| { | |
| release( ); | |
| } | |
| //--------------------------------------------------------------------- | |
| //--- 22.08.01 15:47:31 ----------------------------------------------- | |
| void SAL_CALL OComponentEventThread::kill() | |
| { | |
| OComponentEventThread_TBASE::kill(); | |
| implTerminated( ); | |
| } | |
| //--------------------------------------------------------------------- | |
| //--- 22.08.01 15:47:33 ----------------------------------------------- | |
| void SAL_CALL OComponentEventThread::onTerminated() | |
| { | |
| OComponentEventThread_TBASE::onTerminated(); | |
| implTerminated( ); | |
| } | |
| void OComponentEventThread::run() | |
| { | |
| implStarted( ); | |
| // uns selbst festhalten, damit wir nicht geloescht werden, | |
| // wenn zwischendrinne mal ein dispose gerufen wird. | |
| InterfaceRef xThis(static_cast<XWeak*>(this)); | |
| do | |
| { | |
| ::osl::MutexGuard aGuard(m_aMutex); | |
| while( m_aEvents.size() > 0 ) | |
| { | |
| // Das Control holen und festhalten, damit es waehrend des | |
| // actionPerformed nicht geloescht werden kann. | |
| Reference<XComponent> xComp = m_xComp; | |
| ::cppu::OComponentHelper *pCompImpl = m_pCompImpl; | |
| ThreadEvents::iterator firstEvent( m_aEvents.begin() ); | |
| EventObject* pEvt = *firstEvent; | |
| m_aEvents.erase( firstEvent ); | |
| ThreadObjects::iterator firstControl( m_aControls.begin() ); | |
| Reference<XAdapter> xControlAdapter = *firstControl; | |
| m_aControls.erase( firstControl ); | |
| ThreadBools::iterator firstFlag( m_aFlags.begin() ); | |
| sal_Bool bFlag = *firstFlag; | |
| m_aFlags.erase( firstFlag ); | |
| { | |
| MutexRelease aReleaseOnce(m_aMutex); | |
| // Weil ein queryHardRef eine Exception schmeissen kann sollte | |
| // es nicht bei gelocktem Mutex aufgerufen werden. | |
| Reference<XControl> xControl; | |
| if ( xControlAdapter.is() ) | |
| query_interface(xControlAdapter->queryAdapted(), xControl); | |
| if( xComp.is() ) | |
| processEvent( pCompImpl, pEvt, xControl, bFlag ); | |
| } | |
| delete pEvt; | |
| }; | |
| // Nach einem dispose kennen wir das Control nicht mehr. Dann darf | |
| // auch nicht gewartet werden. | |
| if( !m_xComp.is() ) | |
| return; | |
| // Warte-Bedingung zuruecksetzen | |
| m_aCond.reset(); | |
| { | |
| MutexRelease aReleaseOnce(m_aMutex); | |
| // und warten ... falls nicht zwischenzeitlich doch noch ein | |
| // Event eingetroffen ist. | |
| m_aCond.wait(); | |
| } | |
| } | |
| while( sal_True ); | |
| } | |
| //......................................................................... | |
| } // namespace frm | |
| //......................................................................... | |