]> git.saurik.com Git - wxWidgets.git/commitdiff
Really fix the problem with caret in wxGrid text editor under MSW.
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 28 Apr 2013 18:25:42 +0000 (18:25 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 28 Apr 2013 18:25:42 +0000 (18:25 +0000)
The problem (see #11681) was due to not allowing the native control handle the
focus loss event. This, in turn, was due to the changes of r58969 which tried
to work around a crash which happened if the grid was destroyed from the code
of one of the user-defined event handlers called during the editor dismissal.

Fix both problems at once by calling event.Skip() in OnKillFocus() to let the
native handler have the event too and postponing the editor dismissal a little
by calling DisableCellEditControl() indirectly from a posted event handler
instead of immediately.

As this reverts the now unnecessary changes of r64646, it closes #15162.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@73876 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/generic/grid.h
include/wx/generic/private/grid.h
src/generic/grid.cpp
src/generic/grideditors.cpp

index e940a63c8f88c97fa3c813de2adc8b5b3d8062cf..74888b96fdf061427bdc29826a1a839dcb2d22fe 100644 (file)
@@ -2128,6 +2128,7 @@ protected:
     void OnKeyUp( wxKeyEvent& );
     void OnChar( wxKeyEvent& );
     void OnEraseBackground( wxEraseEvent& );
     void OnKeyUp( wxKeyEvent& );
     void OnChar( wxKeyEvent& );
     void OnEraseBackground( wxEraseEvent& );
+    void OnHideEditor( wxCommandEvent& );
 
 
     bool SetCurrentCell( const wxGridCellCoords& coords );
 
 
     bool SetCurrentCell( const wxGridCellCoords& coords );
index 3b21325aa0a95b0297b0256faa8a77906a22196a..df581d4ce3e5ffc9d55eb99af16ce333dca97e6a 100644 (file)
 
 #if wxUSE_GRID
 
 
 #if wxUSE_GRID
 
+// Internally used (and hence intentionally not exported) event telling wxGrid
+// to hide the currently shown editor.
+wxDECLARE_EVENT( wxEVT_GRID_HIDE_EDITOR, wxCommandEvent );
+
 // ----------------------------------------------------------------------------
 // array classes
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 // array classes
 // ----------------------------------------------------------------------------
index 771f35032eee6217fe7c1732d3dc5641d09ae8d6..4926ae4a992c0d782e1877bef711475ca36198d3 100644 (file)
@@ -2159,6 +2159,7 @@ BEGIN_EVENT_TABLE( wxGrid, wxScrolledWindow )
     EVT_KEY_UP( wxGrid::OnKeyUp )
     EVT_CHAR ( wxGrid::OnChar )
     EVT_ERASE_BACKGROUND( wxGrid::OnEraseBackground )
     EVT_KEY_UP( wxGrid::OnKeyUp )
     EVT_CHAR ( wxGrid::OnChar )
     EVT_ERASE_BACKGROUND( wxGrid::OnEraseBackground )
+    EVT_COMMAND(wxID_ANY, wxEVT_GRID_HIDE_EDITOR, wxGrid::OnHideEditor )
 END_EVENT_TABLE()
 
 bool wxGrid::Create(wxWindow *parent, wxWindowID id,
 END_EVENT_TABLE()
 
 bool wxGrid::Create(wxWindow *parent, wxWindowID id,
@@ -6553,6 +6554,11 @@ void wxGrid::SaveEditControlValue()
     }
 }
 
     }
 }
 
+void wxGrid::OnHideEditor(wxCommandEvent& WXUNUSED(event))
+{
+    DisableCellEditControl();
+}
+
 //
 // ------ Grid location functions
 //  Note that all of these functions work with the logical coordinates of
 //
 // ------ Grid location functions
 //  Note that all of these functions work with the logical coordinates of
index cadc963e9e3fbc053d3354d065e286475ca78233..93095852e8052cb30e32e3cbdffbaa744034912f 100644 (file)
 // implementation
 // ============================================================================
 
 // implementation
 // ============================================================================
 
+wxDEFINE_EVENT( wxEVT_GRID_HIDE_EDITOR, wxCommandEvent );
+
 // ----------------------------------------------------------------------------
 // wxGridCellEditorEvtHandler
 // ----------------------------------------------------------------------------
 
 void wxGridCellEditorEvtHandler::OnKillFocus(wxFocusEvent& event)
 {
 // ----------------------------------------------------------------------------
 // wxGridCellEditorEvtHandler
 // ----------------------------------------------------------------------------
 
 void wxGridCellEditorEvtHandler::OnKillFocus(wxFocusEvent& event)
 {
+    // We must let the native control have this event so in any case don't mark
+    // it as handled, otherwise various weird problems can happen (see #11681).
+    event.Skip();
+
     // Don't disable the cell if we're just starting to edit it
     // Don't disable the cell if we're just starting to edit it
-    if ( m_inSetFocus )
-    {
-        event.Skip();
+    if (m_inSetFocus)
         return;
         return;
-    }
 
 
-    // accept changes
-    m_grid->DisableCellEditControl();
+    // Tell the grid to dismiss the control but don't do it immediately as it
+    // could result in the editor being destroyed right now and a crash in the
+    // code searching for the next event handler, so post an event asking the
+    // grid to do it slightly later instead.
 
 
-    // notice that we must not skip the event here because the call above may
-    // delete the control which received the kill focus event in the first
-    // place and if we pretend not having processed the event, the search for a
-    // handler for it will continue using the now deleted object resulting in a
-    // crash
+    // FIXME-VC6: Once we drop support for VC6, we should use a simpler
+    //            m_grid->CallAfter(&wxGrid::DisableCellEditControl) and get
+    //            rid of wxEVT_GRID_HIDE_EDITOR entirely.
+    m_grid->GetEventHandler()->
+        AddPendingEvent(wxCommandEvent(wxEVT_GRID_HIDE_EDITOR));
 }
 
 void wxGridCellEditorEvtHandler::OnKeyDown(wxKeyEvent& event)
 }
 
 void wxGridCellEditorEvtHandler::OnKeyDown(wxKeyEvent& event)
@@ -394,10 +399,7 @@ void wxGridCellTextEditor::DoCreate(wxWindow* parent,
                                     wxEvtHandler* evtHandler,
                                     long style)
 {
                                     wxEvtHandler* evtHandler,
                                     long style)
 {
-    // Use of wxTE_RICH2 is a strange hack to work around the bug #11681: a
-    // plain text control seems to lose its caret somehow when we hide it and
-    // show it again for a different cell.
-    style |= wxTE_PROCESS_ENTER | wxTE_PROCESS_TAB | wxNO_BORDER | wxTE_RICH2;
+    style |= wxTE_PROCESS_ENTER | wxTE_PROCESS_TAB | wxNO_BORDER;
 
     wxTextCtrl* const text = new wxTextCtrl(parent, id, wxEmptyString,
                                             wxDefaultPosition, wxDefaultSize,
 
     wxTextCtrl* const text = new wxTextCtrl(parent, id, wxEmptyString,
                                             wxDefaultPosition, wxDefaultSize,