]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/event.cpp
added wxMemoryInputStream(wxInputStream&, size_t) ctor (modified patch 1680108)
[wxWidgets.git] / src / common / event.cpp
index ec31583f0d0caaf600a64b0a9b1fa56db211866e..abde457635ea0ea08180470b94f66dfba64ee834 100644 (file)
@@ -1,5 +1,5 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        event.cpp
+// Name:        src/common/event.cpp
 // Purpose:     Event classes
 // Author:      Julian Smart
 // Modified by:
     #pragma hdrstop
 #endif
 
+#include "wx/event.h"
+
 #ifndef WX_PRECOMP
-    #include "wx/defs.h"
-    #include "wx/app.h"
     #include "wx/list.h"
+    #include "wx/app.h"
+    #include "wx/utils.h"
+    #include "wx/stopwatch.h"
+    #include "wx/module.h"
 
     #if wxUSE_GUI
         #include "wx/control.h"
-        #include "wx/utils.h"
         #include "wx/dc.h"
         #include "wx/textctrl.h"
+        #include "wx/validate.h"
     #endif // wxUSE_GUI
 #endif
 
-#include "wx/event.h"
-#include "wx/module.h"
-
-#if wxUSE_GUI
-    #include "wx/validate.h"
-#if wxUSE_STOPWATCH
-    #include "wx/stopwatch.h"
-#endif
-#endif // wxUSE_GUI
-
 // ----------------------------------------------------------------------------
 // wxWin macros
 // ----------------------------------------------------------------------------
@@ -92,6 +86,8 @@
     IMPLEMENT_DYNAMIC_CLASS(wxHelpEvent, wxCommandEvent)
     IMPLEMENT_DYNAMIC_CLASS(wxContextMenuEvent, wxCommandEvent)
     IMPLEMENT_DYNAMIC_CLASS(wxMouseCaptureChangedEvent, wxEvent)
+    IMPLEMENT_DYNAMIC_CLASS(wxMouseCaptureLostEvent, wxEvent)
+    IMPLEMENT_DYNAMIC_CLASS(wxClipboardTextEvent, wxCommandEvent)
 #endif // wxUSE_GUI
 
 #if wxUSE_BASE
@@ -264,6 +260,7 @@ DEFINE_EVENT_TYPE(wxEVT_SHOW)
 DEFINE_EVENT_TYPE(wxEVT_ICONIZE)
 DEFINE_EVENT_TYPE(wxEVT_MAXIMIZE)
 DEFINE_EVENT_TYPE(wxEVT_MOUSE_CAPTURE_CHANGED)
+DEFINE_EVENT_TYPE(wxEVT_MOUSE_CAPTURE_LOST)
 DEFINE_EVENT_TYPE(wxEVT_PAINT)
 DEFINE_EVENT_TYPE(wxEVT_ERASE_BACKGROUND)
 DEFINE_EVENT_TYPE(wxEVT_NC_PAINT)
@@ -288,6 +285,11 @@ DEFINE_EVENT_TYPE(wxEVT_COMPARE_ITEM)
 DEFINE_EVENT_TYPE(wxEVT_INIT_DIALOG)
 DEFINE_EVENT_TYPE(wxEVT_UPDATE_UI)
 
+// Clipboard events
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_COPY)
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_CUT)
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_PASTE)
+
 // Generic command events
 // Note: a click is a higher-level event than button down/up
 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LEFT_CLICK)
@@ -350,7 +352,7 @@ wxEvent::wxEvent(int theId, wxEventType commandType )
 }
 
 wxEvent::wxEvent(const wxEvent &src)
-    : wxObject()
+    : wxObject(src)
     , m_eventObject(src.m_eventObject)
     , m_eventType(src.m_eventType)
     , m_timeStamp(src.m_timeStamp)
@@ -378,9 +380,6 @@ wxEvent::wxEvent(const wxEvent &src)
 
 wxCommandEvent::wxCommandEvent(wxEventType commandType, int theId)
               : wxEvent(theId, commandType)
-#if WXWIN_COMPATIBILITY_2_4
-              , m_commandString(this)
-#endif
 {
     m_clientData = (char *) NULL;
     m_clientObject = (wxClientData *) NULL;
@@ -537,6 +536,7 @@ wxMouseEvent::wxMouseEvent(wxEventType commandType)
     m_wheelRotation = 0;
     m_wheelDelta = 0;
     m_linesPerAction = 0;
+    m_wheelAxis = 0;
 }
 
 void wxMouseEvent::Assign(const wxMouseEvent& event)
@@ -558,6 +558,7 @@ void wxMouseEvent::Assign(const wxMouseEvent& event)
     m_wheelRotation = event.m_wheelRotation;
     m_wheelDelta = event.m_wheelDelta;
     m_linesPerAction = event.m_linesPerAction;
+    m_wheelAxis = event.m_wheelAxis;
 }
 
 // return true if was a button dclick event
@@ -737,10 +738,12 @@ wxKeyEvent::wxKeyEvent(const wxKeyEvent& evt)
 #endif
 }
 
+#if WXWIN_COMPATIBILITY_2_6
 long wxKeyEvent::KeyCode() const
 {
     return m_keyCode;
 }
+#endif // WXWIN_COMPATIBILITY_2_6
 
 wxWindowCreateEvent::wxWindowCreateEvent(wxWindow *win)
 {
@@ -760,6 +763,23 @@ wxChildFocusEvent::wxChildFocusEvent(wxWindow *win)
     SetEventObject(win);
 }
 
+// ----------------------------------------------------------------------------
+// wxHelpEvent
+// ----------------------------------------------------------------------------
+
+/* static */
+wxHelpEvent::Origin wxHelpEvent::GuessOrigin(Origin origin)
+{
+    if ( origin == Origin_Unknown )
+    {
+        // assume that the event comes from the help button if it's not from
+        // keyboard and that pressing F1 always results in the help event
+        origin = wxGetKeyState(WXK_F1) ? Origin_Keyboard : Origin_HelpButton;
+    }
+
+    return origin;
+}
+
 #endif // wxUSE_GUI
 
 
@@ -990,6 +1010,7 @@ wxEvtHandler::wxEvtHandler()
     m_eventsLocker = new wxCriticalSection;
 #  endif
 #endif
+    
     // no client data (yet)
     m_clientData = NULL;
     m_clientDataType = wxClientData_None;
@@ -1023,6 +1044,8 @@ wxEvtHandler::~wxEvtHandler()
         delete m_dynamicEvents;
     };
 
+    if (m_pendingEvents)
+        m_pendingEvents->DeleteContents(true);
     delete m_pendingEvents;
 
 #if wxUSE_THREADS
@@ -1084,10 +1107,7 @@ void wxEvtHandler::AddPendingEvent(wxEvent& event)
     wxENTER_CRIT_SECT( Lock() );
 
     if ( !m_pendingEvents )
-    {
       m_pendingEvents = new wxList;
-      m_pendingEvents->DeleteContents(true);
-    }
 
     m_pendingEvents->Append(eventCopy);
 
@@ -1104,18 +1124,18 @@ void wxEvtHandler::AddPendingEvent(wxEvent& event)
 
     wxLEAVE_CRIT_SECT(*wxPendingEventsLocker);
 
-    // 3) Inform the system that new pending events are somwehere,
+    // 3) Inform the system that new pending events are somewhere,
     //    and that these should be processed in idle time.
     wxWakeUpIdle();
 }
 
 void wxEvtHandler::ProcessPendingEvents()
 {
-    // this method is only called by wxApp if this handler does have pending
-    // events
+    // this method is only called by wxApp if this handler does have
+    // pending events
     wxCHECK_RET( m_pendingEvents,
                  wxT("Please call wxApp::ProcessPendingEvents() instead") );
-
+    
     wxENTER_CRIT_SECT( Lock() );
 
     // we leave the loop once we have processed all events that were present at
@@ -1129,15 +1149,21 @@ void wxEvtHandler::ProcessPendingEvents()
     {
         wxEvent *event = (wxEvent *)node->GetData();
 
+        // It's importan we remove event from list before processing it.
+        // Else a nested event loop, for example from a modal dialog, might
+        // process the same event again.
+
+        m_pendingEvents->Erase(node);
+
         wxLEAVE_CRIT_SECT( Lock() );
 
         ProcessEvent(*event);
 
-        wxENTER_CRIT_SECT( Lock() );
+        delete event;
 
-        m_pendingEvents->Erase(node);
+        wxENTER_CRIT_SECT( Lock() );
 
-        if ( !--n )
+        if ( --n == 0 )
             break;
     }
 
@@ -1342,6 +1368,10 @@ bool wxEvtHandler::SearchDynamicEventTable( wxEvent& event )
         wxDynamicEventTableEntry *entry = (wxDynamicEventTableEntry*)node->GetData();
 #endif // WXWIN_COMPATIBILITY_EVENT_TYPES/!WXWIN_COMPATIBILITY_EVENT_TYPES
 
+        // get next node before (maybe) calling the event handler as it could
+        // call Disconnect() invalidating the current node
+        node = node->GetNext();
+
         if ((event.GetEventType() == entry->m_eventType) && (entry->m_fn != 0))
         {
             wxEvtHandler *handler =
@@ -1356,8 +1386,6 @@ bool wxEvtHandler::SearchDynamicEventTable( wxEvent& event )
                 return true;
             }
         }
-
-        node = node->GetNext();
     }
 
     return false;
@@ -1431,4 +1459,38 @@ wxWindow* wxFindFocusDescendant(wxWindow* ancestor)
     return focusWin;
 }
 
+// ----------------------------------------------------------------------------
+// wxEventBlocker
+// ----------------------------------------------------------------------------
+
+wxEventBlocker::wxEventBlocker(wxWindow *win, wxEventType type)
+{
+    wxCHECK_RET(win, wxT("Null window given to wxEventBlocker"));
+
+    m_window = win;
+
+    Block(type);
+    m_window->PushEventHandler(this);
+}
+
+wxEventBlocker::~wxEventBlocker()
+{
+    wxEvtHandler *popped = m_window->PopEventHandler(false);
+    wxCHECK_RET(popped == this, 
+        wxT("Don't push other event handlers into a window managed by wxEventBlocker!"));
+}
+
+bool wxEventBlocker::ProcessEvent(wxEvent& event)
+{
+    // should this event be blocked?
+    for ( size_t i = 0; i < m_eventsToBlock.size(); i++ )
+    {
+        wxEventType t = (wxEventType)m_eventsToBlock[i];
+        if ( t == wxEVT_ANY || t == event.GetEventType() )
+            return true;   // yes, it should: mark this event as processed
+    }
+
+    return false;
+}
+
 #endif // wxUSE_GUI