#include "wx/thread.h"
+#if wxUSE_BASE
+ #include "wx/ptr_scpd.h"
+
+ wxDECLARE_SCOPED_PTR(wxEvent, wxEventPtr)
+ wxDEFINE_SCOPED_PTR(wxEvent, wxEventPtr)
+#endif // wxUSE_BASE
+
// ----------------------------------------------------------------------------
// wxWin macros
// ----------------------------------------------------------------------------
DEFINE_EVENT_TYPE(wxEVT_COMMAND_TOOL_RCLICKED)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_TOOL_ENTER)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_SPINCTRL_UPDATED)
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_SPINCTRLDOUBLE_UPDATED)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_TOOL_DROPDOWN_CLICKED)
// Mouse event types
wxString wxCommandEvent::GetString() const
{
- if(m_eventType != wxEVT_COMMAND_TEXT_UPDATED || !m_eventObject)
+ if (m_eventType != wxEVT_COMMAND_TEXT_UPDATED || !m_eventObject)
+ {
return m_cmdString;
+ }
else
{
#if wxUSE_TEXTCTRL
wxTextCtrl *txt = wxDynamicCast(m_eventObject, wxTextCtrl);
- if(txt)
+ if ( txt )
return txt->GetValue();
else
#endif // wxUSE_TEXTCTRL
delete[] oldEventTypeTable;
}
-
-// ----------------------------------------------------------------------------
-// wxEventConnectionRef
-// ----------------------------------------------------------------------------
-
-// Below functions are mostly short but kept in cpp file to simplify setting
-// breakpoints (GDB)
-wxEventConnectionRef::wxEventConnectionRef(wxEvtHandler *src, wxEvtHandler *sink)
- : m_src(src), m_sink(sink), m_refCount(1)
-{
- wxASSERT( m_sink );
- m_sink->AddNode( this );
-}
-
-wxEventConnectionRef::~wxEventConnectionRef()
-{
-}
-
-void wxEventConnectionRef::OnObjectDestroy( )
-{
- if( m_src )
- m_src->OnSinkDestroyed( m_sink );
- // It is safe to delete this tracker object here
- delete this;
-}
-
-void wxEventConnectionRef::DecRef( )
-{
- if( !--m_refCount )
- {
- // The sink holds the only external pointer to this object
- if( m_sink )
- m_sink->RemoveNode(this);
- delete this;
- }
-}
-
-
// ----------------------------------------------------------------------------
// wxEvtHandler
// ----------------------------------------------------------------------------
{
wxDynamicEventTableEntry *entry = (wxDynamicEventTableEntry*)*it;
- // Remove ourselves from sink destructor notifications
+ // Remove ourselves from sink destructor notifications
// (this has usually been been done, in wxTrackable destructor)
wxEvtHandler *eventSink = entry->m_eventSink;
- if( eventSink )
+ if ( eventSink )
{
- wxEventConnectionRef *pecr = FindRefInTrackerList( eventSink );
- if( pecr )
- {
- eventSink->RemoveNode( pecr );
- delete pecr;
- }
+ wxEventConnectionRef * const
+ evtConnRef = FindRefInTrackerList(eventSink);
+ if ( evtConnRef )
+ {
+ eventSink->RemoveNode(evtConnRef);
+ delete evtConnRef;
+ }
}
-
+
if (entry->m_callbackUserData)
delete entry->m_callbackUserData;
delete entry;
if ( wxPendingEvents )
{
#if wxUSE_THREADS
- if(wxPendingEventsLocker)
+ if (wxPendingEventsLocker)
wxENTER_CRIT_SECT(*wxPendingEventsLocker);
#endif
//else: we weren't in this list at all, it's ok
#if wxUSE_THREADS
- if(wxPendingEventsLocker)
+ if (wxPendingEventsLocker)
wxLEAVE_CRIT_SECT(*wxPendingEventsLocker);
#endif
}
#endif // wxUSE_THREADS
-void wxEvtHandler::AddPendingEvent(const wxEvent& event)
+void wxEvtHandler::QueueEvent(wxEvent *event)
{
- // 1) Add event to list of pending events of this event handler
-
- wxEvent *eventCopy = event.Clone();
-
- // we must be able to copy the events here so the event class must
- // implement Clone() properly instead of just providing a NULL stab for it
- wxCHECK_RET( eventCopy,
- _T("events of this type aren't supposed to be posted") );
+ wxCHECK_RET( event, "NULL event can't be posted" );
+ // 1) Add this event to our list of pending events
wxENTER_CRIT_SECT( m_pendingEventsLock );
if ( !m_pendingEvents )
m_pendingEvents = new wxList;
- m_pendingEvents->Append(eventCopy);
+ m_pendingEvents->Append(event);
wxLEAVE_CRIT_SECT( m_pendingEventsLock );
"should have pending events if called" );
wxList::compatibility_iterator node = m_pendingEvents->GetFirst();
- wxEvent * const event = wx_static_cast(wxEvent *, node->GetData());
+ wxEventPtr event(wx_static_cast(wxEvent *, node->GetData()));
// it's important we remove event from list before processing it, else a
// nested event loop, for example from a modal dialog, might process the
// if there are no more pending events left, we don't need to stay in this
// list
if ( m_pendingEvents->IsEmpty() )
+ {
+#if wxUSE_THREADS
+ if (wxPendingEventsLocker)
+ wxENTER_CRIT_SECT(*wxPendingEventsLocker);
+#endif
wxPendingEvents->DeleteObject(this);
+#if wxUSE_THREADS
+ if (wxPendingEventsLocker)
+ wxLEAVE_CRIT_SECT(*wxPendingEventsLocker);
+#endif
+ }
wxLEAVE_CRIT_SECT( m_pendingEventsLock );
// careful: this object could have been deleted by the event handler
// executed by the above ProcessEvent() call, so we can't access any fields
// of this object any more
-
- delete event;
}
/*
// Insert at the front of the list so most recent additions are found first
m_dynamicEvents->Insert( (wxObject*) entry );
-
- // Make sure we get to know when a sink is destroyed
- if( eventSink )
+
+ // Make sure we get to know when a sink is destroyed
+ if ( eventSink && eventSink != this )
{
- wxEventConnectionRef *pecr = FindRefInTrackerList( eventSink );
- if( pecr )
- pecr->IncRef( );
+ wxEventConnectionRef *evtConnRef = FindRefInTrackerList(eventSink);
+ if ( evtConnRef )
+ evtConnRef->IncRef( );
else
- pecr = new wxEventConnectionRef(this,eventSink);
+ evtConnRef = new wxEventConnectionRef(this, eventSink);
}
}
return false;
// Remove connection from tracker node (wxEventConnectionRef)
- if( eventSink )
+ if ( eventSink && eventSink != this )
{
- wxEventConnectionRef *pecr = FindRefInTrackerList( eventSink );
- if( pecr )
- pecr->DecRef( );
+ wxEventConnectionRef *evtConnRef = FindRefInTrackerList(eventSink);
+ if ( evtConnRef )
+ evtConnRef->DecRef();
}
wxList::compatibility_iterator node = m_dynamicEvents->GetFirst();
return m_clientData;
}
-// A helper func to find an wxEventConnectionRef object
-wxEventConnectionRef* wxEvtHandler::FindRefInTrackerList( wxEvtHandler *eventSink )
+// A helper to find an wxEventConnectionRef object
+wxEventConnectionRef *
+wxEvtHandler::FindRefInTrackerList(wxEvtHandler *eventSink)
{
- wxASSERT(eventSink);
- for( wxTrackerNode *ptn=eventSink->GetFirst(); ptn; ptn=ptn->m_nxt )
+ for ( wxTrackerNode *node = eventSink->GetFirst(); node; node = node->m_nxt )
{
- // Only want wxEventConnectionRef nodes here
- if( ptn->GetType()!=wxTrackerNode::EventConnectionRef )
- continue;
- wxEventConnectionRef *pecr = static_cast<wxEventConnectionRef*>(ptn);
- if( pecr && pecr->m_src==this )
+ // we only want wxEventConnectionRef nodes here
+ wxEventConnectionRef *evtConnRef = node->ToEventConnection();
+ if ( evtConnRef && evtConnRef->m_src == this )
{
- wxASSERT( pecr->m_sink==eventSink );
- return pecr;
+ wxASSERT( evtConnRef->m_sink==eventSink );
+ return evtConnRef;
}
}
+
return NULL;
}
void wxEvtHandler::OnSinkDestroyed( wxEvtHandler *sink )
{
wxASSERT(m_dynamicEvents);
-
+
// remove all connections with this sink
wxList::compatibility_iterator node = m_dynamicEvents->GetFirst(), node_nxt;
while (node)
{
wxDynamicEventTableEntry *entry = (wxDynamicEventTableEntry*)node->GetData();
node_nxt = node->GetNext();
-
- if( entry->m_eventSink==sink )
+
+ if ( entry->m_eventSink==sink )
{
if (entry->m_callbackUserData)
delete entry->m_callbackUserData;