Merge branch 'osx-dvc'

Some wxOSX wxDataViewCtrl fixes OSX.

See https://github.com/wxWidgets/wxWidgets/pull/1556
This commit is contained in:
Vadim Zeitlin
2019-09-18 14:34:10 +02:00
5 changed files with 58 additions and 24 deletions

View File

@@ -486,10 +486,7 @@ public:
virtual wxDataViewItem GetTopItem() const;
virtual bool IsExpanded(const wxDataViewItem& item) const;
virtual bool Reload();
virtual bool Remove(const wxDataViewItem& parent,
const wxDataViewItem& item);
virtual bool Remove(const wxDataViewItem& parent,
const wxDataViewItemArray& item);
virtual bool Remove(const wxDataViewItem& parent);
virtual bool Update(const wxDataViewColumn* columnPtr);
virtual bool Update(const wxDataViewItem& parent,
const wxDataViewItem& item);

View File

@@ -68,8 +68,7 @@ public:
virtual wxDataViewItem GetTopItem (void) const = 0; // get top-most visible item
virtual bool IsExpanded (wxDataViewItem const& item) const = 0; // checks if the passed item is expanded in the native control
virtual bool Reload (void) = 0; // clears the native control and reloads all data
virtual bool Remove (wxDataViewItem const& parent, wxDataViewItem const& item) = 0; // removes an item from the native control
virtual bool Remove (wxDataViewItem const& parent, wxDataViewItemArray const& item) = 0; // removes items from the native control
virtual bool Remove (wxDataViewItem const& parent) = 0; // removes one or more items under the given parent from the native control
virtual bool Update (wxDataViewColumn const* columnPtr) = 0; // updates the items in the passed column of the native control
virtual bool Update (wxDataViewItem const& parent, wxDataViewItem const& item) = 0; // updates the passed item in the native control
virtual bool Update (wxDataViewItem const& parent, wxDataViewItemArray const& items) = 0; // updates the passed items in the native control

View File

@@ -2513,10 +2513,6 @@ public:
corresponding event. Is @NULL otherwise (for keyboard activation).
Mouse coordinates are adjusted to be relative to the cell.
@note Currently support for this method is not implemented in the
native macOS version of the control, i.e. it will be never called
there.
@since 2.9.3
@note Do not confuse this method with item activation in wxDataViewCtrl

View File

@@ -568,6 +568,14 @@ outlineView:(NSOutlineView*)outlineView
{
wxUnusedVar(outlineView);
if ( implementation->GetDataViewCtrl()->IsDeleting() )
{
// Note that returning "NO" here would result in currently expanded
// branches not being expanded any more, while returning "YES" doesn't
// seem to have any ill effects, even though this is clearly bogus.
return YES;
}
wxCHECK_MSG( model, 0, "Valid model in data source does not exist." );
return model->IsContainer(wxDataViewItemFromItem(item));
}
@@ -597,6 +605,15 @@ outlineView:(NSOutlineView*)outlineView
{
wxUnusedVar(outlineView);
// We ignore any calls to this function happening while items are being
// deleted, as they can (only?) come from -[NSTableView textDidEndEditing:]
// called from our own textDidEndEditing, which is called by
// -[NSOutlineView reloadItem:reloadChildren:], and if the item being
// edited is one of the items being deleted, then trying to use it would
// attempt to use already freed memory and crash.
if ( implementation->GetDataViewCtrl()->IsDeleting() )
return nil;
wxCHECK_MSG( model, nil, "Valid model in data source does not exist." );
wxDataViewColumn* const
@@ -623,6 +640,11 @@ outlineView:(NSOutlineView*)outlineView
{
wxUnusedVar(outlineView);
// See the comment in outlineView:objectValueForTableColumn:byItem: above:
// this function can also be called in the same circumstances.
if ( implementation->GetDataViewCtrl()->IsDeleting() )
return;
wxDataViewColumn* const
col([static_cast<wxDVCNSTableColumn*>(tableColumn) getColumnPointer]);
@@ -1655,10 +1677,35 @@ outlineView:(NSOutlineView*)outlineView
// and setDoubleAction: seems to be wrong as this action message is always
// sent whether the cell is editable or not
wxDataViewCtrl* const dvc = implementation->GetDataViewCtrl();
wxDataViewModel * const model = dvc->GetModel();
const wxDataViewItem item = wxDataViewItemFromItem([self itemAtRow:[self clickedRow]]);
const NSInteger col = [self clickedColumn];
wxDataViewColumn* const dvCol = implementation->GetColumn(col);
// Check if we need to activate a custom renderer first.
if ( wxDataViewCustomRenderer* const
renderer = wxDynamicCast(dvCol->GetRenderer(), wxDataViewCustomRenderer) )
{
if ( renderer->GetMode() == wxDATAVIEW_CELL_ACTIVATABLE &&
model->IsEnabled(item, dvCol->GetModelColumn()) )
{
const wxRect rect = implementation->GetRectangle(item, dvCol);
wxMouseEvent mouseEvent(wxEVT_LEFT_DCLICK);
wxPoint pos = dvc->ScreenToClient(wxGetMousePosition());
pos -= rect.GetPosition();
mouseEvent.m_x = pos.x;
mouseEvent.m_y = pos.y;
renderer->ActivateCell(rect, model, item, col, &mouseEvent);
}
}
// And then send the ACTIVATED event in any case.
wxDataViewEvent event(wxEVT_DATAVIEW_ITEM_ACTIVATED, dvc, item);
event.SetColumn( [self clickedColumn] );
event.SetColumn(col);
dvc->GetEventHandler()->ProcessEvent(event);
}
@@ -1937,6 +1984,10 @@ outlineView:(NSOutlineView*)outlineView
{
// call method of superclass (otherwise editing does not work correctly -
// the outline data source class is not informed about a change of data):
//
// Note that we really, really need to do this, as otherwise we would be
// left with an orphan text control -- even though doing this forces us to
// have the checks for IsDeleting() in several other methods of this class.
[super textDidEndEditing:notification];
// under OSX an event indicating the end of an editing session can be sent
@@ -2339,16 +2390,7 @@ bool wxCocoaDataViewControl::Reload()
return true;
}
bool wxCocoaDataViewControl::Remove(const wxDataViewItem& parent, const wxDataViewItem& WXUNUSED(item))
{
if (parent.IsOk())
[m_OutlineView reloadItem:[m_DataSource getDataViewItemFromBuffer:parent] reloadChildren:YES];
else
[m_OutlineView reloadData];
return true;
}
bool wxCocoaDataViewControl::Remove(const wxDataViewItem& parent, const wxDataViewItemArray& WXUNUSED(item))
bool wxCocoaDataViewControl::Remove(const wxDataViewItem& parent)
{
if (parent.IsOk())
[m_OutlineView reloadItem:[m_DataSource getDataViewItemFromBuffer:parent] reloadChildren:YES];

View File

@@ -170,7 +170,7 @@ bool wxOSXDataViewModelNotifier::ItemDeleted(wxDataViewItem const& parent, wxDat
// to prevent the control trying to ask the model to update an already deleted item the control is informed that currently a deleting process
// has been started and that variables can currently not be updated even when requested by the system:
m_DataViewCtrlPtr->SetDeleting(true);
noFailureFlag = m_DataViewCtrlPtr->GetDataViewPeer()->Remove(parent,item);
noFailureFlag = m_DataViewCtrlPtr->GetDataViewPeer()->Remove(parent);
// enable automatic updating again:
m_DataViewCtrlPtr->SetDeleting(false);
@@ -179,7 +179,7 @@ bool wxOSXDataViewModelNotifier::ItemDeleted(wxDataViewItem const& parent, wxDat
return noFailureFlag;
}
bool wxOSXDataViewModelNotifier::ItemsDeleted(wxDataViewItem const& parent, wxDataViewItemArray const& items)
bool wxOSXDataViewModelNotifier::ItemsDeleted(wxDataViewItem const& parent, wxDataViewItemArray const& WXUNUSED(items))
{
bool noFailureFlag;
@@ -190,7 +190,7 @@ bool wxOSXDataViewModelNotifier::ItemsDeleted(wxDataViewItem const& parent, wxDa
// has been started and that variables can currently not be updated even when requested by the system:
m_DataViewCtrlPtr->SetDeleting(true);
// delete all specified items:
noFailureFlag = m_DataViewCtrlPtr->GetDataViewPeer()->Remove(parent,items);
noFailureFlag = m_DataViewCtrlPtr->GetDataViewPeer()->Remove(parent);
// enable automatic updating again:
m_DataViewCtrlPtr->SetDeleting(false);