From: Vadim Zeitlin Date: Sat, 17 Oct 2009 01:04:13 +0000 (+0000) Subject: Fix crash when editing wxDVC items in place in wxOSX/Cocoa. X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/f32eb96401af815f5662b715330802c2e6bfa452 Fix crash when editing wxDVC items in place in wxOSX/Cocoa. 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 --- diff --git a/include/wx/osx/cocoa/dataview.h b/include/wx/osx/cocoa/dataview.h index 1fffc75bd7..6efca71daf 100644 --- a/include/wx/osx/cocoa/dataview.h +++ b/include/wx/osx/cocoa/dataview.h @@ -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; } diff --git a/src/osx/cocoa/dataview.mm b/src/osx/cocoa/dataview.mm index 127e4bb2a2..9ecff40856 100644 --- a/src/osx/cocoa/dataview.mm +++ b/src/osx/cocoa/dataview.mm @@ -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([[[[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( + [[[[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([[[[self tableColumns] objectAtIndex:[self editedColumn]] identifier] pointer]); + wxDataViewColumn* const dataViewColumnPtr = + static_cast( + [[[[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; } }