]> git.saurik.com Git - wxWidgets.git/commitdiff
Store property name and value in wxPropertyGridEvent, keep track of live event instan...
authorJaakko Salli <jaakko.salli@dnainternet.net>
Sun, 27 Sep 2009 14:35:02 +0000 (14:35 +0000)
committerJaakko Salli <jaakko.salli@dnainternet.net>
Sun, 27 Sep 2009 14:35:02 +0000 (14:35 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@62168 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/propgrid/propgrid.h
interface/wx/propgrid/propgrid.h
src/propgrid/propgrid.cpp

index e5cb9d741dabcce08ad12a3b0cfe0e26bb4cae79..a8dbe52937fa00e64c8072fef67d91555db0b979 100644 (file)
@@ -14,6 +14,7 @@
 
 #if wxUSE_PROPGRID
 
+#include "wx/thread.h"
 #include "wx/dcclient.h"
 #include "wx/scrolwin.h"
 #include "wx/tooltip.h"
@@ -43,6 +44,14 @@ public:
     wxPGGlobalVarsClass();
     ~wxPGGlobalVarsClass();
 
+#if wxUSE_THREAD
+    // Critical section for handling the globals. Generally it is not needed
+    // since GUI code is supposed to be in single thread. However,
+    // we do want the user to be able to convey wxPropertyGridEvents to other
+    // threads.
+    wxCriticalSection   m_critSect;
+#endif
+
     // Used by advprops, but here to make things easier.
     wxString            m_pDefaultImageWildcard;
 
@@ -420,7 +429,7 @@ public:
     /**
         Returns reference to pending value.
     */
-    const wxVariant& GetValue() const
+    wxVariant& GetValue()
     {
         wxASSERT(m_pValue);
         return *m_pValue;
@@ -642,6 +651,7 @@ enum wxPG_KEYBOARD_ACTIONS
 class WXDLLIMPEXP_PROPGRID
     wxPropertyGrid : public wxScrolledWindow, public wxPropertyGridInterface
 {
+    friend class wxPropertyGridEvent;
     friend class wxPropertyGridPageState;
     friend class wxPropertyGridInterface;
     friend class wxPropertyGridManager;
@@ -1851,6 +1861,9 @@ protected:
     // labels when properties use common values
     wxVector<wxPGCommonValue*>  m_commonValues;
 
+    // array of live events
+    wxVector<wxPropertyGridEvent*>  m_liveEvents;
+
     // Which cv selection really sets value to unspecified?
     int                 m_cvUnspecified;
 
@@ -2215,14 +2228,43 @@ public:
     */
     void Veto( bool veto = true ) { m_wasVetoed = veto; }
 
-    /** Returns value that is about to be set for wxEVT_PG_CHANGING.
+    /**
+        Returns name of the associated property.
+
+        @remarks Property name is stored in event, so it remains
+                 accessible even after the associated property or
+                 the property grid has been deleted.
     */
-    const wxVariant& GetValue() const
+    wxString GetPropertyName() const
     {
-        wxASSERT_MSG( m_validationInfo,
-                      "Only call GetValue from a handler "
-                      "of event type that supports it" );
-        return m_validationInfo->GetValue();
+        return m_propertyName;
+    }
+
+    /**
+        Returns value of the associated property. Works for all event
+        types, but for wxEVT_PG_CHANGING this member function returns
+        the value that is pending, so you can call Veto() if the
+        value is not satisfactory.
+
+        @remarks Property value is stored in event, so it remains
+                 accessible even after the associated property or
+                 the property grid has been deleted.
+    */
+    wxVariant GetPropertyValue() const
+    {
+        if ( m_validationInfo )
+            return m_validationInfo->GetValue();
+        return m_value;
+    }
+
+    /**
+        Returns value of the associated property.
+
+        @see GetPropertyValue
+    */
+    wxVariant GetValue() const
+    {
+        return GetPropertyValue();
     }
 
     /**
@@ -2262,25 +2304,44 @@ public:
     bool WasVetoed() const { return m_wasVetoed; }
 
     /** Changes the associated property. */
-    void SetProperty( wxPGProperty* p ) { m_property = p; }
+    void SetProperty( wxPGProperty* p )
+    {
+        m_property = p;
+        if ( p )
+            m_propertyName = p->GetName();
+    }
 
-    void SetPropertyGrid( wxPropertyGrid* pg ) { m_pg = pg; }
+    void SetPropertyValue( wxVariant value )
+    {
+        m_value = value;
+    }
+
+    void SetPropertyGrid( wxPropertyGrid* pg )
+    {
+        m_pg = pg;
+        OnPropertyGridSet();
+    }
 
     void SetupValidationInfo()
     {
         wxASSERT(m_pg);
         wxASSERT( GetEventType() == wxEVT_PG_CHANGING );
         m_validationInfo = &m_pg->GetValidationInfo();
+        m_value = m_validationInfo->GetValue();
     }
 
 private:
     void Init();
+    void OnPropertyGridSet();
     DECLARE_DYNAMIC_CLASS(wxPropertyGridEvent)
 
     wxPGProperty*       m_property;
     wxPropertyGrid*     m_pg;
     wxPGValidationInfo* m_validationInfo;
 
+    wxString            m_propertyName;
+    wxVariant           m_value;
+
     unsigned int        m_column;
 
     bool                m_canVeto;
index 665674620b535771bd83cc9d09342da486a9d500..48f9c06cc7b6ab53efac563bdac5305a01dabfcd 100644 (file)
@@ -270,7 +270,7 @@ public:
     /**
         Returns reference to pending value.
     */
-    const wxVariant& GetValue() const;
+    wxVariant& GetValue();
 
     /** Set validation failure behavior
 
@@ -1076,9 +1076,30 @@ public:
     wxPGVFBFlags GetValidationFailureBehavior() const;
 
     /**
-        Returns value that is about to be set for wxEVT_PG_CHANGING.
+        Returns name of the associated property.
+
+        @remarks Property name is stored in event, so it remains
+                 accessible even after the associated property or
+                 the property grid has been deleted.
+    */
+    wxString GetPropertyName() const;
+
+    /**
+        Returns value of the associated property. Works for all event
+        types, but for wxEVT_PG_CHANGING this member function returns
+        the value that is pending, so you can call Veto() if the
+        value is not satisfactory.
+
+        @remarks Property value is stored in event, so it remains
+                 accessible even after the associated property or
+                 the property grid has been deleted.
+    */
+    wxVariant GetPropertyValue() const
+
+    /**
+        @see GetPropertyValue()
     */
-    const wxVariant& GetValue() const;
+    wxVariant GetValue() const;
 
     /**
         Set if event can be vetoed.
index 4eb852079980af56bc9b1002f6b133ee4ed92312..e941c2a6c16f406b971baed35d0c703a9f286f38 100644 (file)
@@ -582,6 +582,20 @@ wxPropertyGrid::~wxPropertyGrid()
 {
     size_t i;
 
+#if wxUSE_THREAD
+    wxCriticalSectionLocker(wxPGGlobalVars->m_critSect);
+#endif
+
+    //
+    // Remove grid and property pointers from live wxPropertyGridEvents.
+    for ( i=0; i<m_liveEvents.size(); i++ )
+    {
+        wxPropertyGridEvent* evt = m_liveEvents[i];
+        evt->SetPropertyGrid(NULL);
+        evt->SetProperty(NULL);
+    }
+    m_liveEvents.clear();
+
     if ( m_processedEvent )
     {
         // All right... we are being deleted while wxPropertyGrid event
@@ -592,7 +606,7 @@ wxPropertyGrid::~wxPropertyGrid()
         m_processedEvent->StopPropagation();
 
         // Let's use wxMessageBox to make the message appear more
-        // reliably (and *before* the crash can happend).
+        // reliably (and *before* the crash can happen).
         ::wxMessageBox("wxPropertyGrid was being destroyed in an event "
                        "generated by it. This usually leads to a crash "
                        "so it is recommended to destroy the control "
@@ -4399,25 +4413,26 @@ bool wxPropertyGrid::SendEvent( int eventType, wxPGProperty* p,
     evt.SetEventObject(m_eventObject);
     evt.SetProperty(p);
     evt.SetColumn(column);
-    if ( pValue )
+    if ( eventType == wxEVT_PG_CHANGING )
     {
+        wxASSERT( pValue );
         evt.SetCanVeto(true);
-        evt.SetupValidationInfo();
         m_validationInfo.m_pValue = pValue;
+        evt.SetupValidationInfo();
     }
-    else if ( !(selFlags & wxPG_SEL_NOVALIDATE) )
+    else
     {
-        evt.SetCanVeto(true);
+        if ( p )
+            evt.SetPropertyValue(p->GetValue());
+
+        if ( !(selFlags & wxPG_SEL_NOVALIDATE) )
+            evt.SetCanVeto(true);
     }
 
     m_processedEvent = &evt;
-
-    wxEvtHandler* evtHandler = m_eventObject->GetEventHandler();
-
+    m_eventObject->HandleWindowEvent(evt);
     m_processedEvent = NULL;
 
-    evtHandler->ProcessEvent(evt);
-
     return evt.WasVetoed();
 }
 
@@ -5860,6 +5875,7 @@ wxPropertyGridEvent::wxPropertyGridEvent(const wxPropertyGridEvent& event)
     m_eventType = event.GetEventType();
     m_eventObject = event.m_eventObject;
     m_pg = event.m_pg;
+    OnPropertyGridSet();
     m_property = event.m_property;
     m_validationInfo = event.m_validationInfo;
     m_canVeto = event.m_canVeto;
@@ -5868,8 +5884,40 @@ wxPropertyGridEvent::wxPropertyGridEvent(const wxPropertyGridEvent& event)
 
 // -----------------------------------------------------------------------
 
+void wxPropertyGridEvent::OnPropertyGridSet()
+{
+    if ( !m_pg )
+        return;
+
+#if wxUSE_THREAD
+    wxCriticalSectionLocker(wxPGGlobalVars->m_critSect);
+#endif
+    m_pg->m_liveEvents.push_back(this);
+}
+
+// -----------------------------------------------------------------------
+
 wxPropertyGridEvent::~wxPropertyGridEvent()
 {
+    if ( m_pg )
+    {
+    #if wxUSE_THREAD
+        wxCriticalSectionLocker(wxPGGlobalVars->m_critSect);
+    #endif
+
+        // Use iterate from the back since it is more likely that the event
+        // being desroyed is at the end of the array.
+        wxVector<wxPropertyGridEvent*>& liveEvents = m_pg->m_liveEvents;
+
+        for ( int i = liveEvents.size()-1; i >= 0; i-- )
+        {
+            if ( liveEvents[i] == this )
+            {
+                liveEvents.erase(liveEvents.begin() + i);
+                break;
+            }
+        }
+    }
 }
 
 // -----------------------------------------------------------------------