summaryrefslogtreecommitdiff
path: root/forms/source/component/EventThread.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'forms/source/component/EventThread.cxx')
-rw-r--r--forms/source/component/EventThread.cxx254
1 files changed, 254 insertions, 0 deletions
diff --git a/forms/source/component/EventThread.cxx b/forms/source/component/EventThread.cxx
new file mode 100644
index 000000000000..ef60cb5462b3
--- /dev/null
+++ b/forms/source/component/EventThread.cxx
@@ -0,0 +1,254 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: EventThread.cxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 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
+//.........................................................................
+