]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/event.h
fixed memory leak in wxXmlResource introduced when fixing wxVector<> usage (patch...
[wxWidgets.git] / include / wx / event.h
index 5e5c4177a23c7f3173833bc03c3b157ddffb65ff..3e5bc79873e99f20c7c1dac7a5f6d92372b64e61 100644 (file)
@@ -9,8 +9,8 @@
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
-#ifndef _WX_EVENT_H__
-#define _WX_EVENT_H__
+#ifndef _WX_EVENT_H_
+#define _WX_EVENT_H_
 
 #include "wx/defs.h"
 #include "wx/cpp.h"
     #include "wx/cursor.h"
 #endif
 
-#include "wx/thread.h"
-
 #include "wx/dynarray.h"
+#include "wx/thread.h"
+#include "wx/tracker.h"
 
 // ----------------------------------------------------------------------------
 // forward declarations
 // ----------------------------------------------------------------------------
 
 class WXDLLIMPEXP_FWD_BASE wxList;
-
 #if wxUSE_GUI
     class WXDLLIMPEXP_FWD_CORE wxDC;
     class WXDLLIMPEXP_FWD_CORE wxMenu;
@@ -53,47 +52,6 @@ typedef int wxEventType;
 // handler only a function with proper parameter list can be given.
 #define wxStaticCastEvent(type, val) wx_static_cast(type, val)
 
-// in previous versions of wxWidgets the event types used to be constants
-// which created difficulties with custom/user event types definition
-//
-// starting from wxWidgets 2.4 the event types are now dynamically assigned
-// using wxNewEventType() which solves this problem, however at price of
-// several incompatibilities:
-//
-//  a) event table macros declaration changed, it now uses wxEventTableEntry
-//     ctor instead of initialisation from an agregate - the macro
-//     DECLARE_EVENT_TABLE_ENTRY may be used to write code which can compile
-//     with all versions of wxWidgets
-//
-//  b) event types can't be used as switch() cases as they're not really
-//     constant any more - there is no magic solution here, you just have to
-//     change the switch()es to if()s
-//
-// if these are real problems for you, define WXWIN_COMPATIBILITY_EVENT_TYPES
-// as 1 to get 100% old behaviour, however you won't be able to use the
-// libraries using the new dynamic event type allocation in such case, so avoid
-// it if possible.
-#ifndef WXWIN_COMPATIBILITY_EVENT_TYPES
-    #define WXWIN_COMPATIBILITY_EVENT_TYPES 0
-#endif
-
-#if WXWIN_COMPATIBILITY_EVENT_TYPES
-
-#define DECLARE_EVENT_TABLE_ENTRY(type, winid, idLast, fn, obj) \
-    { type, winid, idLast, fn, obj }
-
-#define BEGIN_DECLARE_EVENT_TYPES() enum {
-#define END_DECLARE_EVENT_TYPES() };
-#define DECLARE_EVENT_TYPE(name, value) name = wxEVT_FIRST + value,
-#define DECLARE_LOCAL_EVENT_TYPE(name, value) name = wxEVT_USER_FIRST + value,
-#define DECLARE_EXPORTED_EVENT_TYPE(expdecl, name, value) \
-    DECLARE_LOCAL_EVENT_TYPE(name, value)
-#define DEFINE_EVENT_TYPE(name)
-#define DEFINE_LOCAL_EVENT_TYPE(name)
-
-
-#else // !WXWIN_COMPATIBILITY_EVENT_TYPES
-
 #define DECLARE_EVENT_TABLE_ENTRY(type, winid, idLast, fn, obj) \
     wxEventTableEntry(type, winid, idLast, fn, obj)
 
@@ -111,21 +69,12 @@ typedef int wxEventType;
 // generate a new unique event type
 extern WXDLLIMPEXP_BASE wxEventType wxNewEventType();
 
-#endif // WXWIN_COMPATIBILITY_EVENT_TYPES/!WXWIN_COMPATIBILITY_EVENT_TYPES
-
 BEGIN_DECLARE_EVENT_TYPES()
-
-#if WXWIN_COMPATIBILITY_EVENT_TYPES
-    wxEVT_NULL = 0,
-    wxEVT_FIRST = 10000,
-    wxEVT_USER_FIRST = wxEVT_FIRST + 2000,
-#else // !WXWIN_COMPATIBILITY_EVENT_TYPES
     // it is important to still have these as constants to avoid
     // initialization order related problems
     DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_BASE, wxEVT_NULL, 0)
     DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_BASE, wxEVT_FIRST, 10000)
     DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_BASE, wxEVT_USER_FIRST, wxEVT_FIRST + 2000)
-#endif // WXWIN_COMPATIBILITY_EVENT_TYPES/!WXWIN_COMPATIBILITY_EVENT_TYPES
 
     DECLARE_EVENT_TYPE(wxEVT_COMMAND_BUTTON_CLICKED, 1)
     DECLARE_EVENT_TYPE(wxEVT_COMMAND_CHECKBOX_CLICKED, 2)
@@ -133,13 +82,6 @@ BEGIN_DECLARE_EVENT_TYPES()
     DECLARE_EVENT_TYPE(wxEVT_COMMAND_LISTBOX_SELECTED, 4)
     DECLARE_EVENT_TYPE(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, 5)
     DECLARE_EVENT_TYPE(wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, 6)
-    // now they are in wx/textctrl.h
-#if WXWIN_COMPATIBILITY_EVENT_TYPES
-    DECLARE_EVENT_TYPE(wxEVT_COMMAND_TEXT_UPDATED, 7)
-    DECLARE_EVENT_TYPE(wxEVT_COMMAND_TEXT_ENTER, 8)
-    DECLARE_EVENT_TYPE(wxEVT_COMMAND_TEXT_URL, 13)
-    DECLARE_EVENT_TYPE(wxEVT_COMMAND_TEXT_MAXLEN, 14)
-#endif // WXWIN_COMPATIBILITY_EVENT_TYPES
     DECLARE_EVENT_TYPE(wxEVT_COMMAND_MENU_SELECTED, 9)
     DECLARE_EVENT_TYPE(wxEVT_COMMAND_SLIDER_UPDATED, 10)
     DECLARE_EVENT_TYPE(wxEVT_COMMAND_RADIOBOX_SELECTED, 11)
@@ -312,9 +254,7 @@ END_DECLARE_EVENT_TYPES()
 // wx/textctrl.h in all ports [yet], so declare it here as well
 //
 // still, any new code using it should include wx/textctrl.h explicitly
-#if !WXWIN_COMPATIBILITY_EVENT_TYPES
-    extern const wxEventType WXDLLIMPEXP_CORE wxEVT_COMMAND_TEXT_UPDATED;
-#endif
+extern const wxEventType WXDLLIMPEXP_CORE wxEVT_COMMAND_TEXT_UPDATED;
 
 // the predefined constants for the number of times we propagate event
 // upwards window child-parent chain
@@ -838,7 +778,7 @@ public:
 
     virtual wxEvent *Clone() const { return new wxMouseEvent(*this); }
 
-    wxMouseEvent& operator=(const wxMouseEvent& event) { Assign(event); return *this; }
+    wxMouseEvent& operator=(const wxMouseEvent& event) { if (&event != this) Assign(event); return *this; }
 
 public:
     wxCoord m_x, m_y;
@@ -994,33 +934,30 @@ public:
     // Get Y position
     wxCoord GetY() const { return m_y; }
 
-#if WXWIN_COMPATIBILITY_2_6
-    // deprecated, Use GetKeyCode instead.
-    wxDEPRECATED( long KeyCode() const );
-#endif // WXWIN_COMPATIBILITY_2_6
-
     virtual wxEvent *Clone() const { return new wxKeyEvent(*this); }
 
     // we do need to copy wxKeyEvent sometimes (in wxTreeCtrl code, for
     // example)
     wxKeyEvent& operator=(const wxKeyEvent& evt)
     {
-        m_x = evt.m_x;
-        m_y = evt.m_y;
-
-        m_keyCode = evt.m_keyCode;
-
-        m_controlDown = evt.m_controlDown;
-        m_shiftDown = evt.m_shiftDown;
-        m_altDown = evt.m_altDown;
-        m_metaDown = evt.m_metaDown;
-        m_scanCode = evt.m_scanCode;
-        m_rawCode = evt.m_rawCode;
-        m_rawFlags = evt.m_rawFlags;
+        if (&evt != this)
+        {
+            m_x = evt.m_x;
+            m_y = evt.m_y;
+
+            m_keyCode = evt.m_keyCode;
+
+            m_controlDown = evt.m_controlDown;
+            m_shiftDown = evt.m_shiftDown;
+            m_altDown = evt.m_altDown;
+            m_metaDown = evt.m_metaDown;
+            m_scanCode = evt.m_scanCode;
+            m_rawCode = evt.m_rawCode;
+            m_rawFlags = evt.m_rawFlags;
 #if wxUSE_UNICODE
-        m_uniChar = evt.m_uniChar;
+            m_uniChar = evt.m_uniChar;
 #endif
-
+        }
         return *this;
     }
 
@@ -2169,25 +2106,6 @@ private:
 // as a wxObject method even though it can only be a wxEvtHandler one
 typedef void (wxObject::*wxObjectEventFunction)(wxEvent&);
 
-// we can't have ctors nor base struct in backwards compatibility mode or
-// otherwise we won't be able to initialize the objects with an agregate, so
-// we have to keep both versions
-#if WXWIN_COMPATIBILITY_EVENT_TYPES
-
-struct WXDLLIMPEXP_BASE wxEventTableEntry
-{
-    // For some reason, this can't be wxEventType, or VC++ complains.
-    int m_eventType;            // main event type
-    int m_id;                   // control/menu/toolbar id
-    int m_lastId;               // used for ranges of ids
-    wxObjectEventFunction m_fn; // function to call: not wxEventFunction,
-                                // because of dependency problems
-
-    wxObject* m_callbackUserData;
-};
-
-#else // !WXWIN_COMPATIBILITY_EVENT_TYPES
-
 // struct containing the members common to static and dynamic event tables
 // entries
 struct WXDLLIMPEXP_BASE wxEventTableEntryBase
@@ -2267,8 +2185,6 @@ struct WXDLLIMPEXP_BASE wxDynamicEventTableEntry : public wxEventTableEntryBase
     DECLARE_NO_COPY_CLASS(wxDynamicEventTableEntry)
 };
 
-#endif // !WXWIN_COMPATIBILITY_EVENT_TYPES
-
 // ----------------------------------------------------------------------------
 // wxEventTable: an array of event entries terminated with {0, 0, 0, 0, 0}
 // ----------------------------------------------------------------------------
@@ -2342,11 +2258,44 @@ protected:
     DECLARE_NO_COPY_CLASS(wxEventHashTable)
 };
 
+// ----------------------------------------------------------------------------
+// wxEventConnectionRef: A class that represents all connections between two event 
+// handlers and enables automatic disconnect when an event handler sink goes 
+// out of scope. Each connection/disconnect increases/decreases ref count, and
+// when zero the node goes out of scope. 
+// ----------------------------------------------------------------------------
+
+struct wxEventConnectionRef : public wxTrackerNode {
+
+    wxEventConnectionRef() : m_src(0), m_sink(0), m_refCount(0) { }
+    wxEventConnectionRef( wxEvtHandler *src, wxEvtHandler *sink );
+    virtual ~wxEventConnectionRef();
+        
+    // The sink is being destroyed 
+    virtual void OnObjectDestroy( );
+    virtual wxTrackerNodeType GetType( ){ return EventConnectionRef; } 
+    
+    void IncRef( ) { m_refCount++; }
+    void DecRef( );
+
+protected:   
+    wxEvtHandler *m_src, *m_sink;
+    int m_refCount;
+    
+    friend class wxEvtHandler;
+    
+private:
+    // It makes no sense to copy objects of this class 
+    wxEventConnectionRef& operator = (const wxEventConnectionRef& WXUNUSED(other)) { wxFAIL; return *this; } 
+};
+
+
+
 // ----------------------------------------------------------------------------
 // wxEvtHandler: the base class for all objects handling wxWidgets events
 // ----------------------------------------------------------------------------
 
-class WXDLLIMPEXP_BASE wxEvtHandler : public wxObject
+class WXDLLIMPEXP_BASE wxEvtHandler : public wxObject, public wxTrackableBase
 {
 public:
     wxEvtHandler();
@@ -2444,12 +2393,9 @@ public:
     virtual bool SearchEventTable(wxEventTable& table, wxEvent& event);
     bool SearchDynamicEventTable( wxEvent& event );
 
-#if wxUSE_THREADS
-    void ClearEventLocker();
-#endif // wxUSE_THREADS
-
     // Avoid problems at exit by cleaning up static hash table gracefully
     void ClearEventHashTable() { GetEventHashTable().Clear(); }
+    void OnSinkDestroyed( wxEvtHandler *sink );
 
 private:
     static const wxEventTableEntry sm_eventTableEntries[];
@@ -2487,18 +2433,9 @@ protected:
     wxList*             m_pendingEvents;
 
 #if wxUSE_THREADS
-#if defined (__VISAGECPP__)
-    const wxCriticalSection& Lock() const { return m_eventsLocker; }
-    wxCriticalSection& Lock() { return m_eventsLocker; }
-
-    wxCriticalSection   m_eventsLocker;
-#  else
-    const wxCriticalSection& Lock() const { return *m_eventsLocker; }
-    wxCriticalSection& Lock() { return *m_eventsLocker; }
-
-    wxCriticalSection*  m_eventsLocker;
-#  endif
-#endif
+    // critical section protecting m_pendingEvents
+    wxCriticalSection m_pendingEventsLock;
+#endif // wxUSE_THREADS
 
     // Is event handler enabled?
     bool                m_enabled;
@@ -2525,6 +2462,9 @@ protected:
     virtual void DoSetClientData( void *data );
     virtual void *DoGetClientData() const;
 
+    // Search tracker objects for event connection with this sink
+    wxEventConnectionRef *FindRefInTrackerList( wxEvtHandler *eventSink );
+
 private:
     DECLARE_DYNAMIC_CLASS_NO_COPY(wxEvtHandler)
 };
@@ -3093,8 +3033,9 @@ typedef void (wxEvtHandler::*wxClipboardTextEventFunction)(wxClipboardTextEvent&
 // Global data
 // ----------------------------------------------------------------------------
 
-// for pending event processing - notice that there is intentionally no
-// WXDLLEXPORT here
+// list containing event handlers with pending events for them
+//
+// notice that each event handler should occur at most once in this list
 extern WXDLLIMPEXP_BASE wxList *wxPendingEvents;
 #if wxUSE_THREADS
     extern WXDLLIMPEXP_BASE wxCriticalSection *wxPendingEventsLocker;
@@ -3112,4 +3053,4 @@ WXDLLIMPEXP_CORE wxWindow* wxFindFocusDescendant(wxWindow* ancestor);
 
 #endif // wxUSE_GUI
 
-#endif // _WX_EVENT_H__
+#endif // _WX_EVENT_H_