]> git.saurik.com Git - wxWidgets.git/commitdiff
Fix crash when editing wxDVC items in place in wxOSX/Cocoa.
authorVadim Zeitlin <vadim@wxwidgets.org>
Sat, 17 Oct 2009 01:04:13 +0000 (01:04 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sat, 17 Oct 2009 01:04:13 +0000 (01:04 +0000)
NSOutlineView::editedColumn: and editedRow: return -1 when they are called
from textDidEndEditing so we need to store their values in textDidBeginEditing
and reuse them later.

This fixes the crash in the sample with out-of-range array index exception
which happened whenever a cell was edited.

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

include/wx/osx/cocoa/dataview.h
src/osx/cocoa/dataview.mm

index 1fffc75bd7d98425a98f6abd19c00314c26e185a..6efca71dafcd4e2e302686c0dfdc747685ad3ab3 100644 (file)
@@ -418,7 +418,9 @@ private:
 @interface wxCocoaOutlineView : NSOutlineView
 {
 @private
-  BOOL isEditingCell; // flag indicating if a cell is currently being edited
+  // column and row of the cell being edited or -1 if none
+  int currentlyEditedColumn,
+      currentlyEditedRow;
 
   wxCocoaDataViewControl* implementation;
 }
index 127e4bb2a2639c09a9e6b17e35fd913aae6b172c..9ecff408569dcf91c1e5d79c64150fa3718ca1bf 100644 (file)
@@ -1338,7 +1338,9 @@ wxWidgetImplType* CreateDataView(wxWindowMac* wxpeer, wxWindowMac* WXUNUSED(pare
   self = [super init];
   if (self != nil)
   {
-    isEditingCell = NO;
+    currentlyEditedColumn =
+    currentlyEditedRow = -1;
+
     [self registerForDraggedTypes:[NSArray arrayWithObjects:DataViewPboardType,NSStringPboardType,nil]];
     [self setDelegate:self];
     [self setDoubleAction:@selector(actionDoubleClick:)];
@@ -1644,21 +1646,26 @@ wxWidgetImplType* CreateDataView(wxWindowMac* wxpeer, wxWindowMac* WXUNUSED(pare
  // informed about a change of data):
   [super textDidBeginEditing:notification];
 
-  wxDataViewColumn* const dataViewColumnPtr = reinterpret_cast<wxDataViewColumn*>([[[[self tableColumns] objectAtIndex:[self editedColumn]] identifier] pointer]);
+  // remember the column being edited, it will be used in textDidEndEditing:
+  currentlyEditedColumn = [self editedColumn];
+  currentlyEditedRow = [self editedRow];
+
+  wxDataViewColumn* const dataViewColumnPtr =
+      static_cast<wxDataViewColumn*>(
+        [[[[self tableColumns] objectAtIndex:currentlyEditedColumn] identifier] pointer]);
 
   wxDataViewCtrl* const dataViewCtrlPtr = implementation->GetDataViewCtrl();
 
 
  // stop editing of a custom item first (if necessary)
   dataViewCtrlPtr->FinishCustomItemEditing();
- // set the flag that currently a cell is being edited (see also textDidEndEditing:):
-  isEditingCell = YES;
 
  // now, send the event:
   wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_STARTED,dataViewCtrlPtr->GetId()); // variable definition
 
   dataViewEvent.SetEventObject(dataViewCtrlPtr);
-  dataViewEvent.SetItem(wxDataViewItem([((wxPointerObject*) [self itemAtRow:[self editedRow]]) pointer]));
+  dataViewEvent.SetItem(
+        wxDataViewItem([((wxPointerObject*) [self itemAtRow:currentlyEditedRow]) pointer]));
   dataViewEvent.SetColumn(dataViewCtrlPtr->GetColumnPosition(dataViewColumnPtr));
   dataViewEvent.SetDataViewColumn(dataViewColumnPtr);
   dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
@@ -1674,10 +1681,12 @@ wxWidgetImplType* CreateDataView(wxWindowMac* wxpeer, wxWindowMac* WXUNUSED(pare
  // editing session has been sent (see Documentation for NSControl controlTextDidEndEditing:); this is not expected by a user
  // of the wxWidgets library and therefore an wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_DONE event is only sent if a corresponding
  // wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_STARTED has been sent before; to check if a wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_STARTED
- // has been sent the flag isEditingCell is used:
-  if (isEditingCell == YES)
+ // has been sent the last edited column/row are valid:
+  if ( currentlyEditedColumn != -1 && currentlyEditedRow != -1 )
   {
-    wxDataViewColumn* const dataViewColumnPtr = reinterpret_cast<wxDataViewColumn*>([[[[self tableColumns] objectAtIndex:[self editedColumn]] identifier] pointer]);
+    wxDataViewColumn* const dataViewColumnPtr =
+        static_cast<wxDataViewColumn*>(
+            [[[[self tableColumns] objectAtIndex:currentlyEditedColumn] identifier] pointer]);
 
     wxDataViewCtrl* const dataViewCtrlPtr = implementation->GetDataViewCtrl();
 
@@ -1685,12 +1694,16 @@ wxWidgetImplType* CreateDataView(wxWindowMac* wxpeer, wxWindowMac* WXUNUSED(pare
     wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_DONE,dataViewCtrlPtr->GetId()); // variable definition
 
     dataViewEvent.SetEventObject(dataViewCtrlPtr);
-    dataViewEvent.SetItem(wxDataViewItem([((wxPointerObject*) [self itemAtRow:[self editedRow]]) pointer]));
+    dataViewEvent.SetItem(
+        wxDataViewItem([((wxPointerObject*) [self itemAtRow:currentlyEditedRow]) pointer]));
     dataViewEvent.SetColumn(dataViewCtrlPtr->GetColumnPosition(dataViewColumnPtr));
     dataViewEvent.SetDataViewColumn(dataViewColumnPtr);
     dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
-   // set flag to the inactive state:
-    isEditingCell = NO;
+
+
+    // we're not editing any more
+    currentlyEditedColumn =
+    currentlyEditedRow = -1;
   }
 }