]> git.saurik.com Git - wxWidgets.git/blobdiff - src/osx/cocoa/dataview.mm
make sure mouse moved events are always delivered, see #15008
[wxWidgets.git] / src / osx / cocoa / dataview.mm
index f43a4f27e4b2450d0176fd5fd74fab760adc1a6a..829b5dc5b0ec8127edbf490a26d4c01d8b0a5633 100644 (file)
@@ -1,11 +1,11 @@
 ///////////////////////////////////////////////////////////////////////////////
 // Name:        src/osx/cocoa/dataview.mm
 // Purpose:     wxDataView
-// Author:      
+// Author:
 // Modified by:
 // Created:     2009-01-31
 // RCS-ID:      $Id: dataview.mm$
-// Copyright:   
+// Copyright:
 // Licence:     wxWindows licence
 ///////////////////////////////////////////////////////////////////////////////
 
     #include "wx/utils.h"
 #endif
 
-#include "wx/osx/cocoa/dataview.h"
 #include "wx/osx/private.h"
+#include "wx/osx/cocoa/dataview.h"
 #include "wx/renderer.h"
-
+#include "wx/stopwatch.h"
+#include "wx/dcgraph.h"
 
 // ============================================================================
 // Constants used locally
 // ============================================================================
+
 #define DataViewPboardType @"OutlineViewItem"
 
 // ============================================================================
 // Classes used locally in dataview.mm
 // ============================================================================
-@interface wxCustomRendererObject : NSObject <NSCopying>
-{
-@public
-  NSTableColumn* tableColumn; // not owned by the class
 
-  wxDataViewCustomRenderer* customRenderer; // not owned by the class
-  
-  wxPointerObject* item; // not owned by the class
-}
+// ============================================================================
+// wxPointerObject
+// ============================================================================
 
- //
- // initialization
- //
-  -(id) init;
-  -(id) initWithRenderer:(wxDataViewCustomRenderer*)initRenderer item:(wxPointerObject*)initItem column:(NSTableColumn*)initTableColumn;
+@implementation wxPointerObject
 
-@end
+-(id) init
+{
+    self = [super init];
+    if (self != nil)
+        self->pointer = NULL;
+    return self;
+}
+
+-(id) initWithPointer:(void*) initPointer
+{
+    self = [super init];
+    if (self != nil)
+        self->pointer = initPointer;
+    return self;
+}
 
-@implementation wxCustomRendererObject
 //
-// initialization
+// inherited methods from NSObject
 //
--(id) init
+-(BOOL) isEqual:(id)object
 {
-  self = [super init];
-  if (self != nil)
-  {
-    customRenderer = NULL;
-    item           = NULL;
-    tableColumn    = NULL;
-  }
-  return self;
+    return (object != nil) &&
+             ([object isKindOfClass:[wxPointerObject class]]) &&
+                 (pointer == [((wxPointerObject*) object) pointer]);
 }
 
--(id) initWithRenderer:(wxDataViewCustomRenderer*)initRenderer item:(wxPointerObject*)initItem column:(NSTableColumn*)initTableColumn
+-(NSUInteger) hash
 {
-  self = [super init];
-  if (self != nil)
-  {
-    customRenderer = initRenderer;
-    item           = initItem;
-    tableColumn    = initTableColumn;
-  }
-  return self;
+    return (NSUInteger) pointer;
 }
 
--(id) copyWithZone:(NSZone*)zone
+-(void*) pointer
 {
-  wxCustomRendererObject* copy;
-  
-  
-  copy = [[[self class] allocWithZone:zone] init];
-  copy->customRenderer = customRenderer;
-  copy->item           = item;
-  copy->tableColumn    = tableColumn;
+    return pointer;
+}
 
-  return copy;
+-(void) setPointer:(void*) newPointer
+{
+    pointer = newPointer;
 }
 
 @end
 
-// ============================================================================
-// Functions used locally in dataview.mm
-// ============================================================================
-static NSInteger CompareItems(id item1, id item2, void* context)
+namespace
+{
+
+inline wxDataViewItem wxDataViewItemFromItem(id item)
 {
-  NSArray* const sortDescriptors = (NSArray*) context;
-  
-  NSUInteger const noOfDescriptors = [sortDescriptors count];
+    return wxDataViewItem([static_cast<wxPointerObject *>(item) pointer]);
+}
 
-  NSInteger result(NSOrderedAscending);
+inline wxDataViewItem wxDataViewItemFromMaybeNilItem(id item)
+{
+    return item == nil ? wxDataViewItem() : wxDataViewItemFromItem(item);
+}
 
+} // anonymous namespace
 
-  for (NSUInteger i=0; i<noOfDescriptors; ++i)
-  {
-   // constant definition for abbreviational purposes:
-    wxSortDescriptorObject* const sortDescriptor = (wxSortDescriptorObject*)[sortDescriptors objectAtIndex:i];
+// ----------------------------------------------------------------------------
+// wxCustomRendererObject
+// ----------------------------------------------------------------------------
 
-    int wxComparisonResult;
-    
-    wxComparisonResult = [sortDescriptor modelPtr]->Compare(wxDataViewItem([((wxPointerObject*) item1) pointer]),
-                                                            wxDataViewItem([((wxPointerObject*) item2) pointer]),
-                                                            [sortDescriptor columnPtr]->GetModelColumn(),
-                                                            [sortDescriptor ascending] == YES);
-    if (wxComparisonResult < 0)
+@interface wxCustomRendererObject : NSObject <NSCopying>
+{
+@public
+    wxDataViewCustomRenderer* customRenderer; // not owned by the class
+}
+
+    -(id) init;
+    -(id) initWithRenderer:(wxDataViewCustomRenderer*)renderer;
+@end
+
+@implementation wxCustomRendererObject
+
+-(id) init
+{
+    self = [super init];
+    if (self != nil)
     {
-      result = NSOrderedAscending;
-      break;
+        customRenderer = NULL;
     }
-    else if (wxComparisonResult > 0)
+    return self;
+}
+
+-(id) initWithRenderer:(wxDataViewCustomRenderer*)renderer
+{
+    self = [super init];
+    if (self != nil)
     {
-      result = NSOrderedDescending;
-      break;
+        customRenderer = renderer;
     }
-    else
-      result = NSOrderedSame;
-  }
-  return result;
+    return self;
 }
 
-static NSTextAlignment ConvertToNativeHorizontalTextAlignment(int alignment)
+-(id) copyWithZone:(NSZone*)zone
 {
-  if (alignment & wxALIGN_CENTER_HORIZONTAL) // center alignment is chosen also if alignment is equal to -1
-    return NSCenterTextAlignment;
-  else if (alignment & wxALIGN_RIGHT)
-    return NSRightTextAlignment;
-  else
-    return NSLeftTextAlignment;
+    wxCustomRendererObject* copy;
+
+    copy = [[[self class] allocWithZone:zone] init];
+    copy->customRenderer = customRenderer;
+
+    return copy;
 }
+@end
 
-static NSTableColumn* CreateNativeColumn(wxDataViewColumn const* columnPtr)
+// ----------------------------------------------------------------------------
+// wxDVCNSTableColumn: exists only to override NSTableColumn:dataCellForRow:
+// ----------------------------------------------------------------------------
+
+@interface wxDVCNSTableColumn : NSTableColumn
 {
-  NSTableColumn* nativeColumn([[NSTableColumn alloc] initWithIdentifier:[[[wxPointerObject alloc] initWithPointer:const_cast<wxDataViewColumn*>(columnPtr)] autorelease]]);
+}
 
+    // Get the identifier we use for the specified column. This should be used
+    // for finding columns from identifier only, to initialize the identifier
+    // of a new column use initWithColumnPointer below instead.
+    +(NSString*) identifierForColumnPointer:(const wxDataViewColumn*)column;
 
- // initialize the native column:
-  if ((nativeColumn != NULL) && (columnPtr->GetRenderer() != NULL))
-  {
-   // setting the size related parameters:
-    if (columnPtr->IsResizeable())
-    {
-      [nativeColumn setResizingMask:NSTableColumnUserResizingMask];
-      [nativeColumn setMinWidth:columnPtr->GetMinWidth()];
-      [nativeColumn setMaxWidth:columnPtr->GetMaxWidth()];
-    }
-    else
+    // Initialize the column with the given pointer to the associated
+    // wxDataViewColumn. This pointer can later be retrieved using
+    // getColumnPointer.
+    -(id) initWithColumnPointer:(const wxDataViewColumn*)column;
+
+    // Retrieve the associated column.
+    -(wxDataViewColumn*) getColumnPointer;
+
+    -(id) dataCellForRow:(NSInteger)row;
+@end
+
+@implementation wxDVCNSTableColumn
+
++(NSString*) identifierForColumnPointer:(const wxDataViewColumn*)column
+{
+    // Starting from OS X 10.7 the column identifier must be an NSString and
+    // not just some arbitrary object, so we serialize the pointer into the
+    // string. Notice the use of NSInteger which is big enough to store a
+    // pointer in both 32 and 64 bit builds.
+    return [NSString stringWithFormat:@"%lu", reinterpret_cast<NSUInteger>(column)];
+}
+
+-(id) initWithColumnPointer:(const wxDataViewColumn*)column
+{
+    [self initWithIdentifier: [wxDVCNSTableColumn identifierForColumnPointer:column]];
+    return self;
+}
+
+-(wxDataViewColumn*) getColumnPointer
+{
+    // The case to NSString is needed for OS X < 10.7.
+    return reinterpret_cast<wxDataViewColumn*>(
+            [static_cast<NSString*>([self identifier]) integerValue]);
+}
+
+-(id) dataCellForRow:(NSInteger)row
+{
+    // what we want to do here is to simply return nil for the cells which
+    // shouldn't show anything as otherwise we would show e.g. empty combo box
+    // or progress cells in the columns using the corresponding types even for
+    // the container rows which is wrong
+
+    const wxDataViewColumn * const dvCol = [self getColumnPointer];
+
+    const wxDataViewCtrl * const dvc = dvCol->GetOwner();
+    const wxCocoaDataViewControl * const
+        peer = static_cast<wxCocoaDataViewControl *>(dvc->GetPeer());
+
+
+    // once we do have everything, simply ask NSOutlineView for the item...
+    const id item = peer->GetItemAtRow(row);
+    if ( item )
     {
-      [nativeColumn setResizingMask:NSTableColumnNoResizing];
-      [nativeColumn setMinWidth:columnPtr->GetWidth()];
-      [nativeColumn setMaxWidth:columnPtr->GetWidth()];
+        // ... and if it succeeded, ask the model whether it has any value
+        wxDataViewItem dvItem(wxDataViewItemFromItem(item));
+
+        if ( !dvc->GetModel()->HasValue(dvItem, dvCol->GetModelColumn()) )
+            return nil;
     }
-    [nativeColumn setWidth:columnPtr->GetWidth()];
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
-   // setting the visibility:
-    [nativeColumn setHidden:static_cast<BOOL>(columnPtr->IsHidden())];
-#endif
-   // setting the header:
-    [[nativeColumn headerCell] setAlignment:ConvertToNativeHorizontalTextAlignment(columnPtr->GetAlignment())];
-    [[nativeColumn headerCell] setStringValue:[[wxCFStringRef(columnPtr->GetTitle()).AsNSString() retain] autorelease]];
-   // setting data cell's properties:
-    [[nativeColumn dataCell] setWraps:NO];
-   // setting the default data cell:
-    [nativeColumn setDataCell:columnPtr->GetRenderer()->GetNativeData()->GetColumnCell()];
-   // setting the editablility:
-    bool const dataCellIsEditable = (columnPtr->GetRenderer()->GetMode() == wxDATAVIEW_CELL_EDITABLE);
 
-     [nativeColumn           setEditable:dataCellIsEditable];
-    [[nativeColumn dataCell] setEditable:dataCellIsEditable];
-  }
- // done:
-  return nativeColumn;
+    return [super dataCellForRow:row];
 }
 
+@end
+
 // ============================================================================
-// Public helper functions for dataview implementation on OSX
+// local helpers
 // ============================================================================
-wxWidgetImplType* CreateDataView(wxWindowMac* wxpeer, wxWindowMac* WXUNUSED(parent),  wxWindowID WXUNUSED(id), wxPoint const& pos, wxSize const& size,
-                                 long style, long WXUNUSED(extraStyle))
+
+namespace
+{
+
+// convert from NSObject to different C++ types: all these functions check
+// that the conversion really makes sense and assert if it doesn't
+wxString ObjectToString(NSObject *object)
 {
-  return new wxCocoaDataViewControl(wxpeer,pos,size,style);
+    wxCHECK_MSG( [object isKindOfClass:[NSString class]], "",
+                 wxString::Format
+                 (
+                    "string expected but got %s",
+                    wxCFStringRef::AsString([object className])
+                 ));
+
+    return wxCFStringRef([((NSString*) object) retain]).AsString();
 }
 
-// ============================================================================
-// wxPointerObject
-// ============================================================================
-//
-// This is a helper class to store a pointer in an object.
-//
-@implementation wxPointerObject
-//
-// object initialization
-//
--(id) init
+bool ObjectToBool(NSObject *object)
 {
-  self = [super init];
-  if (self != nil)
-    self.pointer = NULL;
-  return self;
+    // actually the value must be of NSCFBoolean class but it's private so we
+    // can't check for it directly
+    wxCHECK_MSG( [object isKindOfClass:[NSNumber class]], false,
+                 wxString::Format
+                 (
+                    "number expected but got %s",
+                    wxCFStringRef::AsString([object className])
+                 ));
+
+    return [(NSNumber *)object boolValue];
 }
 
--(id) initWithPointer:(void*) initPointer
+long ObjectToLong(NSObject *object)
 {
-  self = [super init];
-  if (self != nil)
-    self.pointer = initPointer;
-  return self;
+    wxCHECK_MSG( [object isKindOfClass:[NSNumber class]], -1,
+                 wxString::Format
+                 (
+                    "number expected but got %s",
+                    wxCFStringRef::AsString([object className])
+                 ));
+
+    return [(NSNumber *)object longValue];
 }
 
-//
-// inherited methods from NSObject
-//
--(BOOL) isEqual:(id)object
+wxDateTime ObjectToDate(NSObject *object)
 {
-  return (object != nil) && ([object isKindOfClass:[wxPointerObject class]]) && (pointer == [((wxPointerObject*) object) pointer]);
+    wxCHECK_MSG( [object isKindOfClass:[NSDate class]], wxInvalidDateTime,
+                 wxString::Format
+                 (
+                    "date expected but got %s",
+                    wxCFStringRef::AsString([object className])
+                 ));
+
+    // get the number of seconds since 1970-01-01 UTC and this is the only
+    // way to convert a double to a wxLongLong
+    const wxLongLong seconds = [((NSDate*) object) timeIntervalSince1970];
+
+    wxDateTime dt(1, wxDateTime::Jan, 1970);
+    dt.Add(wxTimeSpan(0,0,seconds));
+
+    // the user has entered a date in the local timezone but seconds
+    // contains the number of seconds from date in the local timezone
+    // since 1970-01-01 UTC; therefore, the timezone information has to be
+    // transferred to wxWidgets, too:
+    dt.MakeFromTimezone(wxDateTime::UTC);
+
+    return dt;
 }
 
--(NSUInteger) hash
+NSInteger CompareItems(id item1, id item2, void* context)
 {
-  return (NSUInteger) pointer;
+    NSArray* const sortDescriptors = (NSArray*) context;
+
+    NSUInteger const count = [sortDescriptors count];
+
+    NSInteger result = NSOrderedSame;
+    for ( NSUInteger i = 0; i < count && result == NSOrderedSame; ++i )
+    {
+        wxSortDescriptorObject* const
+            sortDescriptor = (wxSortDescriptorObject*)
+                [sortDescriptors objectAtIndex:i];
+
+        int rc = [sortDescriptor modelPtr]->Compare
+                 (
+                     wxDataViewItemFromItem(item1),
+                     wxDataViewItemFromItem(item2),
+                     [sortDescriptor columnPtr]->GetModelColumn(),
+                     [sortDescriptor ascending] == YES
+                 );
+
+        if ( rc < 0 )
+            result = NSOrderedAscending;
+        else if ( rc > 0 )
+            result = NSOrderedDescending;
+    }
+
+    return result;
 }
 
-//
-// access to pointer
-//
--(void*) pointer
+NSTextAlignment ConvertToNativeHorizontalTextAlignment(int alignment)
 {
-  return pointer;
+    if (alignment & wxALIGN_CENTER_HORIZONTAL)
+        return NSCenterTextAlignment;
+    else if (alignment & wxALIGN_RIGHT)
+        return NSRightTextAlignment;
+    else
+        return NSLeftTextAlignment;
 }
 
--(void) setPointer:(void*) newPointer
+NSTableColumn* CreateNativeColumn(const wxDataViewColumn *column)
 {
-  pointer = newPointer;
+    wxDataViewRenderer * const renderer = column->GetRenderer();
+
+    wxCHECK_MSG( renderer, NULL, "column should have a renderer" );
+
+    wxDVCNSTableColumn * const nativeColumn(
+        [[wxDVCNSTableColumn alloc] initWithColumnPointer: column]
+    );
+
+    // setting the size related parameters:
+    int resizingMask;
+    if (column->IsResizeable())
+    {
+        resizingMask = NSTableColumnUserResizingMask;
+        [nativeColumn setMinWidth:column->GetMinWidth()];
+        [nativeColumn setMaxWidth:column->GetMaxWidth()];
+    }
+    else // column is not resizable [by user]
+    {
+        // if the control doesn't show a header, make the columns resize
+        // automatically, this is particularly important for the single column
+        // controls (such as wxDataViewTreeCtrl) as their unique column should
+        // always take up all the available splace
+        resizingMask = column->GetOwner()->HasFlag(wxDV_NO_HEADER)
+                            ? NSTableColumnAutoresizingMask
+                            : NSTableColumnNoResizing;
+    }
+    [nativeColumn setResizingMask:resizingMask];
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+    // setting the visibility:
+    [nativeColumn setHidden:static_cast<BOOL>(column->IsHidden())];
+#endif
+
+    wxDataViewRendererNativeData * const renderData = renderer->GetNativeData();
+
+    // setting the header:
+    [[nativeColumn headerCell] setAlignment:
+        ConvertToNativeHorizontalTextAlignment(column->GetAlignment())];
+    [[nativeColumn headerCell] setStringValue:
+        [[wxCFStringRef(column->GetTitle()).AsNSString() retain] autorelease]];
+    renderData->ApplyLineBreakMode([nativeColumn headerCell]);
+
+    // setting data cell's properties:
+    [[nativeColumn dataCell] setWraps:NO];
+    // setting the default data cell:
+    [nativeColumn setDataCell:renderData->GetColumnCell()];
+    // setting the editablility:
+    const bool isEditable = renderer->GetMode() == wxDATAVIEW_CELL_EDITABLE;
+
+    [nativeColumn setEditable:isEditable];
+    [[nativeColumn dataCell] setEditable:isEditable];
+
+    return nativeColumn;
 }
 
-@end
+} // anonymous namespace
+
+// ============================================================================
+// Public helper functions for dataview implementation on OSX
+// ============================================================================
+
+wxWidgetImplType* CreateDataView(wxWindowMac* wxpeer,
+                                 wxWindowMac* WXUNUSED(parent),
+                                 wxWindowID WXUNUSED(id),
+                                 const wxPoint& pos,
+                                 const wxSize& size,
+                                 long style,
+                                 long WXUNUSED(extraStyle))
+{
+    return new wxCocoaDataViewControl(wxpeer,pos,size,style);
+}
 
 // ============================================================================
 // wxSortDescriptorObject
 // ============================================================================
+
 @implementation wxSortDescriptorObject
-//
-// initialization
-//
 -(id) init
 {
-  self = [super init];
-  if (self != nil)
-  {
-    columnPtr = NULL;
-    modelPtr  = NULL;
-  }
-  return self;
+    self = [super init];
+    if (self != nil)
+    {
+        columnPtr = NULL;
+        modelPtr  = NULL;
+    }
+    return self;
 }
 
--(id) initWithModelPtr:(wxDataViewModel*)initModelPtr sortingColumnPtr:(wxDataViewColumn*)initColumnPtr ascending:(BOOL)sortAscending
+-(id)
+initWithModelPtr:(wxDataViewModel*)initModelPtr
+    sortingColumnPtr:(wxDataViewColumn*)initColumnPtr
+    ascending:(BOOL)sortAscending
 {
-  self = [super initWithKey:@"dummy" ascending:sortAscending];
-  if (self != nil)
-  {
-    columnPtr = initColumnPtr;
-    modelPtr  = initModelPtr;
-  }
-  return self;
+    self = [super initWithKey:@"dummy" ascending:sortAscending];
+    if (self != nil)
+    {
+        columnPtr = initColumnPtr;
+        modelPtr  = initModelPtr;
+    }
+    return self;
 }
 
 -(id) copyWithZone:(NSZone*)zone
 {
-  wxSortDescriptorObject* copy;
-  
-  
-  copy = [super copyWithZone:zone];
-  copy->columnPtr = columnPtr;
-  copy->modelPtr  = modelPtr;
+    wxSortDescriptorObject* copy;
 
-  return copy;
+
+    copy = [super copyWithZone:zone];
+    copy->columnPtr = columnPtr;
+    copy->modelPtr  = modelPtr;
+
+    return copy;
 }
 
 //
@@ -296,22 +459,22 @@ wxWidgetImplType* CreateDataView(wxWindowMac* wxpeer, wxWindowMac* WXUNUSED(pare
 //
 -(wxDataViewColumn*) columnPtr
 {
-  return columnPtr;
+    return columnPtr;
 }
 
 -(wxDataViewModel*) modelPtr
 {
-  return modelPtr;
+    return modelPtr;
 }
 
 -(void) setColumnPtr:(wxDataViewColumn*)newColumnPtr
 {
-  columnPtr = newColumnPtr;
+    columnPtr = newColumnPtr;
 }
 
 -(void) setModelPtr:(wxDataViewModel*)newModelPtr
 {
-  modelPtr = newModelPtr;
+    modelPtr = newModelPtr;
 }
 
 @end
@@ -326,500 +489,514 @@ wxWidgetImplType* CreateDataView(wxWindowMac* wxpeer, wxWindowMac* WXUNUSED(pare
 //
 -(id) init
 {
-  self = [super init];
-  if (self != nil)
-  {
-    implementation = NULL;
-    model          = NULL;
+    self = [super init];
+    if (self != nil)
+    {
+        implementation = NULL;
+        model          = NULL;
 
-    currentParentItem = nil;
+        currentParentItem = nil;
 
-    children = [[NSMutableArray alloc] init];
-    items    = [[NSMutableSet   alloc] init];
-  }
-  return self;
+        children = [[NSMutableArray alloc] init];
+        items    = [[NSMutableSet   alloc] init];
+    }
+    return self;
 }
 
 -(void) dealloc
 {
-  [currentParentItem release];
+    [currentParentItem release];
 
-  [children release];
-  [items    release];
-  
-  [super dealloc];
+    [children release];
+    [items    release];
+
+    [super dealloc];
 }
 
 //
 // methods of informal protocol:
 //
--(BOOL) outlineView:(NSOutlineView*)outlineView acceptDrop:(id<NSDraggingInfo>)info item:(id)item childIndex:(NSInteger)index
+-(BOOL)
+outlineView:(NSOutlineView*)outlineView
+    acceptDrop:(id<NSDraggingInfo>)info
+    item:(id)item childIndex:(NSInteger)index
 {
-  bool dragSuccessful;
+    wxUnusedVar(outlineView);
+    wxUnusedVar(index);
+    
+    NSArray* supportedTypes(
+        [NSArray arrayWithObjects:DataViewPboardType,NSStringPboardType,nil]
+    );
 
-  NSArray* supportedTypes([NSArray arrayWithObjects:DataViewPboardType,NSStringPboardType,nil]);
+    NSPasteboard* pasteboard([info draggingPasteboard]);
 
-  NSPasteboard* pasteboard([info draggingPasteboard]);
+    NSString* bestType([pasteboard availableTypeFromArray:supportedTypes]);
 
-  NSString* bestType([pasteboard availableTypeFromArray:supportedTypes]);
+    if ( bestType == nil )
+        return FALSE;
 
-  
-  if (bestType != nil)
-  {
-    wxDataViewCtrl* const  dataViewCtrlPtr(implementation->GetDataViewCtrl());
+    wxDataViewCtrl * const dvc(implementation->GetDataViewCtrl());
 
-    wxCHECK_MSG(dataViewCtrlPtr != NULL,            false,_("Pointer to data view control not set correctly."));
-    wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,false,_("Pointer to model not set correctly."));
-  // create wxWidget's event:
-    wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_DROP,dataViewCtrlPtr->GetId());
+    wxCHECK_MSG( dvc, false,
+                     "Pointer to data view control not set correctly." );
+    wxCHECK_MSG( dvc->GetModel(), false,
+                    "Pointer to model not set correctly." );
 
-    dataViewEvent.SetEventObject(dataViewCtrlPtr);
-    dataViewEvent.SetItem(wxDataViewItem([((wxPointerObject*) item) pointer]));
-    dataViewEvent.SetModel(dataViewCtrlPtr->GetModel());
-    if ([bestType compare:DataViewPboardType] == NSOrderedSame)
+    wxDataViewEvent event(wxEVT_DATAVIEW_ITEM_DROP, dvc->GetId());
+    event.SetEventObject(dvc);
+    event.SetItem(wxDataViewItemFromItem(item));
+    event.SetModel(dvc->GetModel());
+
+    BOOL dragSuccessful = false;
+    if ( [bestType compare:DataViewPboardType] == NSOrderedSame )
     {
-      NSArray*   dataArray((NSArray*)[pasteboard propertyListForType:DataViewPboardType]);
-      NSUInteger indexDraggedItem, noOfDraggedItems([dataArray count]);
-      
-      indexDraggedItem = 0;
-      while (indexDraggedItem < noOfDraggedItems)
-      {
-        wxDataObjectComposite* dataObjects(implementation->GetDnDDataObjects((NSData*)[dataArray objectAtIndex:indexDraggedItem]));
-
-        if ((dataObjects != NULL) && (dataObjects->GetFormatCount() > 0))
-        {
-          wxMemoryBuffer buffer;
-
-         // copy data into data object:
-          dataViewEvent.SetDataObject(dataObjects);
-          dataViewEvent.SetDataFormat(implementation->GetDnDDataFormat(dataObjects));
-         // copy data into buffer:
-          dataObjects->GetDataHere(dataViewEvent.GetDataFormat().GetType(),buffer.GetWriteBuf(dataViewEvent.GetDataSize()));
-          buffer.UngetWriteBuf(dataViewEvent.GetDataSize());
-          dataViewEvent.SetDataBuffer(buffer.GetData());
-         // finally, send event:
-          if (dataViewCtrlPtr->HandleWindowEvent(dataViewEvent) && dataViewEvent.IsAllowed())
-          {
-            dragSuccessful = true;
-            ++indexDraggedItem;
-          }
-          else
-          {
-            dragSuccessful   = true;
-            indexDraggedItem = noOfDraggedItems; // stop loop
-          }
-        }
-        else
+        NSArray* dataArray((NSArray*)
+                      [pasteboard propertyListForType:DataViewPboardType]);
+        NSUInteger indexDraggedItem, noOfDraggedItems([dataArray count]);
+
+        indexDraggedItem = 0;
+        while (indexDraggedItem < noOfDraggedItems)
         {
-          dragSuccessful   = false;
-          indexDraggedItem = noOfDraggedItems; // stop loop
+            wxDataObjectComposite* dataObjects(
+                implementation->GetDnDDataObjects((NSData*)
+                    [dataArray objectAtIndex:indexDraggedItem]));
+
+            if (dataObjects && (dataObjects->GetFormatCount() > 0))
+            {
+                wxMemoryBuffer buffer;
+
+                // copy data into data object:
+                event.SetDataObject(dataObjects);
+                event.SetDataFormat(
+                    implementation->GetDnDDataFormat(dataObjects));
+                // copy data into buffer:
+                dataObjects->GetDataHere(
+                    event.GetDataFormat().GetType(),
+                    buffer.GetWriteBuf(event.GetDataSize()));
+                buffer.UngetWriteBuf(event.GetDataSize());
+                event.SetDataBuffer(buffer.GetData());
+                // finally, send event:
+                if (dvc->HandleWindowEvent(event) && event.IsAllowed())
+                {
+                    dragSuccessful = true;
+                    ++indexDraggedItem;
+                }
+                else
+                {
+                    dragSuccessful   = true;
+                    indexDraggedItem = noOfDraggedItems; // stop loop
+                }
+            }
+            else
+            {
+                dragSuccessful   = false;
+                indexDraggedItem = noOfDraggedItems; // stop loop
+            }
+            // clean-up:
+            delete dataObjects;
         }
-       // clean-up:
-        delete dataObjects;
-      }
     }
     else
     {
-      CFDataRef              osxData; // needed to convert internally used UTF-16 representation to a UTF-8 representation
-      wxDataObjectComposite* dataObjects   (new wxDataObjectComposite());
-      wxTextDataObject*      textDataObject(new wxTextDataObject());
-      
-      osxData = ::CFStringCreateExternalRepresentation(kCFAllocatorDefault,(CFStringRef)[pasteboard stringForType:NSStringPboardType],kCFStringEncodingUTF8,32);
-      if (textDataObject->SetData(::CFDataGetLength(osxData),::CFDataGetBytePtr(osxData)))
-        dataObjects->Add(textDataObject);
-      else
-        delete textDataObject;
-     // send event if data could be copied:
-      if (dataObjects->GetFormatCount() > 0)
-      {
-        dataViewEvent.SetDataObject(dataObjects);
-        dataViewEvent.SetDataFormat(implementation->GetDnDDataFormat(dataObjects));
-        if (dataViewCtrlPtr->HandleWindowEvent(dataViewEvent) && dataViewEvent.IsAllowed())
-          dragSuccessful = true;
+        // needed to convert internally used UTF-16 representation to a UTF-8
+        // representation
+        CFDataRef              osxData;
+        wxDataObjectComposite* dataObjects   (new wxDataObjectComposite());
+        wxTextDataObject*      textDataObject(new wxTextDataObject());
+
+        osxData = ::CFStringCreateExternalRepresentation
+                    (
+                     kCFAllocatorDefault,
+                     (CFStringRef)[pasteboard stringForType:NSStringPboardType],
+                     kCFStringEncodingUTF8,
+                     32
+                    );
+        if (textDataObject->SetData(::CFDataGetLength(osxData),
+                                    ::CFDataGetBytePtr(osxData)))
+            dataObjects->Add(textDataObject);
+        else
+            delete textDataObject;
+        // send event if data could be copied:
+        if (dataObjects->GetFormatCount() > 0)
+        {
+            event.SetDataObject(dataObjects);
+            event.SetDataFormat(implementation->GetDnDDataFormat(dataObjects));
+            if (dvc->HandleWindowEvent(event) && event.IsAllowed())
+                dragSuccessful = true;
+            else
+                dragSuccessful = false;
+        }
         else
-          dragSuccessful = false;
-      }
-      else
-        dragSuccessful = false;
-     // clean up:
-      ::CFRelease(osxData);
-      delete dataObjects;
+            dragSuccessful = false;
+        // clean up:
+        ::CFRelease(osxData);
+        delete dataObjects;
     }
-  }
-  else
-    dragSuccessful = false;
-  return dragSuccessful;
+    return dragSuccessful;
 }
 
--(id) outlineView:(NSOutlineView*)outlineView child:(NSInteger)index ofItem:(id)item
+-(id) outlineView:(NSOutlineView*)outlineView
+    child:(NSInteger)index
+    ofItem:(id)item
 {
-  if ((item == currentParentItem) && (index < ((NSInteger) [self getChildCount])))
-    return [self getChild:index];
-  else
-  {
+    wxUnusedVar(outlineView);
+
+    if ((item == currentParentItem) &&
+            (index < ((NSInteger) [self getChildCount])))
+        return [self getChild:index];
+
     wxDataViewItemArray dataViewChildren;
 
-    wxCHECK_MSG(model != NULL,0,_("Valid model in data source does not exist."));
-    (void) model->GetChildren((item == nil) ? wxDataViewItem() : wxDataViewItem([((wxPointerObject*) item) pointer]),dataViewChildren);
+    wxCHECK_MSG( model, 0, "Valid model in data source does not exist." );
+    model->GetChildren(wxDataViewItemFromMaybeNilItem(item), dataViewChildren);
     [self bufferItem:item withChildren:&dataViewChildren];
     if ([sortDescriptors count] > 0)
-      [children sortUsingFunction:CompareItems context:sortDescriptors];
+        [children sortUsingFunction:CompareItems context:sortDescriptors];
     return [self getChild:index];
-  }
 }
 
 -(BOOL) outlineView:(NSOutlineView*)outlineView isItemExpandable:(id)item
 {
-  wxCHECK_MSG(model != NULL,0,_("Valid model in data source does not exist."));
-  return model->IsContainer(wxDataViewItem([((wxPointerObject*) item) pointer]));
+    wxUnusedVar(outlineView);
+
+    wxCHECK_MSG( model, 0, "Valid model in data source does not exist." );
+    return model->IsContainer(wxDataViewItemFromItem(item));
 }
 
 -(NSInteger) outlineView:(NSOutlineView*)outlineView numberOfChildrenOfItem:(id)item
 {
-  NSInteger noOfChildren;
+    wxUnusedVar(outlineView);
 
-  wxDataViewItemArray dataViewChildren;
+    NSInteger noOfChildren;
+
+    wxDataViewItemArray dataViewChildren;
 
 
-  wxCHECK_MSG(model != NULL,0,_("Valid model in data source does not exist."));
-  noOfChildren = model->GetChildren((item == nil) ? wxDataViewItem() : wxDataViewItem([((wxPointerObject*) item) pointer]),dataViewChildren);
-  [self bufferItem:item withChildren:&dataViewChildren];
-  if ([sortDescriptors count] > 0)
-    [children sortUsingFunction:CompareItems context:sortDescriptors];
-  return noOfChildren;
+    wxCHECK_MSG( model, 0, "Valid model in data source does not exist." );
+    noOfChildren = model->GetChildren(wxDataViewItemFromMaybeNilItem(item),
+                                      dataViewChildren);
+    [self bufferItem:item withChildren:&dataViewChildren];
+    if ([sortDescriptors count] > 0)
+        [children sortUsingFunction:CompareItems context:sortDescriptors];
+    return noOfChildren;
 }
 
--(id) outlineView:(NSOutlineView*)outlineView objectValueForTableColumn:(NSTableColumn*)tableColumn byItem:(id)item
+-(id)
+outlineView:(NSOutlineView*)outlineView
+    objectValueForTableColumn:(NSTableColumn*)tableColumn
+    byItem:(id)item
 {
-  wxDataViewColumn* dataViewColumnPtr(reinterpret_cast<wxDataViewColumn*>([[tableColumn identifier] pointer]));
+    wxUnusedVar(outlineView);
 
-  wxDataViewItem dataViewItem([((wxPointerObject*) item) pointer]);
+    wxCHECK_MSG( model, nil, "Valid model in data source does not exist." );
 
-  wxVariant value;
+    wxDataViewColumn* const
+        col([static_cast<wxDVCNSTableColumn*>(tableColumn) getColumnPointer]);
+    const unsigned colIdx = col->GetModelColumn();
 
+    wxDataViewItem dataViewItem(wxDataViewItemFromItem(item));
+
+    if ( model->HasValue(dataViewItem, colIdx) )
+    {
+        wxVariant value;
+        model->GetValue(value,dataViewItem, colIdx);
+        col->GetRenderer()->SetValue(value);
+    }
 
-  wxCHECK_MSG(model != NULL,0,_("Valid model in data source does not exist."));
-  model->GetValue(value,dataViewItem,dataViewColumnPtr->GetModelColumn());
-  dataViewColumnPtr->GetRenderer()->SetValue(value);
-  return nil;
+    return nil;
 }
 
--(void) outlineView:(NSOutlineView*)outlineView setObjectValue:(id)object forTableColumn:(NSTableColumn*)tableColumn byItem:(id)item
+-(void)
+outlineView:(NSOutlineView*)outlineView
+    setObjectValue:(id)object
+    forTableColumn:(NSTableColumn*)tableColumn
+    byItem:(id)item
 {
-  wxDataViewColumn* dataViewColumnPtr(reinterpret_cast<wxDataViewColumn*>([[tableColumn identifier] pointer]));
-
-  wxDataViewItem dataViewItem([((wxPointerObject*) item) pointer]);
+    wxUnusedVar(outlineView);
 
+    wxDataViewColumn* const
+        col([static_cast<wxDVCNSTableColumn*>(tableColumn) getColumnPointer]);
 
-  if (((dynamic_cast<wxDataViewTextRenderer*>(dataViewColumnPtr->GetRenderer()) != NULL) || (dynamic_cast<wxDataViewIconTextRenderer*>(dataViewColumnPtr->GetRenderer()) != NULL)) &&
-      ([object isKindOfClass:[NSString class]] == YES))
-  {
-    model->SetValue(wxVariant(wxCFStringRef([((NSString*) object) retain]).AsString()),dataViewItem,dataViewColumnPtr->GetModelColumn()); // the string has to be retained before being passed to wxCFStringRef
-    model->ValueChanged(dataViewItem,dataViewColumnPtr->GetModelColumn());
-  }
-  else if (dynamic_cast<wxDataViewChoiceRenderer*>(dataViewColumnPtr->GetRenderer()) != NULL)
-  {
-    if ([object isKindOfClass:[NSNumber class]] == YES)
-    {
-      model->SetValue(wxVariant(dynamic_cast<wxDataViewChoiceRenderer*>(dataViewColumnPtr->GetRenderer())->GetChoice([((NSNumber*) object) intValue])),
-                      dataViewItem,dataViewColumnPtr->GetModelColumn());
-      model->ValueChanged(dataViewItem,dataViewColumnPtr->GetModelColumn());
-    }
-    else if ([object isKindOfClass:[NSString class]] == YES) // do not know if this case can occur but initializing using strings works
-    {
-      model->SetValue(wxVariant(wxCFStringRef((NSString*) object).AsString()),dataViewItem,dataViewColumnPtr->GetModelColumn());
-      model->ValueChanged(dataViewItem,dataViewColumnPtr->GetModelColumn());
-    }
-  }
-  else if ((dynamic_cast<wxDataViewDateRenderer*>(dataViewColumnPtr->GetRenderer()) != NULL) && ([object isKindOfClass:[NSDate class]] == YES))
-  {
-    wxDateTime wxDateTimeValue(1,wxDateTime::Jan,1970);
-
-    wxLongLong seconds;
-
-    seconds.Assign([((NSDate*) object) timeIntervalSince1970]); // get the number of seconds since 1970-01-01 UTC and this is
-                                                                // the only way to convert a double to a wxLongLong
-   // the user has entered a date in the local timezone but seconds contains the number of seconds from date in the local timezone since 1970-01-01 UTC;
-   // therefore, the timezone information has to be transferred to wxWidgets, too:
-    wxDateTimeValue.Add(wxTimeSpan(0,0,seconds));
-    wxDateTimeValue.MakeFromTimezone(wxDateTime::UTC);
-    model->SetValue(wxVariant(wxDateTimeValue),dataViewItem,dataViewColumnPtr->GetModelColumn());
-    model->ValueChanged(dataViewItem,dataViewColumnPtr->GetModelColumn());
-  }
-  else if ((dynamic_cast<wxDataViewToggleRenderer*>(dataViewColumnPtr->GetRenderer()) != NULL) && ([object isKindOfClass:[NSNumber class]] == YES))
-  {
-    model->SetValue(wxVariant((bool) [((NSNumber*) object) boolValue]),dataViewItem,dataViewColumnPtr->GetModelColumn());
-    model->ValueChanged(dataViewItem,dataViewColumnPtr->GetModelColumn());
-  }
+    col->GetRenderer()->
+        OSXOnCellChanged(object, wxDataViewItemFromItem(item), col->GetModelColumn());
 }
 
 -(void) outlineView:(NSOutlineView*)outlineView sortDescriptorsDidChange:(NSArray*)oldDescriptors
- // Warning: the new sort descriptors are guaranteed to be only of type NSSortDescriptor! Therefore, the
- // sort descriptors for the data source have to be converted.
 {
-  NSArray* newDescriptors;
+    wxUnusedVar(oldDescriptors);
+    
+    // Warning: the new sort descriptors are guaranteed to be only of type
+    // NSSortDescriptor! Therefore, the sort descriptors for the data source
+    // have to be converted.
+    NSArray* newDescriptors;
+
+    NSMutableArray* wxSortDescriptors;
 
-  NSMutableArray* wxSortDescriptors;
-  
-  NSUInteger noOfDescriptors;
+    NSUInteger noOfDescriptors;
 
-  wxDataViewCtrl* const dataViewCtrlPtr = implementation->GetDataViewCtrl();
+    wxDataViewCtrl* const dvc = implementation->GetDataViewCtrl();
 
 
- // convert NSSortDescriptors to wxSortDescriptorObjects:
-  newDescriptors    = [outlineView sortDescriptors];
-  noOfDescriptors   = [newDescriptors count];
-  wxSortDescriptors = [NSMutableArray arrayWithCapacity:noOfDescriptors];
-  for (NSUInteger i=0; i<noOfDescriptors; ++i)
-  {
-   // constant definition for abbreviational purposes:
-    NSSortDescriptor* const newDescriptor = [newDescriptors objectAtIndex:i];
+    // convert NSSortDescriptors to wxSortDescriptorObjects:
+    newDescriptors    = [outlineView sortDescriptors];
+    noOfDescriptors   = [newDescriptors count];
+    wxSortDescriptors = [NSMutableArray arrayWithCapacity:noOfDescriptors];
+    for (NSUInteger i=0; i<noOfDescriptors; ++i)
+    {
+        NSSortDescriptor* const newDescriptor = [newDescriptors objectAtIndex:i];
 
-    [wxSortDescriptors addObject:[[[wxSortDescriptorObject alloc] initWithModelPtr:model
-                                                                  sortingColumnPtr:dataViewCtrlPtr->GetColumn([[newDescriptor key] intValue])
-                                                                         ascending:[newDescriptor ascending]] autorelease]];
-  }
-  [[outlineView dataSource] setSortDescriptors:wxSortDescriptors];
+        [wxSortDescriptors addObject:[[[wxSortDescriptorObject alloc] initWithModelPtr:model
+            sortingColumnPtr:dvc->GetColumn([[newDescriptor key] intValue])
+            ascending:[newDescriptor ascending]] autorelease]];
+    }
+    [(wxCocoaOutlineDataSource*)[outlineView dataSource] setSortDescriptors:wxSortDescriptors];
 
- // send first the event to wxWidgets that the sorting has changed so that the program can do special actions before
// the sorting actually starts:
-  wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_COLUMN_SORTED,dataViewCtrlPtr->GetId()); // variable defintion
+    // send first the event to wxWidgets that the sorting has changed so that
   // the program can do special actions before the sorting actually starts:
+    wxDataViewEvent event(wxEVT_DATAVIEW_COLUMN_SORTED,dvc->GetId()); // variable definition
 
-  dataViewEvent.SetEventObject(dataViewCtrlPtr);
-  if (noOfDescriptors > 0)
-  {
-   // constant definition for abbreviational purposes:
-    wxDataViewColumn* const dataViewColumnPtr = [[wxSortDescriptors objectAtIndex:0] columnPtr];
+    event.SetEventObject(dvc);
+    if (noOfDescriptors > 0)
+    {
+        wxDataViewColumn* const col = [[wxSortDescriptors objectAtIndex:0] columnPtr];
 
-    dataViewEvent.SetColumn(dataViewCtrlPtr->GetColumnPosition(dataViewColumnPtr));
-    dataViewEvent.SetDataViewColumn(dataViewColumnPtr);
-  }
-  dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
+        event.SetColumn(dvc->GetColumnPosition(col));
+        event.SetDataViewColumn(col);
+    }
+    dvc->GetEventHandler()->ProcessEvent(event);
 
- // start re-ordering the data;
- // children's buffer must be cleared first because it contains the old order:
-  [self clearChildren];
- // sorting is done while reloading the data:
-  [outlineView reloadData];
   // start re-ordering the data;
   // children's buffer must be cleared first because it contains the old order:
+    [self clearChildren];
   // sorting is done while reloading the data:
+    [outlineView reloadData];
 }
 
 -(NSDragOperation) outlineView:(NSOutlineView*)outlineView validateDrop:(id<NSDraggingInfo>)info proposedItem:(id)item proposedChildIndex:(NSInteger)index
 {
-  NSArray* supportedTypes([NSArray arrayWithObjects:DataViewPboardType,NSStringPboardType,nil]);
+    wxUnusedVar(outlineView);
+    wxUnusedVar(index);
 
-  NSDragOperation dragOperation;
+    NSArray* supportedTypes([NSArray arrayWithObjects:DataViewPboardType,NSStringPboardType,nil]);
 
-  NSPasteboard* pasteboard([info draggingPasteboard]);
+    NSPasteboard* pasteboard([info draggingPasteboard]);
 
-  NSString* bestType([pasteboard availableTypeFromArray:supportedTypes]);
+    NSString* bestType([pasteboard availableTypeFromArray:supportedTypes]);
+    if (bestType == nil)
+        return NSDragOperationNone;
 
-  
-  if (bestType != nil)
-  {
-    wxDataViewCtrl* const  dataViewCtrlPtr(implementation->GetDataViewCtrl());
+    NSDragOperation dragOperation = NSDragOperationNone;
+    wxDataViewCtrl* const dvc(implementation->GetDataViewCtrl());
 
-    wxCHECK_MSG(dataViewCtrlPtr != NULL,            false,_("Pointer to data view control not set correctly."));
-    wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,false,_("Pointer to model not set correctly."));
-  // create wxWidget's event:
-    wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_DROP_POSSIBLE,dataViewCtrlPtr->GetId());
+    wxCHECK_MSG(dvc, false, "Pointer to data view control not set correctly.");
+    wxCHECK_MSG(dvc->GetModel(), false, "Pointer to model not set correctly.");
 
-    dataViewEvent.SetEventObject(dataViewCtrlPtr);
-    dataViewEvent.SetItem(wxDataViewItem([((wxPointerObject*) item) pointer]));
-    dataViewEvent.SetModel(dataViewCtrlPtr->GetModel());
+    wxDataViewEvent
+        event(wxEVT_DATAVIEW_ITEM_DROP_POSSIBLE,dvc->GetId());
+
+    event.SetEventObject(dvc);
+    event.SetItem(wxDataViewItemFromItem(item));
+    event.SetModel(dvc->GetModel());
     if ([bestType compare:DataViewPboardType] == NSOrderedSame)
     {
-      NSArray*               dataArray((NSArray*)[pasteboard propertyListForType:DataViewPboardType]);
-      NSUInteger             indexDraggedItem, noOfDraggedItems([dataArray count]);
-      
-      indexDraggedItem = 0;
-      while (indexDraggedItem < noOfDraggedItems)
-      {
-        wxDataObjectComposite* dataObjects(implementation->GetDnDDataObjects((NSData*)[dataArray objectAtIndex:indexDraggedItem]));
-
-        if ((dataObjects != NULL) && (dataObjects->GetFormatCount() > 0))
-        {
-          wxMemoryBuffer buffer;
-
-         // copy data into data object:
-          dataViewEvent.SetDataObject(dataObjects);
-          dataViewEvent.SetDataFormat(implementation->GetDnDDataFormat(dataObjects));
-         // copy data into buffer:
-          dataObjects->GetDataHere(dataViewEvent.GetDataFormat().GetType(),buffer.GetWriteBuf(dataViewEvent.GetDataSize()));
-          buffer.UngetWriteBuf(dataViewEvent.GetDataSize());
-          dataViewEvent.SetDataBuffer(buffer.GetData());
-         // finally, send event:
-          if (dataViewCtrlPtr->HandleWindowEvent(dataViewEvent) && dataViewEvent.IsAllowed())
-          {
-            dragOperation = NSDragOperationEvery;
-            ++indexDraggedItem;
-          }
-          else
-          {
-            dragOperation    = NSDragOperationNone;
-            indexDraggedItem = noOfDraggedItems; // stop loop
-          }
-        }
-        else
+        NSArray*               dataArray((NSArray*)[pasteboard propertyListForType:DataViewPboardType]);
+        NSUInteger             indexDraggedItem, noOfDraggedItems([dataArray count]);
+
+        indexDraggedItem = 0;
+        while (indexDraggedItem < noOfDraggedItems)
         {
-          dragOperation    = NSDragOperationNone;
-          indexDraggedItem = noOfDraggedItems; // stop loop
+            wxDataObjectComposite* dataObjects(implementation->GetDnDDataObjects((NSData*)[dataArray objectAtIndex:indexDraggedItem]));
+
+            if (dataObjects && (dataObjects->GetFormatCount() > 0))
+            {
+                wxMemoryBuffer buffer;
+
+                // copy data into data object:
+                event.SetDataObject(dataObjects);
+                event.SetDataFormat(implementation->GetDnDDataFormat(dataObjects));
+                // copy data into buffer:
+                dataObjects->GetDataHere(event.GetDataFormat().GetType(),buffer.GetWriteBuf(event.GetDataSize()));
+                buffer.UngetWriteBuf(event.GetDataSize());
+                event.SetDataBuffer(buffer.GetData());
+                // finally, send event:
+                if (dvc->HandleWindowEvent(event) && event.IsAllowed())
+                {
+                    dragOperation = NSDragOperationEvery;
+                    ++indexDraggedItem;
+                }
+                else
+                {
+                    dragOperation    = NSDragOperationNone;
+                    indexDraggedItem = noOfDraggedItems; // stop loop
+                }
+            }
+            else
+            {
+                dragOperation    = NSDragOperationNone;
+                indexDraggedItem = noOfDraggedItems; // stop loop
+            }
+            // clean-up:
+            delete dataObjects;
         }
-       // clean-up:
-        delete dataObjects;
-      }
     }
     else
     {
-      CFDataRef              osxData; // needed to convert internally used UTF-16 representation to a UTF-8 representation
-      wxDataObjectComposite* dataObjects   (new wxDataObjectComposite());
-      wxTextDataObject*      textDataObject(new wxTextDataObject());
-      
-      osxData = ::CFStringCreateExternalRepresentation(kCFAllocatorDefault,(CFStringRef)[pasteboard stringForType:NSStringPboardType],kCFStringEncodingUTF8,32);
-      if (textDataObject->SetData(::CFDataGetLength(osxData),::CFDataGetBytePtr(osxData)))
-        dataObjects->Add(textDataObject);
-      else
-        delete textDataObject;
-     // send event if data could be copied:
-      if (dataObjects->GetFormatCount() > 0)
-      {
-        dataViewEvent.SetDataObject(dataObjects);
-        dataViewEvent.SetDataFormat(implementation->GetDnDDataFormat(dataObjects));
-        if (dataViewCtrlPtr->HandleWindowEvent(dataViewEvent) && dataViewEvent.IsAllowed())
-          dragOperation = NSDragOperationEvery;
+        // needed to convert internally used UTF-16 representation to a UTF-8
+        // representation
+        CFDataRef              osxData;
+        wxDataObjectComposite* dataObjects   (new wxDataObjectComposite());
+        wxTextDataObject*      textDataObject(new wxTextDataObject());
+
+        osxData = ::CFStringCreateExternalRepresentation(kCFAllocatorDefault,(CFStringRef)[pasteboard stringForType:NSStringPboardType],kCFStringEncodingUTF8,32);
+        if (textDataObject->SetData(::CFDataGetLength(osxData),::CFDataGetBytePtr(osxData)))
+            dataObjects->Add(textDataObject);
+        else
+            delete textDataObject;
+        // send event if data could be copied:
+        if (dataObjects->GetFormatCount() > 0)
+        {
+            event.SetDataObject(dataObjects);
+            event.SetDataFormat(implementation->GetDnDDataFormat(dataObjects));
+            if (dvc->HandleWindowEvent(event) && event.IsAllowed())
+                dragOperation = NSDragOperationEvery;
+            else
+                dragOperation = NSDragOperationNone;
+        }
         else
-          dragOperation = NSDragOperationNone;
-      }
-      else
-        dragOperation = NSDragOperationNone;
-     // clean up:
-      ::CFRelease(osxData);
-      delete dataObjects;
+            dragOperation = NSDragOperationNone;
+        // clean up:
+        ::CFRelease(osxData);
+        delete dataObjects;
     }
-  }
-  else
-    dragOperation = NSDragOperationNone;
-  return dragOperation;
+
+    return dragOperation;
 }
 
 -(BOOL) outlineView:(NSOutlineView*)outlineView writeItems:(NSArray*)writeItems toPasteboard:(NSPasteboard*)pasteboard
- // the pasteboard will be filled up with an array containing the data as returned by the events (including the data type)
- // and a concatenation of text (string) data; the text data will only be put onto the pasteboard if for all items a
- // string representation exists
 {
-  wxDataViewCtrl* const dataViewCtrlPtr = implementation->GetDataViewCtrl();
-  
-  wxDataViewItemArray dataViewItems;
+    wxUnusedVar(outlineView);
 
+    // the pasteboard will be filled up with an array containing the data as
+    // returned by the events (including the data type) and a concatenation of
+    // text (string) data; the text data will only be put onto the pasteboard
+    // if for all items a string representation exists
+    wxDataViewCtrl* const dvc = implementation->GetDataViewCtrl();
 
-  wxCHECK_MSG(dataViewCtrlPtr != NULL,            false,_("Pointer to data view control not set correctly."));
-  wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,false,_("Pointer to model not set correctly."));
+    wxDataViewItemArray dataViewItems;
 
-  if ([writeItems count] > 0)
-  {
-    bool            dataStringAvailable(true); // a flag indicating if for all items a data string is available
-    NSMutableArray* dataArray = [[NSMutableArray arrayWithCapacity:[writeItems count]] retain]; // data of all items
-    wxString        dataString; // contains the string data of all items
 
-   // send a begin drag event for all selected items and proceed with dragging unless the event is vetoed:
-    wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_BEGIN_DRAG,dataViewCtrlPtr->GetId());
+    wxCHECK_MSG(dvc, false,"Pointer to data view control not set correctly.");
+    wxCHECK_MSG(dvc->GetModel(),false,"Pointer to model not set correctly.");
 
-    dataViewEvent.SetEventObject(dataViewCtrlPtr);
-    dataViewEvent.SetModel(dataViewCtrlPtr->GetModel());
-    for (size_t itemCounter=0; itemCounter<[writeItems count]; ++itemCounter)
+    if ([writeItems count] > 0)
     {
-      bool                   itemStringAvailable(false);              // a flag indicating if for the current item a string is available
-      wxDataObjectComposite* itemObject(new wxDataObjectComposite()); // data object for current item
-      wxString               itemString;                              // contains the TAB concatenated data of an item
-
-      dataViewEvent.SetItem(wxDataViewItem([((wxPointerObject*) [writeItems objectAtIndex:itemCounter]) pointer]));
-      itemString = ::ConcatenateDataViewItemValues(dataViewCtrlPtr,dataViewEvent.GetItem());
-      itemObject->Add(new wxTextDataObject(itemString));
-      dataViewEvent.SetDataObject(itemObject);
-     // check if event has not been vetoed:
-      if (dataViewCtrlPtr->HandleWindowEvent(dataViewEvent) && dataViewEvent.IsAllowed() && (dataViewEvent.GetDataObject()->GetFormatCount() > 0))
-      {
-       // constant definition for abbreviational purposes:
-        size_t const noOfFormats = dataViewEvent.GetDataObject()->GetFormatCount();
-       // variable definition and initialization:
-        wxDataFormat* dataFormats(new wxDataFormat[noOfFormats]);
-
-        dataViewEvent.GetDataObject()->GetAllFormats(dataFormats,wxDataObject::Get);
-        for (size_t formatCounter=0; formatCounter<noOfFormats; ++formatCounter)
+        bool            dataStringAvailable(true); // a flag indicating if for all items a data string is available
+        NSMutableArray* dataArray = [NSMutableArray arrayWithCapacity:[writeItems count]]; // data of all items
+        wxString        dataString; // contains the string data of all items
+
+        // send a begin drag event for all selected items and proceed with
+        // dragging unless the event is vetoed:
+        wxDataViewEvent
+            event(wxEVT_DATAVIEW_ITEM_BEGIN_DRAG,dvc->GetId());
+
+        event.SetEventObject(dvc);
+        event.SetModel(dvc->GetModel());
+        for (size_t itemCounter=0; itemCounter<[writeItems count]; ++itemCounter)
         {
-         // constant definitions for abbreviational purposes:
-          wxDataFormatId const idDataFormat = dataFormats[formatCounter].GetType();
-          size_t const dataSize       = dataViewEvent.GetDataObject()->GetDataSize(idDataFormat);
-          size_t const dataBufferSize = sizeof(wxDataFormatId)+dataSize;
-         // variable definitions (used in all case statements):
-          wxMemoryBuffer dataBuffer(dataBufferSize);
-          
-          dataBuffer.AppendData(&idDataFormat,sizeof(wxDataFormatId));
-          switch (idDataFormat)
-          {
-            case wxDF_TEXT:
-              if (!itemStringAvailable) // otherwise wxDF_UNICODETEXT already filled up the string; and the UNICODE representation has priority
-              {
-                dataViewEvent.GetDataObject()->GetDataHere(wxDF_TEXT,dataBuffer.GetAppendBuf(dataSize));
-                dataBuffer.UngetAppendBuf(dataSize);
-                [dataArray addObject:[NSData dataWithBytes:dataBuffer.GetData() length:dataBufferSize]];
-                itemString = wxString(reinterpret_cast<char const*>(dataBuffer.GetData())+sizeof(wxDataFormatId),wxConvLocal);
-                itemStringAvailable = true;
-              }
-              break;
-            case wxDF_UNICODETEXT:
-              {
-                dataViewEvent.GetDataObject()->GetDataHere(wxDF_UNICODETEXT,dataBuffer.GetAppendBuf(dataSize));
-                dataBuffer.UngetAppendBuf(dataSize);
-                if (itemStringAvailable) // does an object already exist as an ASCII text (see wxDF_TEXT case statement)?
-                  [dataArray replaceObjectAtIndex:itemCounter withObject:[NSData dataWithBytes:dataBuffer.GetData() length:dataBufferSize]];
-                else
-                  [dataArray addObject:[NSData dataWithBytes:dataBuffer.GetData() length:dataBufferSize]];
-                itemString = wxString::FromUTF8(reinterpret_cast<char const*>(dataBuffer.GetData())+sizeof(wxDataFormatId),dataSize);
-                itemStringAvailable = true;
-              } /* block */
-              break;
-            default:
-              wxFAIL_MSG(_("Data object has invalid or unsupported data format"));
-              [dataArray release];
-              return NO;
-          }
+            bool                   itemStringAvailable(false);              // a flag indicating if for the current item a string is available
+            wxDataObjectComposite* itemObject(new wxDataObjectComposite()); // data object for current item
+            wxString               itemString;                              // contains the TAB concatenated data of an item
+
+            event.SetItem(
+                wxDataViewItemFromItem([writeItems objectAtIndex:itemCounter]));
+            itemString = ::ConcatenateDataViewItemValues(dvc,event.GetItem());
+            itemObject->Add(new wxTextDataObject(itemString));
+            event.SetDataObject(itemObject);
+            // check if event has not been vetoed:
+            if (dvc->HandleWindowEvent(event) && event.IsAllowed() && (event.GetDataObject()->GetFormatCount() > 0))
+            {
+                size_t const noOfFormats = event.GetDataObject()->GetFormatCount();
+                wxDataFormat* dataFormats(new wxDataFormat[noOfFormats]);
+
+                event.GetDataObject()->GetAllFormats(dataFormats,wxDataObject::Get);
+                for (size_t formatCounter=0; formatCounter<noOfFormats; ++formatCounter)
+                {
+                    // constant definitions for abbreviational purposes:
+                    wxDataFormatId const idDataFormat = dataFormats[formatCounter].GetType();
+                    size_t const dataSize       = event.GetDataObject()->GetDataSize(idDataFormat);
+                    size_t const dataBufferSize = sizeof(wxDataFormatId)+dataSize;
+                    // variable definitions (used in all case statements):
+                    // give additional headroom for trailing NULL
+                    wxMemoryBuffer dataBuffer(dataBufferSize+4);
+
+                    dataBuffer.AppendData(&idDataFormat,sizeof(wxDataFormatId));
+                    switch (idDataFormat)
+                    {
+                        case wxDF_TEXT:
+                            // otherwise wxDF_UNICODETEXT already filled up
+                            // the string; and the UNICODE representation has
+                            // priority
+                            if (!itemStringAvailable)
+                            {
+                                event.GetDataObject()->GetDataHere(wxDF_TEXT,dataBuffer.GetAppendBuf(dataSize));
+                                dataBuffer.UngetAppendBuf(dataSize);
+                                [dataArray addObject:[NSData dataWithBytes:dataBuffer.GetData() length:dataBufferSize]];
+                                itemString = wxString(static_cast<char const*>(dataBuffer.GetData())+sizeof(wxDataFormatId),wxConvLocal);
+                                itemStringAvailable = true;
+                            }
+                            break;
+                        case wxDF_UNICODETEXT:
+                            {
+                                event.GetDataObject()->GetDataHere(wxDF_UNICODETEXT,dataBuffer.GetAppendBuf(dataSize));
+                                dataBuffer.UngetAppendBuf(dataSize);
+                                if (itemStringAvailable) // does an object already exist as an ASCII text (see wxDF_TEXT case statement)?
+                                    [dataArray replaceObjectAtIndex:itemCounter withObject:[NSData dataWithBytes:dataBuffer.GetData() length:dataBufferSize]];
+                                else
+                                    [dataArray addObject:[NSData dataWithBytes:dataBuffer.GetData() length:dataBufferSize]];
+                                itemString = wxString::FromUTF8(static_cast<char const*>(dataBuffer.GetData())+sizeof(wxDataFormatId),dataSize);
+                                itemStringAvailable = true;
+                            } /* block */
+                            break;
+                        default:
+                            wxFAIL_MSG("Data object has invalid or unsupported data format");
+                            return NO;
+                    }
+                }
+                delete[] dataFormats;
+                delete itemObject;
+                if (dataStringAvailable)
+                    if (itemStringAvailable)
+                    {
+                        if (itemCounter > 0)
+                            dataString << wxT('\n');
+                        dataString << itemString;
+                    }
+                    else
+                        dataStringAvailable = false;
+            }
+            else
+            {
+                delete itemObject;
+                return NO; // dragging was vetoed or no data available
+            }
         }
-        delete[] dataFormats;
-        delete itemObject;
         if (dataStringAvailable)
-          if (itemStringAvailable)
-          {
-            if (itemCounter > 0)
-              dataString << wxT('\n');
-            dataString << itemString;
-          }
-          else
-            dataStringAvailable = false;
-      }
-      else
-      {
-        [dataArray release];
-        delete itemObject;
-        return NO; // dragging was vetoed or no data available
-      }
-    }
-    if (dataStringAvailable)
-    {
-      wxCFStringRef osxString(dataString);
-      
-      [pasteboard declareTypes:[NSArray arrayWithObjects:DataViewPboardType,NSStringPboardType,nil] owner:nil];
-      [pasteboard setPropertyList:dataArray forType:DataViewPboardType];
-      [pasteboard setString:osxString.AsNSString() forType:NSStringPboardType];
+        {
+            wxCFStringRef osxString(dataString);
+
+            [pasteboard declareTypes:[NSArray arrayWithObjects:DataViewPboardType,NSStringPboardType,nil] owner:nil];
+            [pasteboard setPropertyList:dataArray forType:DataViewPboardType];
+            [pasteboard setString:osxString.AsNSString() forType:NSStringPboardType];
+        }
+        else
+        {
+            [pasteboard declareTypes:[NSArray arrayWithObject:DataViewPboardType] owner:nil];
+            [pasteboard setPropertyList:dataArray forType:DataViewPboardType];
+        }
+        return YES;
     }
     else
-    {
-      [pasteboard declareTypes:[NSArray arrayWithObject:DataViewPboardType] owner:nil];
-      [pasteboard setPropertyList:dataArray forType:DataViewPboardType];
-    }
-    return YES;
-  }
-  else
-    return NO; // no items to drag (should never occur)
+        return NO; // no items to drag (should never occur)
 }
 
 //
@@ -827,32 +1004,32 @@ wxWidgetImplType* CreateDataView(wxWindowMac* wxpeer, wxWindowMac* WXUNUSED(pare
 //
 -(void) addToBuffer:(wxPointerObject*)item
 {
-  [items addObject:item];
+    [items addObject:item];
 }
 
 -(void) clearBuffer
 {
-  [items removeAllObjects];
+    [items removeAllObjects];
 }
 
--(wxPointerObject*) getDataViewItemFromBuffer:(wxDataViewItem const&)item
+-(wxPointerObject*) getDataViewItemFromBuffer:(const wxDataViewItem&)item
 {
-  return [items member:[[[wxPointerObject alloc] initWithPointer:item.GetID()] autorelease]];
+    return [items member:[[[wxPointerObject alloc] initWithPointer:item.GetID()] autorelease]];
 }
 
 -(wxPointerObject*) getItemFromBuffer:(wxPointerObject*)item
 {
-  return [items member:item];
+    return [items member:item];
 }
 
 -(BOOL) isInBuffer:(wxPointerObject*)item
 {
-  return [items containsObject:item];
+    return [items containsObject:item];
 }
 
 -(void) removeFromBuffer:(wxPointerObject*)item
 {
-  [items removeObject:item];
+    [items removeObject:item];
 }
 
 //
@@ -860,27 +1037,27 @@ wxWidgetImplType* CreateDataView(wxWindowMac* wxpeer, wxWindowMac* WXUNUSED(pare
 //
 -(void) appendChild:(wxPointerObject*)item
 {
-  [children addObject:item];
+    [children addObject:item];
 }
 
 -(void) clearChildren
 {
-  [children removeAllObjects];
+    [children removeAllObjects];
 }
 
 -(wxPointerObject*) getChild:(NSUInteger)index
 {
-  return [children objectAtIndex:index];
+    return [children objectAtIndex:index];
 }
 
 -(NSUInteger) getChildCount
 {
-  return [children count];
+    return [children count];
 }
 
 -(void) removeChild:(NSUInteger)index
 {
-  [children removeObjectAtIndex:index];
+    [children removeObjectAtIndex:index];
 }
 
 //
@@ -888,9 +1065,9 @@ wxWidgetImplType* CreateDataView(wxWindowMac* wxpeer, wxWindowMac* WXUNUSED(pare
 //
 -(void) clearBuffers
 {
-  [self clearBuffer];
-  [self clearChildren];
-  [self setCurrentParentItem:nil];
+    [self clearBuffer];
+    [self clearChildren];
+    [self setCurrentParentItem:nil];
 }
 
 //
@@ -898,14 +1075,14 @@ wxWidgetImplType* CreateDataView(wxWindowMac* wxpeer, wxWindowMac* WXUNUSED(pare
 //
 -(NSArray*) sortDescriptors
 {
-  return sortDescriptors;
+    return sortDescriptors;
 }
 
 -(void) setSortDescriptors:(NSArray*)newSortDescriptors
 {
-  [newSortDescriptors retain];
-  [sortDescriptors release];
-  sortDescriptors = newSortDescriptors;
+    [newSortDescriptors retain];
+    [sortDescriptors release];
+    sortDescriptors = newSortDescriptors;
 }
 
 //
@@ -913,34 +1090,34 @@ wxWidgetImplType* CreateDataView(wxWindowMac* wxpeer, wxWindowMac* WXUNUSED(pare
 //
 -(wxPointerObject*) currentParentItem
 {
-  return currentParentItem;
+    return currentParentItem;
 }
 
 -(wxCocoaDataViewControl*) implementation
 {
-  return implementation;
+    return implementation;
 }
 
 -(wxDataViewModel*) model
 {
-  return model;
+    return model;
 }
 
 -(void) setCurrentParentItem:(wxPointerObject*)newCurrentParentItem
 {
-  [newCurrentParentItem retain];
-  [currentParentItem release];
-  currentParentItem = newCurrentParentItem;
+    [newCurrentParentItem retain];
+    [currentParentItem release];
+    currentParentItem = newCurrentParentItem;
 }
 
 -(void) setImplementation:(wxCocoaDataViewControl*) newImplementation
 {
-  implementation = newImplementation;
+    implementation = newImplementation;
 }
 
 -(void) setModel:(wxDataViewModel*) newModel
 {
-  model = newModel;
+    model = newModel;
 }
 
 //
@@ -948,32 +1125,37 @@ wxWidgetImplType* CreateDataView(wxWindowMac* wxpeer, wxWindowMac* WXUNUSED(pare
 //
 -(void) bufferItem:(wxPointerObject*)parentItem withChildren:(wxDataViewItemArray*)dataViewChildrenPtr
 {
-  NSInteger const noOfChildren = (*dataViewChildrenPtr).GetCount();
-
-  [self setCurrentParentItem:parentItem];
-  [self clearChildren];
-  for (NSInteger indexChild=0; indexChild<noOfChildren; ++indexChild)
-  {
-    wxPointerObject* bufferedPointerObject;
-    wxPointerObject* newPointerObject([[wxPointerObject alloc] initWithPointer:(*dataViewChildrenPtr)[indexChild].GetID()]);
-
-   // The next statement and test looks strange but there is unfortunately no workaround:
-   // due to the fact that two pointer objects are identical if their pointers are identical - because the method isEqual
-   // has been overloaded - the set operation will only add a new pointer object if there is not already one in the set
-   // having the same pointer. On the other side the children's array would always add the new pointer object. This means
-   // that different pointer objects are stored in the set and array. This will finally lead to a crash as objects diverge.
-   // To solve this issue it is first tested if the child already exists in the set and if it is the case the sets object
-   // is going to be appended to the array, otheriwse the new pointer object is added to the set and array:
-    bufferedPointerObject = [self getItemFromBuffer:newPointerObject];
-    if (bufferedPointerObject == nil)
+    NSInteger const noOfChildren = (*dataViewChildrenPtr).GetCount();
+
+    [self setCurrentParentItem:parentItem];
+    [self clearChildren];
+    for (NSInteger indexChild=0; indexChild<noOfChildren; ++indexChild)
     {
-      [items    addObject:newPointerObject];
-      [children addObject:newPointerObject];
+        wxPointerObject* bufferedPointerObject;
+        wxPointerObject* newPointerObject([[wxPointerObject alloc] initWithPointer:(*dataViewChildrenPtr)[indexChild].GetID()]);
+
+        // The next statement and test looks strange but there is
+        // unfortunately no workaround: due to the fact that two pointer
+        // objects are identical if their pointers are identical - because the
+        // method isEqual has been overloaded - the set operation will only
+        // add a new pointer object if there is not already one in the set
+        // having the same pointer. On the other side the children's array
+        // would always add the new pointer object. This means that different
+        // pointer objects are stored in the set and array. This will finally
+        // lead to a crash as objects diverge. To solve this issue it is first
+        // tested if the child already exists in the set and if it is the case
+        // the sets object is going to be appended to the array, otheriwse the
+        // new pointer object is added to the set and array:
+        bufferedPointerObject = [self getItemFromBuffer:newPointerObject];
+        if (bufferedPointerObject == nil)
+        {
+            [items    addObject:newPointerObject];
+            [children addObject:newPointerObject];
+        }
+        else
+            [children addObject:bufferedPointerObject];
+        [newPointerObject release];
     }
-    else
-      [children addObject:bufferedPointerObject];
-    [newPointerObject release];
-  }
 }
 
 @end
@@ -981,16 +1163,34 @@ wxWidgetImplType* CreateDataView(wxWindowMac* wxpeer, wxWindowMac* WXUNUSED(pare
 // ============================================================================
 // wxCustomCell
 // ============================================================================
+
 @implementation wxCustomCell
-//
-// other methods
-//
+
+#if 0 // starting implementation for custom cell clicks
+
+- (id)init
+{
+    self = [super init];
+    [self setAction:@selector(clickedAction)];
+    [self setTarget:self];
+    return self;
+}
+
+- (void) clickedAction: (id) sender
+{
+    wxUnusedVar(sender);
+}
+
+#endif
+
 -(NSSize) cellSize
 {
-  wxCustomRendererObject* customRendererObject(((wxCustomRendererObject*)[self objectValue]));
+    wxCustomRendererObject * const
+        obj = static_cast<wxCustomRendererObject *>([self objectValue]);
 
 
-  return NSMakeSize(customRendererObject->customRenderer->GetSize().GetWidth(),customRendererObject->customRenderer->GetSize().GetHeight());
+    const wxSize size = obj->customRenderer->GetSize();
+    return NSMakeSize(size.x, size.y);
 }
 
 //
@@ -998,41 +1198,48 @@ wxWidgetImplType* CreateDataView(wxWindowMac* wxpeer, wxWindowMac* WXUNUSED(pare
 //
 -(void) drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView
 {
-  wxCustomRendererObject* customRendererObject(((wxCustomRendererObject*)[self objectValue]));
-
-
- // draw its own background:
-  [[self backgroundColor] set];
-  NSRectFill(cellFrame);
-
-  (void) (customRendererObject->customRenderer->Render(wxFromNSRect(controlView,cellFrame),customRendererObject->customRenderer->GetDC(),0));
-  customRendererObject->customRenderer->SetDC(NULL);
-}
+    wxCustomRendererObject * const
+        obj = static_cast<wxCustomRendererObject *>([self objectValue]);
+    if ( !obj )
+    {
+        // this may happen for the custom cells in container rows: they don't
+        // have any values
+        return;
+    }
 
-#if 0 //TODO FIXME: MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
--(NSUInteger) hitTestForEvent:(NSEvent*)event inRect:(NSRect)cellFrame ofView:(NSView*)controlView
-{
-  NSPoint point = [controlView convertPoint:[event locationInWindow] fromView:nil];
+    wxDataViewCustomRenderer * const renderer = obj->customRenderer;
 
-  wxCustomRendererObject* customRendererObject((wxCustomRendererObject*)[self objectValue]);
+    // if this method is called everything is already setup correctly, 
+    CGContextRef context = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort];
+    CGContextSaveGState( context );
+    
+    if ( ![controlView isFlipped] )
+    {
+        CGContextTranslateCTM( context, 0,  [controlView bounds].size.height );
+        CGContextScaleCTM( context, 1, -1 );
+    }
+        
+    wxGCDC dc;
+    wxGraphicsContext* gc = wxGraphicsContext::CreateFromNative(context);
+    dc.SetGraphicsContext(gc);
 
+    int state = 0;
+    if ( [self isHighlighted] )
+        state |= wxDATAVIEW_CELL_SELECTED;
 
+    renderer->WXCallRender(wxFromNSRect(controlView, cellFrame), &dc, state);
 
-  customRendererObject->customRenderer->LeftClick(wxFromNSPoint(controlView,point),wxFromNSRect(controlView,cellFrame),
-                                                  customRendererObject->GetOwner()->GetOwner(),wxDataViewItem([customRendererObject->item pointer]),
-                                                  [this->m_OutlineView columnWithIdentifier:[customRendererObject->GetColumnPtr() identifier]]);
-  return NSCellHitContentArea;
+    CGContextRestoreGState( context );
 }
-#endif
 
 -(NSRect) imageRectForBounds:(NSRect)cellFrame
 {
-  return cellFrame;
+    return cellFrame;
 }
 
 -(NSRect) titleRectForBounds:(NSRect)cellFrame
 {
-   return cellFrame;
+    return cellFrame;
 }
 
 @end
@@ -1046,40 +1253,39 @@ wxWidgetImplType* CreateDataView(wxWindowMac* wxpeer, wxWindowMac* WXUNUSED(pare
 //
 -(id) init
 {
-  self = [super init];
-  if (self != nil)
-  {
-   // initializing the text part:
-    [self setLineBreakMode:NSLineBreakByTruncatingMiddle];
-    [self setSelectable:YES];
-   // initializing the image part:
-    image       = nil;
-    imageSize   = NSMakeSize(16,16);
-    spaceImageText = 5.0;
-    xImageShift    = 5.0;
-  }
-  return self;
-}
+    self = [super init];
+    if (self != nil)
+    {
+        // initializing the text part:
+        [self setSelectable:YES];
+        // initializing the image part:
+        image       = nil;
+        imageSize   = NSMakeSize(16,16);
+        spaceImageText = 5.0;
+        xImageShift    = 5.0;
+    }
+    return self;
+}
 
 -(id) copyWithZone:(NSZone*)zone
 {
-  wxImageTextCell* cell;
-  
-  
-  cell = (wxImageTextCell*) [super copyWithZone:zone];
-  cell->image          = [image retain];
-  cell->imageSize      = imageSize;
-  cell->spaceImageText = spaceImageText;
-  cell->xImageShift    = xImageShift;
+    wxImageTextCell* cell;
+
+
+    cell = (wxImageTextCell*) [super copyWithZone:zone];
+    cell->image          = [image retain];
+    cell->imageSize      = imageSize;
+    cell->spaceImageText = spaceImageText;
+    cell->xImageShift    = xImageShift;
 
-  return cell;
+    return cell;
 }
 
 -(void) dealloc
 {
-  [image release];
+    [image release];
 
-  [super dealloc];
+    [super dealloc];
 }
 
 //
@@ -1087,26 +1293,26 @@ wxWidgetImplType* CreateDataView(wxWindowMac* wxpeer, wxWindowMac* WXUNUSED(pare
 //
 -(NSTextAlignment) alignment
 {
-  return cellAlignment;
+    return cellAlignment;
 }
 
 -(void) setAlignment:(NSTextAlignment)newAlignment
 {
-  cellAlignment = newAlignment;
-  switch (newAlignment)
-  {
-    case NSCenterTextAlignment:
-    case NSLeftTextAlignment:
-    case NSJustifiedTextAlignment:
-    case NSNaturalTextAlignment:
-      [super setAlignment:NSLeftTextAlignment];
-      break;
-    case NSRightTextAlignment:
-      [super setAlignment:NSRightTextAlignment];
-      break;
-    default:
-      wxFAIL_MSG(_("Unknown alignment type."));
-  }
+    cellAlignment = newAlignment;
+    switch (newAlignment)
+    {
+        case NSCenterTextAlignment:
+        case NSLeftTextAlignment:
+        case NSJustifiedTextAlignment:
+        case NSNaturalTextAlignment:
+            [super setAlignment:NSLeftTextAlignment];
+            break;
+        case NSRightTextAlignment:
+            [super setAlignment:NSRightTextAlignment];
+            break;
+        default:
+            wxFAIL_MSG("Unknown alignment type.");
+    }
 }
 
 //
@@ -1114,24 +1320,24 @@ wxWidgetImplType* CreateDataView(wxWindowMac* wxpeer, wxWindowMac* WXUNUSED(pare
 //
 -(NSImage*) image
 {
-  return image;
+    return image;
 }
 
 -(void) setImage:(NSImage*)newImage
 {
-  [newImage retain];
-  [image release];
-  image = newImage;
+    [newImage retain];
+    [image release];
+    image = newImage;
 }
 
 -(NSSize) imageSize
 {
-  return imageSize;
+    return imageSize;
 }
 
 -(void) setImageSize:(NSSize) newImageSize
 {
-  imageSize = newImageSize;
+    imageSize = newImageSize;
 }
 
 //
@@ -1139,24 +1345,24 @@ wxWidgetImplType* CreateDataView(wxWindowMac* wxpeer, wxWindowMac* WXUNUSED(pare
 //
 -(NSSize) cellImageSize
 {
-  return NSMakeSize(imageSize.width+xImageShift+spaceImageText,imageSize.height);
+    return NSMakeSize(imageSize.width+xImageShift+spaceImageText,imageSize.height);
 }
 
 -(NSSize) cellSize
 {
-  NSSize cellSize([super cellSize]);
+    NSSize cellSize([super cellSize]);
 
 
-  if (imageSize.height > cellSize.height)
-    cellSize.height = imageSize.height;
-  cellSize.width += imageSize.width+xImageShift+spaceImageText;
+    if (imageSize.height > cellSize.height)
+        cellSize.height = imageSize.height;
+    cellSize.width += imageSize.width+xImageShift+spaceImageText;
 
-  return cellSize;
+    return cellSize;
 }
 
 -(NSSize) cellTextSize
 {
-  return [super cellSize];
+    return [super cellSize];
 }
 
 //
@@ -1164,182 +1370,205 @@ wxWidgetImplType* CreateDataView(wxWindowMac* wxpeer, wxWindowMac* WXUNUSED(pare
 //
 -(void) determineCellParts:(NSRect)cellFrame imagePart:(NSRect*)imageFrame textPart:(NSRect*)textFrame
 {
-  switch (cellAlignment)
-  {
-    case NSCenterTextAlignment:
-      {
-        CGFloat const cellSpace = cellFrame.size.width-[self cellSize].width;
-
-        if (cellSpace <= 0) // if the cell's frame is smaller than its contents (at least in x-direction) make sure that the image is visible:
-          NSDivideRect(cellFrame,imageFrame,textFrame,xImageShift+imageSize.width+spaceImageText,NSMinXEdge);
-        else // otherwise center the image and text in the cell's frame
-          NSDivideRect(cellFrame,imageFrame,textFrame,xImageShift+imageSize.width+spaceImageText+0.5*cellSpace,NSMinXEdge);
-      }
-      break;
-    case NSJustifiedTextAlignment:
-    case NSLeftTextAlignment:
-    case NSNaturalTextAlignment: // how to determine the natural writing direction? TODO
-      NSDivideRect(cellFrame,imageFrame,textFrame,xImageShift+imageSize.width+spaceImageText,NSMinXEdge);
-      break;
-    case NSRightTextAlignment:
-      {
-        CGFloat const cellSpace = cellFrame.size.width-[self cellSize].width;
-
-        if (cellSpace <= 0) // if the cell's frame is smaller than its contents (at least in x-direction) make sure that the image is visible:
-          NSDivideRect(cellFrame,imageFrame,textFrame,xImageShift+imageSize.width+spaceImageText,NSMinXEdge);
-        else // otherwise right align the image and text in the cell's frame
-          NSDivideRect(cellFrame,imageFrame,textFrame,xImageShift+imageSize.width+spaceImageText+cellSpace,NSMinXEdge);
-      }
-      break;
-    default:
-      *imageFrame = NSZeroRect;
-      *textFrame  = NSZeroRect;
-      wxFAIL_MSG(_("Unhandled alignment type."));
-  }
+    switch (cellAlignment)
+    {
+        case NSCenterTextAlignment:
+            {
+                CGFloat const cellSpace = cellFrame.size.width-[self cellSize].width;
+
+                // if the cell's frame is smaller than its contents (at least
+                // in x-direction) make sure that the image is visible:
+                if (cellSpace <= 0)
+                    NSDivideRect(cellFrame,imageFrame,textFrame,xImageShift+imageSize.width+spaceImageText,NSMinXEdge);
+                else // otherwise center the image and text in the cell's frame
+                    NSDivideRect(cellFrame,imageFrame,textFrame,xImageShift+imageSize.width+spaceImageText+0.5*cellSpace,NSMinXEdge);
+            }
+            break;
+        case NSJustifiedTextAlignment:
+        case NSLeftTextAlignment:
+        case NSNaturalTextAlignment: // how to determine the natural writing direction? TODO
+            NSDivideRect(cellFrame,imageFrame,textFrame,xImageShift+imageSize.width+spaceImageText,NSMinXEdge);
+            break;
+        case NSRightTextAlignment:
+            {
+                CGFloat const cellSpace = cellFrame.size.width-[self cellSize].width;
+
+                // if the cell's frame is smaller than its contents (at least
+                // in x-direction) make sure that the image is visible:
+                if (cellSpace <= 0)
+                    NSDivideRect(cellFrame,imageFrame,textFrame,xImageShift+imageSize.width+spaceImageText,NSMinXEdge);
+                else // otherwise right align the image and text in the cell's frame
+                    NSDivideRect(cellFrame,imageFrame,textFrame,xImageShift+imageSize.width+spaceImageText+cellSpace,NSMinXEdge);
+            }
+            break;
+        default:
+            *imageFrame = NSZeroRect;
+            *textFrame  = NSZeroRect;
+            wxFAIL_MSG("Unhandled alignment type.");
+    }
 }
 
 -(void) drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView
 {
-  NSRect textFrame, imageFrame;
-
-
-  [self determineCellParts:cellFrame imagePart:&imageFrame textPart:&textFrame];
-// draw the image part by ourselves;
- // check if the cell has to draw its own background (checking is done by the parameter of the textfield's cell):
-  if ([self drawsBackground])
-  {
-    [[self backgroundColor] set];
-    NSRectFill(imageFrame);
-  }
-  if (image != nil)
-  {
-   // the image is slightly shifted (xImageShift) and has a fixed size but the image's frame might be larger and starts
-   // currently on the left side of the cell's frame; therefore, the origin and the image's frame size have to be adjusted:
-    if (imageFrame.size.width >= xImageShift+imageSize.width+spaceImageText)
+    NSRect textFrame, imageFrame;
+
+
+    [self determineCellParts:cellFrame imagePart:&imageFrame textPart:&textFrame];
+    // draw the image part by ourselves;
+    // check if the cell has to draw its own background (checking is done by
+    // the parameter of the textfield's cell):
+    if ([self drawsBackground])
     {
-      imageFrame.origin.x += imageFrame.size.width-imageSize.width-spaceImageText;
-      imageFrame.size.width = imageSize.width;
+        [[self backgroundColor] set];
+        NSRectFill(imageFrame);
     }
-    else
+    if (image != nil)
     {
-      imageFrame.origin.x   += xImageShift;
-      imageFrame.size.width -= xImageShift+spaceImageText;
+        // the image is slightly shifted (xImageShift) and has a fixed size
+        // but the image's frame might be larger and starts currently on the
+        // left side of the cell's frame; therefore, the origin and the
+        // image's frame size have to be adjusted:
+        if (imageFrame.size.width >= xImageShift+imageSize.width+spaceImageText)
+        {
+            imageFrame.origin.x += imageFrame.size.width-imageSize.width-spaceImageText;
+            imageFrame.size.width = imageSize.width;
+        }
+        else
+        {
+            imageFrame.origin.x   += xImageShift;
+            imageFrame.size.width -= xImageShift+spaceImageText;
+        }
+        // ...and the image has to be centered in the y-direction:
+        if (imageFrame.size.height > imageSize.height)
+            imageFrame.size.height = imageSize.height;
+        imageFrame.origin.y += ceil(0.5*(cellFrame.size.height-imageFrame.size.height));
+
+        // according to the documentation the coordinate system should be
+        // flipped for NSTableViews (y-coordinate goes from top to bottom); to
+        // draw an image correctly the coordinate system has to be transformed
+        // to a bottom-top coordinate system, otherwise the image's
+        // content is flipped:
+        NSAffineTransform* coordinateTransform([NSAffineTransform transform]);
+
+        if ([controlView isFlipped])
+        {
+            [coordinateTransform scaleXBy: 1.0 yBy:-1.0]; // first the coordinate system is brought back to bottom-top orientation
+            [coordinateTransform translateXBy:0.0 yBy:(-2.0)*imageFrame.origin.y-imageFrame.size.height]; // the coordinate system has to be moved to compensate for the
+            [coordinateTransform concat];                                                                 // other orientation and the position of the image's frame
+        }
+        [image drawInRect:imageFrame fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; // suggested method to draw the image
+        // instead of compositeToPoint:operation:
+        // take back previous transformation (if the view is not flipped the
+        // coordinate transformation matrix contains the identity matrix and
+        // the next two operations do not change the content's transformation
+        // matrix):
+        [coordinateTransform invert];
+        [coordinateTransform concat];
     }
-   // ...and the image has to be centered in the y-direction:
-    if (imageFrame.size.height > imageSize.height)
-      imageFrame.size.height = imageSize.height;
-    imageFrame.origin.y += ceil(0.5*(cellFrame.size.height-imageFrame.size.height));
-
-   // according to the documentation the coordinate system should be flipped for NSTableViews (y-coordinate goes from top to bottom);
-   // to draw an image correctly the coordinate system has to be transformed to a bottom-top coordinate system, otherwise the image's
-   // content is flipped:
-    NSAffineTransform* coordinateTransform([NSAffineTransform transform]);
-    
-    if ([controlView isFlipped])
+    // let the textfield cell draw the text part:
+    if (textFrame.size.width > [self cellTextSize].width)
     {
-      [coordinateTransform scaleXBy: 1.0 yBy:-1.0]; // first the coordinate system is brought back to bottom-top orientation
-      [coordinateTransform translateXBy:0.0 yBy:(-2.0)*imageFrame.origin.y-imageFrame.size.height]; // the coordinate system has to be moved to compensate for the
-      [coordinateTransform concat];                                                                 // other orientation and the position of the image's frame
+        // for unknown reasons the alignment of the text cell is ignored;
+        // therefore change the size so that alignment does not influence the
+        // visualization anymore
+        textFrame.size.width = [self cellTextSize].width;
     }
-    [image drawInRect:imageFrame fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; // suggested method to draw the image
-                                                                                                    // instead of compositeToPoint:operation:
-   // take back previous transformation (if the view is not flipped the coordinate transformation matrix contains the identity matrix
-   // and the next two operations do not change the content's transformation matrix):
-    [coordinateTransform invert];
-    [coordinateTransform concat];
-  }
- // let the textfield cell draw the text part:
-  if (textFrame.size.width > [self cellTextSize].width) // for unknown reasons the alignment of the text cell is ignored; therefore change the size so that
-    textFrame.size.width = [self cellTextSize].width;   // alignment does not influence the visualization anymore
-  [super drawWithFrame:textFrame inView:controlView];
+    [super drawWithFrame:textFrame inView:controlView];
 }
 
 -(void) editWithFrame:(NSRect)aRect inView:(NSView*)controlView editor:(NSText*)textObj delegate:(id)anObject event:(NSEvent*)theEvent
 {
-  NSRect textFrame, imageFrame;
+    NSRect textFrame, imageFrame;
 
 
-  [self determineCellParts:aRect imagePart:&imageFrame textPart:&textFrame];
-  [super editWithFrame:textFrame inView:controlView editor:textObj delegate:anObject event:theEvent];
+    [self determineCellParts:aRect imagePart:&imageFrame textPart:&textFrame];
+    [super editWithFrame:textFrame inView:controlView editor:textObj delegate:anObject event:theEvent];
 }
 
 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
 -(NSUInteger) hitTestForEvent:(NSEvent*)event inRect:(NSRect)cellFrame ofView:(NSView*)controlView
 {
-  NSPoint point = [controlView convertPoint:[event locationInWindow] fromView:nil];
+    NSPoint point = [controlView convertPoint:[event locationInWindow] fromView:nil];
 
-  NSRect imageFrame, textFrame;
+    NSRect imageFrame, textFrame;
 
 
-  [self determineCellParts:cellFrame imagePart:&imageFrame textPart:&textFrame];
-  if (image != nil)
-  {
-   // the image is shifted...
-    if (imageFrame.size.width >= xImageShift+imageSize.width+spaceImageText)
+    [self determineCellParts:cellFrame imagePart:&imageFrame textPart:&textFrame];
+    if (image != nil)
     {
-      imageFrame.origin.x += imageFrame.size.width-imageSize.width-spaceImageText;
-      imageFrame.size.width = imageSize.width;
+        // the image is shifted...
+        if (imageFrame.size.width >= xImageShift+imageSize.width+spaceImageText)
+        {
+            imageFrame.origin.x += imageFrame.size.width-imageSize.width-spaceImageText;
+            imageFrame.size.width = imageSize.width;
+        }
+        else
+        {
+            imageFrame.origin.x   += xImageShift;
+            imageFrame.size.width -= xImageShift+spaceImageText;
+        }
+        // ...and centered:
+        if (imageFrame.size.height > imageSize.height)
+            imageFrame.size.height = imageSize.height;
+        imageFrame.origin.y += ceil(0.5*(cellFrame.size.height-imageFrame.size.height));
+        // If the point is in the image rect, then it is a content hit (see
+        // documentation for hitTestForEvent:inRect:ofView):
+        if (NSMouseInRect(point, imageFrame, [controlView isFlipped]))
+            return NSCellHitContentArea;
     }
-    else
+    // if the image was not hit let's try the text part:
+    if (textFrame.size.width > [self cellTextSize].width)
     {
-      imageFrame.origin.x   += xImageShift;
-      imageFrame.size.width -= xImageShift+spaceImageText;
+        // for unknown reasons the alignment of the text cell is ignored;
+        // therefore change the size so that alignment does not influence the
+        // visualization anymore
+        textFrame.size.width = [self cellTextSize].width;
     }
-   // ...and centered:
-    if (imageFrame.size.height > imageSize.height)
-      imageFrame.size.height = imageSize.height;
-    imageFrame.origin.y += ceil(0.5*(cellFrame.size.height-imageFrame.size.height));
-    // If the point is in the image rect, then it is a content hit (see documentation for hitTestForEvent:inRect:ofView):
-    if (NSMouseInRect(point, imageFrame, [controlView isFlipped]))
-      return NSCellHitContentArea;
-  }
- // if the image was not hit let's try the text part:
-  if (textFrame.size.width > [self cellTextSize].width) // for unknown reasons the alignment of the text cell is ignored; therefore change the size so that
-    textFrame.size.width = [self cellTextSize].width;   // alignment does not influence the visualization anymore
-  return [super hitTestForEvent:event inRect:textFrame ofView:controlView];    
+
+    return [super hitTestForEvent:event inRect:textFrame ofView:controlView];
 }
 #endif
 
 -(NSRect) imageRectForBounds:(NSRect)cellFrame
 {
-  NSRect textFrame, imageFrame;
+    NSRect textFrame, imageFrame;
 
 
-  [self determineCellParts:cellFrame imagePart:&imageFrame textPart:&textFrame];
-  if (imageFrame.size.width >= xImageShift+imageSize.width+spaceImageText)
-  {
-    imageFrame.origin.x += imageFrame.size.width-imageSize.width-spaceImageText;
-    imageFrame.size.width = imageSize.width;
-  }
-  else
-  {
-    imageFrame.origin.x   += xImageShift;
-    imageFrame.size.width -= xImageShift+spaceImageText;
-  }
- // ...and centered:
-  if (imageFrame.size.height > imageSize.height)
-    imageFrame.size.height = imageSize.height;
-  imageFrame.origin.y += ceil(0.5*(cellFrame.size.height-imageFrame.size.height));
-  
-  return imageFrame;
+    [self determineCellParts:cellFrame imagePart:&imageFrame textPart:&textFrame];
+    if (imageFrame.size.width >= xImageShift+imageSize.width+spaceImageText)
+    {
+        imageFrame.origin.x += imageFrame.size.width-imageSize.width-spaceImageText;
+        imageFrame.size.width = imageSize.width;
+    }
+    else
+    {
+        imageFrame.origin.x   += xImageShift;
+        imageFrame.size.width -= xImageShift+spaceImageText;
+    }
   // ...and centered:
+    if (imageFrame.size.height > imageSize.height)
+        imageFrame.size.height = imageSize.height;
+    imageFrame.origin.y += ceil(0.5*(cellFrame.size.height-imageFrame.size.height));
+
+    return imageFrame;
 }
 
 -(void) selectWithFrame:(NSRect)aRect inView:(NSView*)controlView editor:(NSText*)textObj delegate:(id)anObject start:(NSInteger)selStart length:(NSInteger)selLength
 {
-  NSRect textFrame, imageFrame;
+    NSRect textFrame, imageFrame;
 
 
-  [self determineCellParts:aRect imagePart:&imageFrame textPart:&textFrame];
-  [super selectWithFrame:textFrame inView:controlView editor:textObj delegate:anObject start:selStart length:selLength];
+    [self determineCellParts:aRect imagePart:&imageFrame textPart:&textFrame];
+    [super selectWithFrame:textFrame inView:controlView editor:textObj delegate:anObject start:selStart length:selLength];
 }
 
 -(NSRect) titleRectForBounds:(NSRect)cellFrame
 {
-  NSRect textFrame, imageFrame;
+    NSRect textFrame, imageFrame;
 
 
-  [self determineCellParts:cellFrame imagePart:&imageFrame textPart:&textFrame];
-   return textFrame;
+    [self determineCellParts:cellFrame imagePart:&imageFrame textPart:&textFrame];
+    return textFrame;
 }
 
 @end
@@ -1354,18 +1583,20 @@ wxWidgetImplType* CreateDataView(wxWindowMac* wxpeer, wxWindowMac* WXUNUSED(pare
 //
 -(id) init
 {
-  self = [super init];
-  if (self != nil)
-  {
-    isEditingCell = NO;
-    [self registerForDraggedTypes:[NSArray arrayWithObjects:DataViewPboardType,NSStringPboardType,nil]];
-    [self setDelegate:self];
-    [self setDoubleAction:@selector(actionDoubleClick:)];
-    [self setDraggingSourceOperationMask:NSDragOperationEvery forLocal:NO];
-    [self setDraggingSourceOperationMask:NSDragOperationEvery forLocal:YES];
-    [self setTarget:self];
-  }
-  return self;
+    self = [super init];
+    if (self != nil)
+    {
+        currentlyEditedColumn =
+            currentlyEditedRow = -1;
+
+        [self registerForDraggedTypes:[NSArray arrayWithObjects:DataViewPboardType,NSStringPboardType,nil]];
+        [self setDelegate:self];
+        [self setDoubleAction:@selector(actionDoubleClick:)];
+        [self setDraggingSourceOperationMask:NSDragOperationEvery forLocal:NO];
+        [self setDraggingSourceOperationMask:NSDragOperationEvery forLocal:YES];
+        [self setTarget:self];
+    }
+    return self;
 }
 
 //
@@ -1373,29 +1604,32 @@ wxWidgetImplType* CreateDataView(wxWindowMac* wxpeer, wxWindowMac* WXUNUSED(pare
 //
 -(wxCocoaDataViewControl*) implementation
 {
-  return implementation;
+    return implementation;
 }
 
 -(void) setImplementation:(wxCocoaDataViewControl*) newImplementation
 {
-  implementation = newImplementation;
+    implementation = newImplementation;
 }
 
 //
 // actions
 //
 -(void) actionDoubleClick:(id)sender
- // actually the documentation (NSTableView 2007-10-31) for doubleAction: and setDoubleAction: seems to be wrong as this action message is always sent
- // whether the cell is editable or not
 {
-  wxDataViewCtrl* const dataViewCtrlPtr = implementation->GetDataViewCtrl();
+    wxUnusedVar(sender);
+
+    // actually the documentation (NSTableView 2007-10-31) for doubleAction:
+    // 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();
 
-  wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED,dataViewCtrlPtr->GetId()); // variable definition
+    wxDataViewEvent event(wxEVT_DATAVIEW_ITEM_ACTIVATED,dvc->GetId());
 
 
-  dataViewEvent.SetEventObject(dataViewCtrlPtr);
-  dataViewEvent.SetItem(wxDataViewItem([((wxPointerObject*) [self itemAtRow:[self clickedRow]]) pointer]));
-  dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
+    event.SetEventObject(dvc);
+    event.SetItem(wxDataViewItemFromItem([self itemAtRow:[self clickedRow]]));
+    dvc->GetEventHandler()->ProcessEvent(event);
 }
 
 
@@ -1403,26 +1637,30 @@ wxWidgetImplType* CreateDataView(wxWindowMac* wxpeer, wxWindowMac* WXUNUSED(pare
 // contextual menus
 //
 -(NSMenu*) menuForEvent:(NSEvent*)theEvent
- // this method does not do any special menu event handling but only sends an event message; therefore, the user
- // has full control if a context menu should be shown or not
 {
-  wxDataViewCtrl* const dataViewCtrlPtr = implementation->GetDataViewCtrl();
-            
-  wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU,dataViewCtrlPtr->GetId());
+    wxUnusedVar(theEvent);
+
+    // this method does not do any special menu event handling but only sends
+    // an event message; therefore, the user has full control if a context
+    // menu should be shown or not
+    wxDataViewCtrl* const dvc = implementation->GetDataViewCtrl();
 
-  wxDataViewItemArray selectedItems;
+    wxDataViewEvent event(wxEVT_DATAVIEW_ITEM_CONTEXT_MENU,dvc->GetId());
 
+    wxDataViewItemArray selectedItems;
 
-  dataViewEvent.SetEventObject(dataViewCtrlPtr);
-  dataViewEvent.SetModel(dataViewCtrlPtr->GetModel());
- // get the item information;
- // theoretically more than one ID can be returned but the event can only handle one item, therefore only the first
- // item of the array is returned:
-  if (dataViewCtrlPtr->GetSelections(selectedItems) > 0)
-    dataViewEvent.SetItem(selectedItems[0]);
-  dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
- // nothing is done:
-  return nil;
+
+    event.SetEventObject(dvc);
+    event.SetModel(dvc->GetModel());
+    // get the item information;
+    // theoretically more than one ID can be returned but the event can only
+    // handle one item, therefore only the first item of the array is
+    // returned:
+    if (dvc->GetSelections(selectedItems) > 0)
+        event.SetItem(selectedItems[0]);
+    dvc->GetEventHandler()->ProcessEvent(event);
+    // nothing is done:
+    return nil;
 }
 
 //
@@ -1430,90 +1668,131 @@ wxWidgetImplType* CreateDataView(wxWindowMac* wxpeer, wxWindowMac* WXUNUSED(pare
 //
 -(void) outlineView:(NSOutlineView*)outlineView mouseDownInHeaderOfTableColumn:(NSTableColumn*)tableColumn
 {
-  wxDataViewColumn* const dataViewColumnPtr(reinterpret_cast<wxDataViewColumn*>([[tableColumn identifier] pointer]));
+    wxDataViewColumn* const
+        col([static_cast<wxDVCNSTableColumn*>(tableColumn) getColumnPointer]);
 
-  wxDataViewCtrl* const dataViewCtrlPtr = implementation->GetDataViewCtrl();
-            
-  wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK,dataViewCtrlPtr->GetId());
+    wxDataViewCtrl* const dvc = implementation->GetDataViewCtrl();
 
+    wxDataViewEvent
+        event(wxEVT_DATAVIEW_COLUMN_HEADER_CLICK,dvc->GetId());
 
- // first, send an event that the user clicked into a column's header:
-  dataViewEvent.SetEventObject(dataViewCtrlPtr);
-  dataViewEvent.SetColumn(dataViewCtrlPtr->GetColumnPosition(dataViewColumnPtr));
-  dataViewEvent.SetDataViewColumn(dataViewColumnPtr);
-  dataViewCtrlPtr->HandleWindowEvent(dataViewEvent);
 
- // now, check if the click may have had an influence on sorting, too;
- // the sorting setup has to be done only if the clicked table column is sortable and has not been used for
- // sorting before the click; if the column is already responsible for sorting the native control changes
- // the sorting direction automatically and informs the data source via outlineView:sortDescriptorsDidChange:
-  if (dataViewColumnPtr->IsSortable() && ([tableColumn sortDescriptorPrototype] == nil))
-  {
-   // remove the sort order from the previously sorted column table (it can also be that
-   // no sorted column table exists):
-    UInt32 const noOfColumns = [outlineView numberOfColumns];
-    
-    for (UInt32 i=0; i<noOfColumns; ++i)
-      [[[outlineView tableColumns] objectAtIndex:i] setSortDescriptorPrototype:nil];
-   // make column table sortable:
-    NSArray*          sortDescriptors;
-    NSSortDescriptor* sortDescriptor;
-    
-    sortDescriptor = [[NSSortDescriptor alloc] initWithKey:[NSString stringWithFormat:@"%d",[outlineView columnWithIdentifier:[tableColumn identifier]]]
-                                                 ascending:YES];
-    sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
-    [tableColumn setSortDescriptorPrototype:sortDescriptor];
-    [outlineView setSortDescriptors:sortDescriptors];
-    [sortDescriptor release];
-  }
+    // first, send an event that the user clicked into a column's header:
+    event.SetEventObject(dvc);
+    event.SetColumn(dvc->GetColumnPosition(col));
+    event.SetDataViewColumn(col);
+    dvc->HandleWindowEvent(event);
+
+    // now, check if the click may have had an influence on sorting, too;
+    // the sorting setup has to be done only if the clicked table column is
+    // sortable and has not been used for sorting before the click; if the
+    // column is already responsible for sorting the native control changes
+    // the sorting direction automatically and informs the data source via
+    // outlineView:sortDescriptorsDidChange:
+    if (col->IsSortable() && ([tableColumn sortDescriptorPrototype] == nil))
+    {
+        // remove the sort order from the previously sorted column table (it
+        // can also be that no sorted column table exists):
+        UInt32 const noOfColumns = [outlineView numberOfColumns];
+
+        for (UInt32 i=0; i<noOfColumns; ++i)
+            [[[outlineView tableColumns] objectAtIndex:i] setSortDescriptorPrototype:nil];
+        // make column table sortable:
+        NSArray*          sortDescriptors;
+        NSSortDescriptor* sortDescriptor;
+
+        sortDescriptor = [[NSSortDescriptor alloc] initWithKey:[NSString stringWithFormat:@"%d",[outlineView columnWithIdentifier:[tableColumn identifier]]]
+            ascending:YES];
+        sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
+        [tableColumn setSortDescriptorPrototype:sortDescriptor];
+        [outlineView setSortDescriptors:sortDescriptors];
+        [sortDescriptor release];
+    }
 }
 
 -(BOOL) outlineView:(NSOutlineView*)outlineView shouldCollapseItem:(id)item
 {
-  wxDataViewCtrl* const dataViewCtrlPtr = implementation->GetDataViewCtrl();
-            
-  wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSING,dataViewCtrlPtr->GetId()); // variable definition
+    wxUnusedVar(outlineView);
+
+    wxDataViewCtrl* const dvc = implementation->GetDataViewCtrl();
+
+    wxDataViewEvent event(wxEVT_DATAVIEW_ITEM_COLLAPSING,dvc->GetId());
 
 
-  dataViewEvent.SetEventObject(dataViewCtrlPtr);
-  dataViewEvent.SetItem       (wxDataViewItem([((wxPointerObject*) item) pointer]));
-  dataViewEvent.SetModel      (dataViewCtrlPtr->GetModel());
- // finally send the equivalent wxWidget event:
-  dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
- // opening the container is allowed if not vetoed:
-  return dataViewEvent.IsAllowed();
+    event.SetEventObject(dvc);
+    event.SetItem       (wxDataViewItemFromItem(item));
+    event.SetModel      (dvc->GetModel());
   // finally send the equivalent wxWidget event:
+    dvc->GetEventHandler()->ProcessEvent(event);
   // opening the container is allowed if not vetoed:
+    return event.IsAllowed();
 }
 
 -(BOOL) outlineView:(NSOutlineView*)outlineView shouldExpandItem:(id)item
 {
-  wxDataViewCtrl* const dataViewCtrlPtr = implementation->GetDataViewCtrl();
-            
-  wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDING,dataViewCtrlPtr->GetId()); // variable definition
+    wxUnusedVar(outlineView);
 
+    wxDataViewCtrl* const dvc = implementation->GetDataViewCtrl();
 
-  dataViewEvent.SetEventObject(dataViewCtrlPtr);
-  dataViewEvent.SetItem       (wxDataViewItem([((wxPointerObject*) item) pointer]));
-  dataViewEvent.SetModel      (dataViewCtrlPtr->GetModel());
- // finally send the equivalent wxWidget event:
-  dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
- // opening the container is allowed if not vetoed:
-  return dataViewEvent.IsAllowed();
+    wxDataViewEvent event(wxEVT_DATAVIEW_ITEM_EXPANDING,dvc->GetId());
+
+
+    event.SetEventObject(dvc);
+    event.SetItem       (wxDataViewItemFromItem(item));
+    event.SetModel      (dvc->GetModel());
+    // finally send the equivalent wxWidget event:
+    dvc->GetEventHandler()->ProcessEvent(event);
+    // opening the container is allowed if not vetoed:
+    return event.IsAllowed();
 }
 
 -(BOOL) outlineView:(NSOutlineView*)outlineView shouldSelectTableColumn:(NSTableColumn*)tableColumn
 {
-  return NO;
+    wxUnusedVar(tableColumn);
+    wxUnusedVar(outlineView);
+
+    return NO;
 }
 
--(void) outlineView:(NSOutlineView*)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn*) tableColumn item:(id)item
+-(void) outlineView:(wxCocoaOutlineView*)outlineView
+    willDisplayCell:(id)cell
+    forTableColumn:(NSTableColumn*)tableColumn
+    item:(id)item
 {
-  wxDataViewColumn* dataViewColumnPtr(reinterpret_cast<wxDataViewColumn*>([[tableColumn identifier] pointer]));
+    wxUnusedVar(outlineView);
+
+    wxDataViewCtrl * const dvc = implementation->GetDataViewCtrl();
+    wxDataViewModel * const model = dvc->GetModel();
+
+    wxDataViewColumn* const
+        dvCol([static_cast<wxDVCNSTableColumn*>(tableColumn) getColumnPointer]);
+    const unsigned colIdx = dvCol->GetModelColumn();
+
+    wxDataViewItem dvItem(wxDataViewItemFromItem(item));
+
+    if ( !model->HasValue(dvItem, colIdx) )
+        return;
+
+    wxDataViewRenderer * const renderer = dvCol->GetRenderer();
+    wxDataViewRendererNativeData * const data = renderer->GetNativeData();
 
+    // let the renderer know about what it's going to render next
+    data->SetColumnPtr(tableColumn);
+    data->SetItem(item);
+    data->SetItemCell(cell);
 
-  dataViewColumnPtr->GetRenderer()->GetNativeData()->SetColumnPtr(tableColumn);
-  dataViewColumnPtr->GetRenderer()->GetNativeData()->SetItem(item);
-  dataViewColumnPtr->GetRenderer()->GetNativeData()->SetItemCell(cell);
-  (void) dataViewColumnPtr->GetRenderer()->Render();
+    // use the attributes: notice that we need to do this whether we have them
+    // or not as even if this cell doesn't have any attributes, the previous
+    // one might have had some and then we need to reset them back to default
+    wxDataViewItemAttr attr;
+    model->GetAttr(dvItem, colIdx, attr);
+    renderer->OSXApplyAttr(attr);
+
+    // set the state (enabled/disabled) of the item
+    renderer->OSXApplyEnabled(model->IsEnabled(dvItem, colIdx));
+
+    // and finally do draw it
+    renderer->MacRender();
 }
 
 //
@@ -1521,325 +1800,480 @@ wxWidgetImplType* CreateDataView(wxWindowMac* wxpeer, wxWindowMac* WXUNUSED(pare
 //
 -(void) outlineViewColumnDidMove:(NSNotification*)notification
 {
-  int const newColumnPosition = [[[notification userInfo] objectForKey:@"NSNewColumn"] intValue];
+    int const newColumnPosition = [[[notification userInfo] objectForKey:@"NSNewColumn"] intValue];
+
+    NSTableColumn*
+        tableColumn = [[self tableColumns] objectAtIndex:newColumnPosition];
+    wxDataViewColumn* const
+        col([static_cast<wxDVCNSTableColumn*>(tableColumn) getColumnPointer]);
 
-  wxDataViewColumn* const dataViewColumnPtr(reinterpret_cast<wxDataViewColumn*>([[[[self tableColumns] objectAtIndex:newColumnPosition] identifier] pointer]));
+    wxDataViewCtrl* const dvc = implementation->GetDataViewCtrl();
 
-  wxDataViewCtrl* const dataViewCtrlPtr = implementation->GetDataViewCtrl();
-  
-  wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_COLUMN_REORDERED,dataViewCtrlPtr->GetId());
+    wxDataViewEvent event(wxEVT_DATAVIEW_COLUMN_REORDERED,dvc->GetId());
 
 
-  dataViewEvent.SetEventObject(dataViewCtrlPtr);
-  dataViewEvent.SetColumn(dataViewCtrlPtr->GetColumnPosition(dataViewColumnPtr));
-  dataViewEvent.SetDataViewColumn(dataViewColumnPtr);
-  dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
+    event.SetEventObject(dvc);
+    event.SetColumn(dvc->GetColumnPosition(col));
+    event.SetDataViewColumn(col);
+    dvc->GetEventHandler()->ProcessEvent(event);
 }
 
 -(void) outlineViewItemDidCollapse:(NSNotification*)notification
 {
-  wxDataViewCtrl* const dataViewCtrlPtr = implementation->GetDataViewCtrl();
-            
-  wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSED,dataViewCtrlPtr->GetId());
+    wxDataViewCtrl* const dvc = implementation->GetDataViewCtrl();
 
+    wxDataViewEvent event(wxEVT_DATAVIEW_ITEM_COLLAPSED,dvc->GetId());
 
-  dataViewEvent.SetEventObject(dataViewCtrlPtr);
-  dataViewEvent.SetItem(wxDataViewItem([((wxPointerObject*) [[notification userInfo] objectForKey:@"NSObject"]) pointer]));
-  dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
+
+    event.SetEventObject(dvc);
+    event.SetItem(wxDataViewItemFromItem(
+                    [[notification userInfo] objectForKey:@"NSObject"]));
+    dvc->GetEventHandler()->ProcessEvent(event);
 }
 
 -(void) outlineViewItemDidExpand:(NSNotification*)notification
 {
-  wxDataViewCtrl* const dataViewCtrlPtr = implementation->GetDataViewCtrl();
-            
-  wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDED,dataViewCtrlPtr->GetId());
+    wxDataViewCtrl* const dvc = implementation->GetDataViewCtrl();
+
+    wxDataViewEvent event(wxEVT_DATAVIEW_ITEM_EXPANDED,dvc->GetId());
 
 
-  dataViewEvent.SetEventObject(dataViewCtrlPtr);
-  dataViewEvent.SetItem(wxDataViewItem([((wxPointerObject*) [[notification userInfo] objectForKey:@"NSObject"]) pointer]));
-  dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
+    event.SetEventObject(dvc);
+    event.SetItem(wxDataViewItemFromItem(
+                    [[notification userInfo] objectForKey:@"NSObject"]));
+    dvc->GetEventHandler()->ProcessEvent(event);
 }
 
 -(void) outlineViewSelectionDidChange:(NSNotification*)notification
 {
-  wxDataViewCtrl* const dataViewCtrlPtr = implementation->GetDataViewCtrl();
+    wxUnusedVar(notification);
 
-  wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED,dataViewCtrlPtr->GetId()); // variable definition
+    wxDataViewCtrl* const dvc = implementation->GetDataViewCtrl();
 
+    wxDataViewEvent event(wxEVT_DATAVIEW_SELECTION_CHANGED,dvc->GetId());
 
-  dataViewEvent.SetEventObject(dataViewCtrlPtr);
-  dataViewEvent.SetModel      (dataViewCtrlPtr->GetModel());
- // finally send the equivalent wxWidget event:
-  dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
+    event.SetEventObject(dvc);
+    event.SetModel(dvc->GetModel());
+    event.SetItem(dvc->GetSelection());
+    dvc->GetEventHandler()->ProcessEvent(event);
 }
 
 -(void) textDidBeginEditing:(NSNotification*)notification
- // this notification is only sent if the user started modifying the cell (not when the user clicked into the cell
- // and the cell's editor is called!)
 {
- // call method of superclass (otherwise editing does not work correctly - the outline data source class is not
- // informed about a change of data):
-  [super textDidBeginEditing:notification];
+    // this notification is only sent if the user started modifying the cell
+    // (not when the user clicked into the cell and the cell's editor is
+    // called!)
+
+    // call method of superclass (otherwise editing does not work correctly -
+    // the outline data source class is not 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];
 
-  wxDataViewCtrl* const dataViewCtrlPtr = implementation->GetDataViewCtrl();
+    NSTableColumn*
+        tableColumn = [[self tableColumns] objectAtIndex:currentlyEditedColumn];
+    wxDataViewColumn* const
+        col([static_cast<wxDVCNSTableColumn*>(tableColumn) getColumnPointer]);
 
+    wxDataViewCtrl* const dvc = 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
+    // stop editing of a custom item first (if necessary)
+    dvc->FinishCustomItemEditing();
 
-  dataViewEvent.SetEventObject(dataViewCtrlPtr);
-  dataViewEvent.SetItem(wxDataViewItem([((wxPointerObject*) [self itemAtRow:[self editedRow]]) pointer]));
-  dataViewEvent.SetColumn(dataViewCtrlPtr->GetColumnPosition(dataViewColumnPtr));
-  dataViewEvent.SetDataViewColumn(dataViewColumnPtr);
-  dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
+    // now, send the event:
+    wxDataViewEvent
+        event(wxEVT_DATAVIEW_ITEM_EDITING_STARTED,dvc->GetId());
+
+    event.SetEventObject(dvc);
+    event.SetItem(
+            wxDataViewItemFromItem([self itemAtRow:currentlyEditedRow]));
+    event.SetColumn(dvc->GetColumnPosition(col));
+    event.SetDataViewColumn(col);
+    dvc->GetEventHandler()->ProcessEvent(event);
 }
 
 -(void) textDidEndEditing:(NSNotification*)notification
 {
- // call method of superclass (otherwise editing does not work correctly - the outline data source class is not
- // informed about a change of data):
-  [super textDidEndEditing:notification];
+    // call method of superclass (otherwise editing does not work correctly -
+    // the outline data source class is not informed about a change of data):
+    [super textDidEndEditing:notification];
+
+    // under OSX an event indicating the end of an editing session can be sent
+    // even if no event indicating a start of an 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_DATAVIEW_ITEM_EDITING_DONE event is only sent if a
+    // corresponding wxEVT_DATAVIEW_ITEM_EDITING_STARTED has been sent
+    // before; to check if a wxEVT_DATAVIEW_ITEM_EDITING_STARTED has
+    // been sent the last edited column/row are valid:
+    if ( currentlyEditedColumn != -1 && currentlyEditedRow != -1 )
+    {
+        NSTableColumn*
+            tableColumn = [[self tableColumns] objectAtIndex:currentlyEditedColumn];
+        wxDataViewColumn* const
+            col([static_cast<wxDVCNSTableColumn*>(tableColumn) getColumnPointer]);
+
+        wxDataViewCtrl* const dvc = implementation->GetDataViewCtrl();
 
- // under OSX an event indicating the end of an editing session can be sent even if no event indicating a start of an
- // 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)
-  {
-    wxDataViewColumn* const dataViewColumnPtr = reinterpret_cast<wxDataViewColumn*>([[[[self tableColumns] objectAtIndex:[self editedColumn]] identifier] pointer]);
+        // send event to wxWidgets:
+        wxDataViewEvent
+            event(wxEVT_DATAVIEW_ITEM_EDITING_DONE,dvc->GetId());
 
-    wxDataViewCtrl* const dataViewCtrlPtr = implementation->GetDataViewCtrl();
+        event.SetEventObject(dvc);
+        event.SetItem(
+                wxDataViewItemFromItem([self itemAtRow:currentlyEditedRow]));
+        event.SetColumn(dvc->GetColumnPosition(col));
+        event.SetDataViewColumn(col);
+        dvc->GetEventHandler()->ProcessEvent(event);
 
-   // send event to wxWidgets:
-    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.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;
+    }
 }
 
 @end
+
 // ============================================================================
 // wxCocoaDataViewControl
 // ============================================================================
-//
-// constructors / destructor
-//
-wxCocoaDataViewControl::wxCocoaDataViewControl(wxWindow* peer, wxPoint const& pos, wxSize const& size, long style)
-                       :wxWidgetCocoaImpl(peer,[[NSScrollView alloc] initWithFrame:wxOSXGetFrameForControl(peer,pos,size)]),
-                        m_DataSource(NULL), m_OutlineView([[wxCocoaOutlineView alloc] init])
+
+wxCocoaDataViewControl::wxCocoaDataViewControl(wxWindow* peer,
+                                               const wxPoint& pos,
+                                               const wxSize& size,
+                                               long style)
+    : wxWidgetCocoaImpl
+      (
+        peer,
+        [[NSScrollView alloc] initWithFrame:wxOSXGetFrameForControl(peer,pos,size)]
+      ),
+      m_DataSource(NULL),
+      m_OutlineView([[wxCocoaOutlineView alloc] init])
 {
- // initialize scrollview (the outline view is part of a scrollview):
-  NSScrollView* scrollview = (NSScrollView*) this->GetWXWidget(); // definition for abbreviational purposes
-  
+    // initialize scrollview (the outline view is part of a scrollview):
+    NSScrollView* scrollview = (NSScrollView*) GetWXWidget();
 
-  [scrollview setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
-  [scrollview setBorderType:NSNoBorder];
-  [scrollview setHasVerticalScroller:YES];
-  [scrollview setHasHorizontalScroller:YES];
-  [scrollview setAutohidesScrollers:YES];
-  [scrollview setDocumentView:this->m_OutlineView];
+    [scrollview setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
+    [scrollview setBorderType:NSNoBorder];
+    [scrollview setHasVerticalScroller:YES];
+    [scrollview setHasHorizontalScroller:YES];
+    [scrollview setAutohidesScrollers:YES];
+    [scrollview setDocumentView:m_OutlineView];
 
- // setting up the native control itself
-  NSUInteger maskGridStyle(NSTableViewGridNone);
+    // initialize the native control itself too
+    InitOutlineView(style);
+}
 
-  [this->m_OutlineView setImplementation:this];
-  [this->m_OutlineView setColumnAutoresizingStyle:NSTableViewSequentialColumnAutoresizingStyle];
-  [this->m_OutlineView setIndentationPerLevel:this->GetDataViewCtrl()->GetIndent()];
-  if (style & wxDV_HORIZ_RULES)
-    maskGridStyle |= NSTableViewSolidHorizontalGridLineMask;
-  if (style & wxDV_VERT_RULES)
-    maskGridStyle |= NSTableViewSolidVerticalGridLineMask;
-  [this->m_OutlineView setGridStyleMask:maskGridStyle];
-  [this->m_OutlineView setAllowsMultipleSelection:           (style & wxDV_MULTIPLE)  != 0];
-  [this->m_OutlineView setUsesAlternatingRowBackgroundColors:(style & wxDV_ROW_LINES) != 0];
+void wxCocoaDataViewControl::InitOutlineView(long style)
+{
+    [m_OutlineView setImplementation:this];
+    [m_OutlineView setColumnAutoresizingStyle:NSTableViewSequentialColumnAutoresizingStyle];
+    [m_OutlineView setIndentationPerLevel:GetDataViewCtrl()->GetIndent()];
+    NSUInteger maskGridStyle(NSTableViewGridNone);
+    if (style & wxDV_HORIZ_RULES)
+        maskGridStyle |= NSTableViewSolidHorizontalGridLineMask;
+    if (style & wxDV_VERT_RULES)
+        maskGridStyle |= NSTableViewSolidVerticalGridLineMask;
+    [m_OutlineView setGridStyleMask:maskGridStyle];
+    [m_OutlineView setAllowsMultipleSelection:           (style & wxDV_MULTIPLE)  != 0];
+    [m_OutlineView setUsesAlternatingRowBackgroundColors:(style & wxDV_ROW_LINES) != 0];
+
+    if ( style & wxDV_NO_HEADER )
+        [m_OutlineView setHeaderView:nil];
 }
 
-wxCocoaDataViewControl::~wxCocoaDataViewControl(void)
+wxCocoaDataViewControl::~wxCocoaDataViewControl()
 {
-  [this->m_DataSource  release];
-  [this->m_OutlineView release];
+    [m_DataSource  release];
+    [m_OutlineView release];
 }
 
 //
 // column related methods (inherited from wxDataViewWidgetImpl)
 //
-bool wxCocoaDataViewControl::ClearColumns(void)
+bool wxCocoaDataViewControl::ClearColumns()
 {
-  bool const bufAllowsMultipleSelection = [this->m_OutlineView allowsMultipleSelection];
-
+    // as there is a bug in NSOutlineView version (OSX 10.5.6 #6555162) the
+    // columns cannot be deleted if there is an outline column in the view;
+    // therefore, the whole view is deleted and newly constructed:
+    [m_OutlineView release];
+    m_OutlineView = [[wxCocoaOutlineView alloc] init];
+    [((NSScrollView*) GetWXWidget()) setDocumentView:m_OutlineView];
+    [m_OutlineView setDataSource:m_DataSource];
 
- // as there is a bug in NSOutlineView version (OSX 10.5.6 #6555162) the columns cannot be deleted if there is an outline column in the view;
- // therefore, the whole view is deleted and newly constructed:
-  [this->m_OutlineView release];
-  this->m_OutlineView = [[wxCocoaOutlineView alloc] init];
-  [((NSScrollView*) this->GetWXWidget()) setDocumentView:this->m_OutlineView];
+    InitOutlineView(GetDataViewCtrl()->GetWindowStyle());
 
- // setting up the native control itself
-  [this->m_OutlineView setImplementation:this];
-  [this->m_OutlineView setColumnAutoresizingStyle:NSTableViewSequentialColumnAutoresizingStyle];
-  [this->m_OutlineView setIndentationPerLevel:this->GetDataViewCtrl()->GetIndent()];
-  if (bufAllowsMultipleSelection)
-    [this->m_OutlineView setAllowsMultipleSelection:YES];
-  [this->m_OutlineView setDataSource:this->m_DataSource];
- // done:
-  return true;
+    return true;
 }
 
 bool wxCocoaDataViewControl::DeleteColumn(wxDataViewColumn* columnPtr)
 {
-  if ([this->m_OutlineView outlineTableColumn] == columnPtr->GetNativeData()->GetNativeColumnPtr())
-    [this->m_OutlineView setOutlineTableColumn:nil]; // due to a bug this does not work
-  [this->m_OutlineView removeTableColumn:columnPtr->GetNativeData()->GetNativeColumnPtr()]; // due to a confirmed bug #6555162 the deletion does not work for
-                                                                                            // outline table columns (... and there is no workaround)
-  return (([this->m_OutlineView columnWithIdentifier:[[[wxPointerObject alloc] initWithPointer:columnPtr] autorelease]]) == -1);
+    if ([m_OutlineView outlineTableColumn] == columnPtr->GetNativeData()->GetNativeColumnPtr())
+        [m_OutlineView setOutlineTableColumn:nil]; // due to a bug this does not work
+    [m_OutlineView removeTableColumn:columnPtr->GetNativeData()->GetNativeColumnPtr()]; // due to a confirmed bug #6555162 the deletion does not work for
+    // outline table columns (... and there is no workaround)
+    return (([m_OutlineView columnWithIdentifier:[wxDVCNSTableColumn identifierForColumnPointer:columnPtr]]) == -1);
 }
 
-void wxCocoaDataViewControl::DoSetExpanderColumn(wxDataViewColumn const* columnPtr)
+void wxCocoaDataViewControl::DoSetExpanderColumn(const wxDataViewColumn *columnPtr)
 {
-  [this->m_OutlineView setOutlineTableColumn:columnPtr->GetNativeData()->GetNativeColumnPtr()];
+    [m_OutlineView setOutlineTableColumn:columnPtr->GetNativeData()->GetNativeColumnPtr()];
 }
 
 wxDataViewColumn* wxCocoaDataViewControl::GetColumn(unsigned int pos) const
 {
-  return reinterpret_cast<wxDataViewColumn*>([[[[this->m_OutlineView tableColumns] objectAtIndex:pos] identifier] pointer]);
+    NSTableColumn* tableColumn = [[m_OutlineView tableColumns] objectAtIndex:pos];
+    return [static_cast<wxDVCNSTableColumn*>(tableColumn) getColumnPointer];
 }
 
-int wxCocoaDataViewControl::GetColumnPosition(wxDataViewColumn const* columnPtr) const
+int wxCocoaDataViewControl::GetColumnPosition(const wxDataViewColumn *columnPtr) const
 {
-  return [this->m_OutlineView columnWithIdentifier:[[[wxPointerObject alloc] initWithPointer:const_cast<wxDataViewColumn*>(columnPtr)] autorelease]];
+    return [m_OutlineView columnWithIdentifier:[wxDVCNSTableColumn identifierForColumnPointer:columnPtr]];
 }
 
 bool wxCocoaDataViewControl::InsertColumn(unsigned int pos, wxDataViewColumn* columnPtr)
 {
-  NSTableColumn* nativeColumn;
+    // create column and set the native data of the dataview column:
+    NSTableColumn *nativeColumn = ::CreateNativeColumn(columnPtr);
+    columnPtr->GetNativeData()->SetNativeColumnPtr(nativeColumn);
+    // as the native control does not allow the insertion of a column at a
+    // specified position the column is first appended and - if necessary -
+    // moved to its final position:
+    [m_OutlineView addTableColumn:nativeColumn];
+    if (pos != static_cast<unsigned int>([m_OutlineView numberOfColumns]-1))
+        [m_OutlineView moveColumn:[m_OutlineView numberOfColumns]-1 toColumn:pos];
+
+    // set columns width now that it can be computed even for autosized columns:
+    columnPtr->SetWidth(columnPtr->GetWidthVariable());
+
+    // done:
+    return true;
+}
+
+void wxCocoaDataViewControl::FitColumnWidthToContent(unsigned int pos)
+{
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
+    const int count = GetCount();
+    NSTableColumn *column = GetColumn(pos)->GetNativeData()->GetNativeColumnPtr();
+
+    class MaxWidthCalculator
+    {
+    public:
+        MaxWidthCalculator(wxCocoaOutlineView *view,
+                           NSTableColumn *column, unsigned columnIndex)
+            : m_width(0),
+              m_view(view),
+              m_column(columnIndex),
+              m_indent(0)
+        {
+            // account for indentation in the column with expander
+            if ( column == [m_view outlineTableColumn] )
+                m_indent = [m_view indentationPerLevel];
+        }
+
+        void UpdateWithWidth(int width)
+        {
+            m_width = wxMax(m_width, width);
+        }
 
+        void UpdateWithRow(int row)
+        {
+            NSCell *cell = [m_view preparedCellAtColumn:m_column row:row];
+            unsigned cellWidth = [cell cellSize].width + 1/*round the float up*/;
 
- // create column and set the native data of the dataview column:
-  nativeColumn = ::CreateNativeColumn(columnPtr);
-  columnPtr->GetNativeData()->SetNativeColumnPtr(nativeColumn);
- // as the native control does not allow the insertion of a column at a specified position the column is first appended and
- // - if necessary - moved to its final position:
-  [this->m_OutlineView addTableColumn:nativeColumn];
-  if (pos != static_cast<unsigned int>([this->m_OutlineView numberOfColumns]-1))
-    [this->m_OutlineView moveColumn:[this->m_OutlineView numberOfColumns]-1 toColumn:pos];
- // done:
-  return true;
+            if ( m_indent )
+                cellWidth += m_indent * ([m_view levelForRow:row] + 1);
+
+            m_width = wxMax(m_width, cellWidth);
+        }
+
+        int GetMaxWidth() const { return m_width; }
+
+    private:
+        int m_width;
+        wxCocoaOutlineView *m_view;
+        unsigned m_column;
+        int m_indent;
+    };
+
+    MaxWidthCalculator calculator(m_OutlineView, column, pos);
+
+    if ( [column headerCell] )
+    {
+        calculator.UpdateWithWidth([[column headerCell] cellSize].width + 1/*round the float up*/);
+    }
+
+    // The code below deserves some explanation. For very large controls, we
+    // simply can't afford to calculate sizes for all items, it takes too
+    // long. So the best we can do is to check the first and the last N/2
+    // items in the control for some sufficiently large N and calculate best
+    // sizes from that. That can result in the calculated best width being too
+    // small for some outliers, but it's better to get slightly imperfect
+    // result than to wait several seconds after every update. To avoid highly
+    // visible miscalculations, we also include all currently visible items
+    // no matter what.  Finally, the value of N is determined dynamically by
+    // measuring how much time we spent on the determining item widths so far.
+
+#if wxUSE_STOPWATCH
+    int top_part_end = count;
+    static const long CALC_TIMEOUT = 20/*ms*/;
+    // don't call wxStopWatch::Time() too often
+    static const unsigned CALC_CHECK_FREQ = 100;
+    wxStopWatch timer;
+#else
+    // use some hard-coded limit, that's the best we can do without timer
+    int top_part_end = wxMin(500, count);
+#endif // wxUSE_STOPWATCH/!wxUSE_STOPWATCH
+
+    int row = 0;
+
+    for ( row = 0; row < top_part_end; row++ )
+    {
+#if wxUSE_STOPWATCH
+        if ( row % CALC_CHECK_FREQ == CALC_CHECK_FREQ-1 &&
+             timer.Time() > CALC_TIMEOUT )
+            break;
+#endif // wxUSE_STOPWATCH
+        calculator.UpdateWithRow(row);
+    }
+
+    // row is the first unmeasured item now; that's our value of N/2
+
+    if ( row < count )
+    {
+        top_part_end = row;
+
+        // add bottom N/2 items now:
+        const int bottom_part_start = wxMax(row, count - row);
+        for ( row = bottom_part_start; row < count; row++ )
+            calculator.UpdateWithRow(row);
+
+        // finally, include currently visible items in the calculation:
+        const NSRange visible = [m_OutlineView rowsInRect:[m_OutlineView visibleRect]];
+        const int first_visible = wxMax(visible.location, top_part_end);
+        const int last_visible = wxMin(first_visible + visible.length, bottom_part_start);
+
+        for ( row = first_visible; row < last_visible; row++ )
+            calculator.UpdateWithRow(row);
+
+        wxLogTrace("dataview",
+                   "determined best size from %d top, %d bottom plus %d more visible items out of %d total",
+                   top_part_end,
+                   count - bottom_part_start,
+                   wxMax(0, last_visible - first_visible),
+                   count);
+    }
+
+    [column setWidth:calculator.GetMaxWidth()];
+#endif // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
 }
 
 //
 // item related methods (inherited from wxDataViewWidgetImpl)
 //
-bool wxCocoaDataViewControl::Add(wxDataViewItem const& parent, wxDataViewItem const& WXUNUSED(item))
+bool wxCocoaDataViewControl::Add(const wxDataViewItem& parent, const wxDataViewItem& WXUNUSED(item))
 {
-  if (parent.IsOk())
-    [this->m_OutlineView reloadItem:[this->m_DataSource getDataViewItemFromBuffer:parent] reloadChildren:YES];
-  else
-    [this->m_OutlineView reloadData];
-  return true;
+    if (parent.IsOk())
+        [m_OutlineView reloadItem:[m_DataSource getDataViewItemFromBuffer:parent] reloadChildren:YES];
+    else
+        [m_OutlineView reloadData];
+    return true;
 }
 
-bool wxCocoaDataViewControl::Add(wxDataViewItem const& parent, wxDataViewItemArray const& WXUNUSED(items))
+bool wxCocoaDataViewControl::Add(const wxDataViewItem& parent, const wxDataViewItemArray& WXUNUSED(items))
 {
-  if (parent.IsOk())
-    [this->m_OutlineView reloadItem:[this->m_DataSource getDataViewItemFromBuffer:parent] reloadChildren:YES];
-  else
-    [this->m_OutlineView reloadData];
-  return true;
+    if (parent.IsOk())
+        [m_OutlineView reloadItem:[m_DataSource getDataViewItemFromBuffer:parent] reloadChildren:YES];
+    else
+        [m_OutlineView reloadData];
+    return true;
 }
 
-void wxCocoaDataViewControl::Collapse(wxDataViewItem const& item)
+void wxCocoaDataViewControl::Collapse(const wxDataViewItem& item)
 {
-  [this->m_OutlineView collapseItem:[this->m_DataSource getDataViewItemFromBuffer:item]];
+    [m_OutlineView collapseItem:[m_DataSource getDataViewItemFromBuffer:item]];
 }
 
-void wxCocoaDataViewControl::EnsureVisible(wxDataViewItem const& item, wxDataViewColumn const* columnPtr)
+void wxCocoaDataViewControl::EnsureVisible(const wxDataViewItem& item, const wxDataViewColumn *columnPtr)
 {
-  if (item.IsOk())
-  {
-    [this->m_OutlineView scrollRowToVisible:[this->m_OutlineView rowForItem:[this->m_DataSource getDataViewItemFromBuffer:item]]];
-    if (columnPtr != NULL)
-      [this->m_OutlineView scrollColumnToVisible:this->GetColumnPosition(columnPtr)];
-  }
+    if (item.IsOk())
+    {
+        [m_OutlineView scrollRowToVisible:[m_OutlineView rowForItem:[m_DataSource getDataViewItemFromBuffer:item]]];
+        if (columnPtr)
+            [m_OutlineView scrollColumnToVisible:GetColumnPosition(columnPtr)];
+    }
 }
 
-void wxCocoaDataViewControl::Expand(wxDataViewItem const& item)
+void wxCocoaDataViewControl::Expand(const wxDataViewItem& item)
 {
-  [this->m_OutlineView expandItem:[this->m_DataSource getDataViewItemFromBuffer:item]];
+    [m_OutlineView expandItem:[m_DataSource getDataViewItemFromBuffer:item]];
 }
 
-unsigned int wxCocoaDataViewControl::GetCount(void) const
+unsigned int wxCocoaDataViewControl::GetCount() const
 {
-  return [this->m_OutlineView numberOfRows];
+    return [m_OutlineView numberOfRows];
 }
 
-wxRect wxCocoaDataViewControl::GetRectangle(wxDataViewItem const& item, wxDataViewColumn const* columnPtr)
+wxRect wxCocoaDataViewControl::GetRectangle(const wxDataViewItem& item, const wxDataViewColumn *columnPtr)
 {
-  return wxFromNSRect([m_osxView superview],[this->m_OutlineView frameOfCellAtColumn:this->GetColumnPosition(columnPtr)
-                                             row:[this->m_OutlineView rowForItem:[this->m_DataSource getDataViewItemFromBuffer:item]]]);
+    return wxFromNSRect([m_osxView superview],[m_OutlineView frameOfCellAtColumn:GetColumnPosition(columnPtr)
+            row:[m_OutlineView rowForItem:[m_DataSource getDataViewItemFromBuffer:item]]]);
 }
 
-bool wxCocoaDataViewControl::IsExpanded(wxDataViewItem const& item) const
+bool wxCocoaDataViewControl::IsExpanded(const wxDataViewItem& item) const
 {
-  return [this->m_OutlineView isItemExpanded:[this->m_DataSource getDataViewItemFromBuffer:item]];
+    return [m_OutlineView isItemExpanded:[m_DataSource getDataViewItemFromBuffer:item]];
 }
 
-bool wxCocoaDataViewControl::Reload(void)
+bool wxCocoaDataViewControl::Reload()
 {
-  [this->m_DataSource clearBuffers];
-  [this->m_OutlineView scrollColumnToVisible:0];
-  [this->m_OutlineView scrollRowToVisible:0];
-  [this->m_OutlineView reloadData];
-  return true;
+    [m_DataSource clearBuffers];
+    [m_OutlineView reloadData];
+    [m_OutlineView scrollColumnToVisible:0];
+    [m_OutlineView scrollRowToVisible:0];
+    return true;
 }
 
-bool wxCocoaDataViewControl::Remove(wxDataViewItem const& parent, wxDataViewItem const& WXUNUSED(item))
+bool wxCocoaDataViewControl::Remove(const wxDataViewItem& parent, const wxDataViewItem& WXUNUSED(item))
 {
-  if (parent.IsOk())
-    [this->m_OutlineView reloadItem:[this->m_DataSource getDataViewItemFromBuffer:parent] reloadChildren:YES];
-  else
-    [this->m_OutlineView reloadData];
-  return true;
+    if (parent.IsOk())
+        [m_OutlineView reloadItem:[m_DataSource getDataViewItemFromBuffer:parent] reloadChildren:YES];
+    else
+        [m_OutlineView reloadData];
+    return true;
 }
 
-bool wxCocoaDataViewControl::Remove(wxDataViewItem const& parent, wxDataViewItemArray const& WXUNUSED(item))
+bool wxCocoaDataViewControl::Remove(const wxDataViewItem& parent, const wxDataViewItemArray& WXUNUSED(item))
 {
-  if (parent.IsOk())
-    [this->m_OutlineView reloadItem:[this->m_DataSource getDataViewItemFromBuffer:parent] reloadChildren:YES];
-  else
-    [this->m_OutlineView reloadData];
-  return true;
+    if (parent.IsOk())
+        [m_OutlineView reloadItem:[m_DataSource getDataViewItemFromBuffer:parent] reloadChildren:YES];
+    else
+        [m_OutlineView reloadData];
+    return true;
 }
 
-bool wxCocoaDataViewControl::Update(wxDataViewColumn const* columnPtr)
+bool wxCocoaDataViewControl::Update(const wxDataViewColumn *columnPtr)
 {
-  return false;
+    wxUnusedVar(columnPtr);
+    
+    return false;
 }
 
-bool wxCocoaDataViewControl::Update(wxDataViewItem const& WXUNUSED(parent), wxDataViewItem const& item)
+bool wxCocoaDataViewControl::Update(const wxDataViewItem& WXUNUSED(parent), const wxDataViewItem& item)
 {
-  [this->m_OutlineView reloadItem:[this->m_DataSource getDataViewItemFromBuffer:item]];
-  return true;
+    [m_OutlineView reloadItem:[m_DataSource getDataViewItemFromBuffer:item]];
+    return true;
 }
 
-bool wxCocoaDataViewControl::Update(wxDataViewItem const& WXUNUSED(parent), wxDataViewItemArray const& items)
+bool wxCocoaDataViewControl::Update(const wxDataViewItem& WXUNUSED(parent), const wxDataViewItemArray& items)
 {
-  for (size_t i=0; i<items.GetCount(); ++i)
-    [this->m_OutlineView reloadItem:[this->m_DataSource getDataViewItemFromBuffer:items[i]]];
-  return true;
+    for (size_t i=0; i<items.GetCount(); ++i)
+        [m_OutlineView reloadItem:[m_DataSource getDataViewItemFromBuffer:items[i]]];
+    return true;
 }
 
 //
@@ -1847,88 +2281,122 @@ bool wxCocoaDataViewControl::Update(wxDataViewItem const& WXUNUSED(parent), wxDa
 //
 bool wxCocoaDataViewControl::AssociateModel(wxDataViewModel* model)
 {
-  [this->m_DataSource release];
-  if (model != NULL)
-  {
-    this->m_DataSource = [[wxCocoaOutlineDataSource alloc] init];
-    [this->m_DataSource setImplementation:this];
-    [this->m_DataSource setModel:model];
-  }
-  else
-    this->m_DataSource = NULL;
-  [this->m_OutlineView setDataSource:this->m_DataSource]; // if there is a data source the data is immediately going to be requested
-  return true;
+    [m_DataSource release];
+    if (model)
+    {
+        m_DataSource = [[wxCocoaOutlineDataSource alloc] init];
+        [m_DataSource setImplementation:this];
+        [m_DataSource setModel:model];
+    }
+    else
+        m_DataSource = NULL;
+    [m_OutlineView setDataSource:m_DataSource]; // if there is a data source the data is immediately going to be requested
+    return true;
 }
 
 //
 // selection related methods (inherited from wxDataViewWidgetImpl)
 //
+
+wxDataViewItem wxCocoaDataViewControl::GetCurrentItem() const
+{
+    return wxDataViewItem([[m_OutlineView itemAtRow:[m_OutlineView selectedRow]] pointer]);
+}
+
+wxDataViewColumn *wxCocoaDataViewControl::GetCurrentColumn() const
+{
+    int col = [m_OutlineView selectedColumn];
+    if ( col == -1 )
+        return NULL;
+    return GetColumn(col);
+}
+
+void wxCocoaDataViewControl::SetCurrentItem(const wxDataViewItem& item)
+{
+    // We can't have unselected current item in a NSTableView, as the
+    // documentation of its deselectRow method explains, the control will
+    // automatically change the current item to the closest still selected item
+    // if the current item is deselected. So we have no choice but to select
+    // the item in the same time as making it current.
+    Select(item);
+}
+
+int wxCocoaDataViewControl::GetSelectedItemsCount() const
+{
+    return [m_OutlineView numberOfSelectedRows];
+}
+
 int wxCocoaDataViewControl::GetSelections(wxDataViewItemArray& sel) const
 {
-  NSIndexSet* selectedRowIndexes([this->m_OutlineView selectedRowIndexes]);
-  
-  NSUInteger indexRow;
+    NSIndexSet* selectedRowIndexes([m_OutlineView selectedRowIndexes]);
 
-  
-  sel.Empty();
-  sel.Alloc([selectedRowIndexes count]);
-  indexRow = [selectedRowIndexes firstIndex];
-  while (indexRow != NSNotFound)
-  {
-    sel.Add(wxDataViewItem([[this->m_OutlineView itemAtRow:indexRow] pointer]));
-    indexRow = [selectedRowIndexes indexGreaterThanIndex:indexRow];
-  }
-  return sel.GetCount();
+    NSUInteger indexRow;
+
+
+    sel.Empty();
+    sel.Alloc([selectedRowIndexes count]);
+    indexRow = [selectedRowIndexes firstIndex];
+    while (indexRow != NSNotFound)
+    {
+        sel.Add(wxDataViewItem([[m_OutlineView itemAtRow:indexRow] pointer]));
+        indexRow = [selectedRowIndexes indexGreaterThanIndex:indexRow];
+    }
+    return sel.GetCount();
 }
 
-bool wxCocoaDataViewControl::IsSelected(wxDataViewItem const& item) const
+bool wxCocoaDataViewControl::IsSelected(const wxDataViewItem& item) const
 {
-  return [this->m_OutlineView isRowSelected:[this->m_OutlineView rowForItem:[this->m_DataSource getDataViewItemFromBuffer:item]]];
+    return [m_OutlineView isRowSelected:[m_OutlineView rowForItem:[m_DataSource getDataViewItemFromBuffer:item]]];
 }
 
-void wxCocoaDataViewControl::Select(wxDataViewItem const& item)
+void wxCocoaDataViewControl::Select(const wxDataViewItem& item)
 {
-  if (item.IsOk())
-    [this->m_OutlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:[this->m_OutlineView rowForItem:[this->m_DataSource getDataViewItemFromBuffer:item]]]
-                        byExtendingSelection:NO];
+    if (item.IsOk())
+        [m_OutlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:[m_OutlineView rowForItem:[m_DataSource getDataViewItemFromBuffer:item]]]
+            byExtendingSelection:GetDataViewCtrl()->HasFlag(wxDV_MULTIPLE) ? YES : NO];
 }
 
-void wxCocoaDataViewControl::SelectAll(void)
+void wxCocoaDataViewControl::SelectAll()
 {
-  [this->m_OutlineView selectAll:this->m_OutlineView];
+    [m_OutlineView selectAll:m_OutlineView];
 }
 
-void wxCocoaDataViewControl::Unselect(wxDataViewItem const& item)
+void wxCocoaDataViewControl::Unselect(const wxDataViewItem& item)
 {
-  if (item.IsOk())
-    [this->m_OutlineView deselectRow:[this->m_OutlineView rowForItem:[this->m_DataSource getDataViewItemFromBuffer:item]]];
+    if (item.IsOk())
+        [m_OutlineView deselectRow:[m_OutlineView rowForItem:[m_DataSource getDataViewItemFromBuffer:item]]];
 }
 
-void wxCocoaDataViewControl::UnselectAll(void)
+void wxCocoaDataViewControl::UnselectAll()
 {
-  [this->m_OutlineView deselectAll:this->m_OutlineView];
+    [m_OutlineView deselectAll:m_OutlineView];
 }
 
 //
 // sorting related methods
 //
-wxDataViewColumn* wxCocoaDataViewControl::GetSortingColumn(void) const
+wxDataViewColumn* wxCocoaDataViewControl::GetSortingColumn() const
 {
-  NSArray* const columns = [this->m_OutlineView tableColumns];
+    NSArray* const columns = [m_OutlineView tableColumns];
 
-  UInt32 const noOfColumns = [columns count];
+    UInt32 const noOfColumns = [columns count];
 
 
-  for (UInt32 i=0; i<noOfColumns; ++i)
-    if ([[columns objectAtIndex:i] sortDescriptorPrototype] != nil)
-      return reinterpret_cast<wxDataViewColumn*>([[[columns objectAtIndex:i] identifier] pointer]);
-  return NULL;
+    for (UInt32 i=0; i<noOfColumns; ++i)
+        if ([[columns objectAtIndex:i] sortDescriptorPrototype] != nil)
+            return GetColumn(i);
+    return NULL;
+}
+
+void wxCocoaDataViewControl::Resort()
+{
+    [m_DataSource clearChildren];
+    [m_OutlineView reloadData];
 }
 
-void wxCocoaDataViewControl::Resort(void)
+void wxCocoaDataViewControl::StartEditor( const wxDataViewItem & item, unsigned int column )
 {
-  [this->m_DataSource clearChildren];
-  [this->m_OutlineView reloadData];
+    [m_OutlineView editColumn:column row:[m_OutlineView rowForItem:[m_DataSource getDataViewItemFromBuffer:item]] withEvent:nil select:YES];
 }
 
 //
@@ -1936,40 +2404,40 @@ void wxCocoaDataViewControl::Resort(void)
 //
 void wxCocoaDataViewControl::DoSetIndent(int indent)
 {
-  [this->m_OutlineView setIndentationPerLevel:static_cast<CGFloat>(indent)];
+    [m_OutlineView setIndentationPerLevel:static_cast<CGFloat>(indent)];
 }
 
-void wxCocoaDataViewControl::HitTest(wxPoint const& point, wxDataViewItem& item, wxDataViewColumn*& columnPtr) const
+void wxCocoaDataViewControl::HitTest(const wxPoint& point, wxDataViewItem& item, wxDataViewColumn*& columnPtr) const
 {
-  NSPoint const nativePoint = wxToNSPoint((NSScrollView*) this->GetWXWidget(),point);
+    NSPoint const nativePoint = wxToNSPoint((NSScrollView*) GetWXWidget(),point);
 
-  int indexColumn;
-  int indexRow;
+    int indexColumn;
+    int indexRow;
 
-  
-  indexColumn = [this->m_OutlineView columnAtPoint:nativePoint];
-  indexRow    = [this->m_OutlineView rowAtPoint:   nativePoint];
-  if ((indexColumn >= 0) && (indexRow >= 0))
-  {
-    columnPtr = reinterpret_cast<wxDataViewColumn*>([[[[this->m_OutlineView tableColumns] objectAtIndex:indexColumn] identifier] pointer]);
-    item      = wxDataViewItem([[this->m_OutlineView itemAtRow:indexRow] pointer]);
-  }
-  else
-  {
-    columnPtr = NULL;
-    item      = wxDataViewItem();
-  }
+
+    indexColumn = [m_OutlineView columnAtPoint:nativePoint];
+    indexRow    = [m_OutlineView rowAtPoint:   nativePoint];
+    if ((indexColumn >= 0) && (indexRow >= 0))
+    {
+        columnPtr = GetColumn(indexColumn);
+        item      = wxDataViewItem([[m_OutlineView itemAtRow:indexRow] pointer]);
+    }
+    else
+    {
+        columnPtr = NULL;
+        item      = wxDataViewItem();
+    }
 }
 
-void wxCocoaDataViewControl::SetRowHeight(wxDataViewItem const& WXUNUSED(item), unsigned int WXUNUSED(height))
- // Not supported by the native control
+void wxCocoaDataViewControl::SetRowHeight(const wxDataViewItem& WXUNUSED(item), unsigned int WXUNUSED(height))
   // Not supported by the native control
 {
 }
 
-void wxCocoaDataViewControl::OnSize(void)
+void wxCocoaDataViewControl::OnSize()
 {
-  if ([this->m_OutlineView numberOfColumns] == 1)
-    [this->m_OutlineView sizeLastColumnToFit];
+    if ([m_OutlineView numberOfColumns] == 1)
+        [m_OutlineView sizeLastColumnToFit];
 }
 
 //
@@ -1977,122 +2445,296 @@ void wxCocoaDataViewControl::OnSize(void)
 //
 wxDataFormat wxCocoaDataViewControl::GetDnDDataFormat(wxDataObjectComposite* dataObjects)
 {
-  wxDataFormat resultFormat;
+    wxDataFormat resultFormat;
+    if ( !dataObjects )
+        return resultFormat;
 
-
-  if (dataObjects != NULL)
-  {
     bool compatible(true);
 
     size_t const noOfFormats = dataObjects->GetFormatCount();
     size_t       indexFormat;
 
     wxDataFormat* formats;
-    
-   // get all formats and check afterwards if the formats are compatible; if they are compatible the preferred format is returned otherwise
-   // wxDF_INVALID is returned;
-   // currently compatible types (ordered by priority are):
-   //  - wxDF_UNICODETEXT - wxDF_TEXT
+
+    // get all formats and check afterwards if the formats are compatible; if
+    // they are compatible the preferred format is returned otherwise
+    // wxDF_INVALID is returned;
+    // currently compatible types (ordered by priority are):
+    //  - wxDF_UNICODETEXT - wxDF_TEXT
     formats = new wxDataFormat[noOfFormats];
     dataObjects->GetAllFormats(formats);
     indexFormat = 0;
     while ((indexFormat < noOfFormats) && compatible)
     {
-      switch (resultFormat.GetType())
-      {
-        case wxDF_INVALID:
-          resultFormat.SetType(formats[indexFormat].GetType()); // first format (should only be reached if indexFormat == 0)
-          break;
+        switch (resultFormat.GetType())
+        {
+            case wxDF_INVALID:
+                resultFormat.SetType(formats[indexFormat].GetType()); // first format (should only be reached if indexFormat == 0)
+                break;
+            case wxDF_TEXT:
+                if (formats[indexFormat].GetType() == wxDF_UNICODETEXT)
+                    resultFormat.SetType(wxDF_UNICODETEXT);
+                else // incompatible
+                {
+                    resultFormat.SetType(wxDF_INVALID);
+                    compatible = false;
+                }
+                break;
+            case wxDF_UNICODETEXT:
+                if (formats[indexFormat].GetType() != wxDF_TEXT)
+                {
+                    resultFormat.SetType(wxDF_INVALID);
+                    compatible = false;
+                }
+                break;
+            default:
+                resultFormat.SetType(wxDF_INVALID); // not (yet) supported format
+                compatible = false;
+        }
+        ++indexFormat;
+    }
+
+    delete[] formats;
+
+    return resultFormat;
+}
+
+wxDataObjectComposite* wxCocoaDataViewControl::GetDnDDataObjects(NSData* dataObject) const
+{
+    wxDataFormatId dataFormatID;
+
+
+    [dataObject getBytes:&dataFormatID length:sizeof(wxDataFormatId)];
+    switch (dataFormatID)
+    {
         case wxDF_TEXT:
-          if (formats[indexFormat].GetType() == wxDF_UNICODETEXT)
-            resultFormat.SetType(wxDF_UNICODETEXT);
-          else // incompatible
-          {
-            resultFormat.SetType(wxDF_INVALID);
-            compatible = false;
-          }
-          break;
         case wxDF_UNICODETEXT:
-          if (formats[indexFormat].GetType() != wxDF_TEXT)
-          {
-            resultFormat.SetType(wxDF_INVALID);
-            compatible = false;
-          }
-          break;
+            {
+                wxTextDataObject* textDataObject(new wxTextDataObject());
+
+                if (textDataObject->SetData(wxDataFormat(dataFormatID),[dataObject length]-sizeof(wxDataFormatId),static_cast<char const*>([dataObject bytes])+sizeof(wxDataFormatId)))
+                {
+                    wxDataObjectComposite* dataObjectComposite(new wxDataObjectComposite());
+
+                    dataObjectComposite->Add(textDataObject);
+                    return dataObjectComposite;
+                }
+                else
+                {
+                    delete textDataObject;
+                    return NULL;
+                }
+            }
+            break;
         default:
-          resultFormat.SetType(wxDF_INVALID); // not (yet) supported format
-          compatible = false;
-      }
-      ++indexFormat;
-    } /* while */
-   // clean up:
-    delete[] formats;
-  }
-  return resultFormat;
+            return NULL;
+    }
 }
 
-wxDataObjectComposite* wxCocoaDataViewControl::GetDnDDataObjects(NSData* dataObject) const
+id wxCocoaDataViewControl::GetItemAtRow(int row) const
 {
-  wxDataFormatId dataFormatID;
+    return [m_OutlineView itemAtRow:row];
+}
 
-  
-  [dataObject getBytes:&dataFormatID length:sizeof(wxDataFormatId)];
-  switch (dataFormatID)
-  {
-    case wxDF_TEXT:
-    case wxDF_UNICODETEXT:
-      {
-        wxTextDataObject* textDataObject(new wxTextDataObject());
-        
-        if (textDataObject->SetData(wxDataFormat(dataFormatID),[dataObject length]-sizeof(wxDataFormatId),reinterpret_cast<char const*>([dataObject bytes])+sizeof(wxDataFormatId)))
-        {
-          wxDataObjectComposite* dataObjectComposite(new wxDataObjectComposite());
+// ----------------------------------------------------------------------------
+// wxDataViewRendererNativeData
+// ----------------------------------------------------------------------------
 
-          dataObjectComposite->Add(textDataObject);
-          return dataObjectComposite;
-        }
-        else
-        {
-          delete textDataObject;
-          return NULL;
-        }
-      }
-      break;
-    default:
-      return NULL;
-  }
+void wxDataViewRendererNativeData::Init()
+{
+    m_origFont = NULL;
+    m_origTextColour = NULL;
+    m_ellipsizeMode = wxELLIPSIZE_MIDDLE;
+
+    if ( m_ColumnCell )
+        ApplyLineBreakMode(m_ColumnCell);
+}
+
+void wxDataViewRendererNativeData::ApplyLineBreakMode(NSCell *cell)
+{
+    NSLineBreakMode nsMode = NSLineBreakByWordWrapping;
+    switch ( m_ellipsizeMode )
+    {
+        case wxELLIPSIZE_NONE:
+            nsMode = NSLineBreakByClipping;
+            break;
+
+        case wxELLIPSIZE_START:
+            nsMode = NSLineBreakByTruncatingHead;
+            break;
+
+        case wxELLIPSIZE_MIDDLE:
+            nsMode = NSLineBreakByTruncatingMiddle;
+            break;
+
+        case wxELLIPSIZE_END:
+            nsMode = NSLineBreakByTruncatingTail;
+            break;
+    }
+
+    wxASSERT_MSG( nsMode != NSLineBreakByWordWrapping, "unknown wxEllipsizeMode" );
+
+    [cell setLineBreakMode: nsMode];
 }
 
 // ---------------------------------------------------------
 // wxDataViewRenderer
 // ---------------------------------------------------------
-wxDataViewRenderer::wxDataViewRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align)
-                   :wxDataViewRendererBase(varianttype,mode,align), m_alignment(align), m_mode(mode), m_NativeDataPtr(NULL)
+
+wxDataViewRenderer::wxDataViewRenderer(const wxString& varianttype,
+                                       wxDataViewCellMode mode,
+                                       int align)
+    : wxDataViewRendererBase(varianttype, mode, align),
+      m_alignment(align),
+      m_mode(mode),
+      m_NativeDataPtr(NULL)
 {
 }
 
-wxDataViewRenderer::~wxDataViewRenderer(void)
+wxDataViewRenderer::~wxDataViewRenderer()
 {
-  delete this->m_NativeDataPtr;
+    delete m_NativeDataPtr;
 }
 
 void wxDataViewRenderer::SetAlignment(int align)
 {
-  this->m_alignment = align;
-  [this->GetNativeData()->GetColumnCell() setAlignment:ConvertToNativeHorizontalTextAlignment(align)];
+    m_alignment = align;
+    [GetNativeData()->GetColumnCell() setAlignment:ConvertToNativeHorizontalTextAlignment(align)];
 }
 
 void wxDataViewRenderer::SetMode(wxDataViewCellMode mode)
 {
-  this->m_mode = mode;
-  if (this->GetOwner() != NULL)
-    [this->GetOwner()->GetNativeData()->GetNativeColumnPtr() setEditable:(mode == wxDATAVIEW_CELL_EDITABLE)];
+    m_mode = mode;
+    if ( GetOwner() )
+        [GetOwner()->GetNativeData()->GetNativeColumnPtr() setEditable:(mode == wxDATAVIEW_CELL_EDITABLE)];
 }
 
 void wxDataViewRenderer::SetNativeData(wxDataViewRendererNativeData* newNativeDataPtr)
 {
-  delete this->m_NativeDataPtr;
-  this->m_NativeDataPtr = newNativeDataPtr;
+    delete m_NativeDataPtr;
+    m_NativeDataPtr = newNativeDataPtr;
+}
+
+void wxDataViewRenderer::EnableEllipsize(wxEllipsizeMode mode)
+{
+    // we need to store this value to apply it to the columns headerCell in
+    // CreateNativeColumn()
+    GetNativeData()->SetEllipsizeMode(mode);
+
+    // but we may already apply it to the column cell which will be used for
+    // this column
+    GetNativeData()->ApplyLineBreakMode(GetNativeData()->GetColumnCell());
+}
+
+wxEllipsizeMode wxDataViewRenderer::GetEllipsizeMode() const
+{
+    return GetNativeData()->GetEllipsizeMode();
+}
+
+void
+wxDataViewRenderer::OSXOnCellChanged(NSObject *object,
+                                     const wxDataViewItem& item,
+                                     unsigned col)
+{
+    // TODO: This code should really be removed and this function be made pure
+    //       virtual. We just need to decide what to do with custom renderers
+    //       (i.e. wxDataViewCustomRenderer), currently OS X "in place" editing
+    //       which doesn't really create an editor control is not compatible
+    //       with the in place editing under other platforms.
+
+    wxVariant value;
+    if ( [object isKindOfClass:[NSString class]] )
+        value = ObjectToString(object);
+    else if ( [object isKindOfClass:[NSNumber class]] )
+        value = ObjectToLong(object);
+    else if ( [object isKindOfClass:[NSDate class]] )
+        value = ObjectToDate(object);
+    else
+    {
+        wxFAIL_MSG( wxString::Format
+                    (
+                     "unknown value type %s",
+                     wxCFStringRef::AsString([object className])
+                    ));
+        return;
+    }
+
+    wxDataViewModel *model = GetOwner()->GetOwner()->GetModel();
+    model->ChangeValue(value, item, col);
+}
+
+void wxDataViewRenderer::OSXApplyAttr(const wxDataViewItemAttr& attr)
+{
+    wxDataViewRendererNativeData * const data = GetNativeData();
+    NSCell * const cell = data->GetItemCell();
+
+    // set the font and text colour to use: we need to do it if we had ever
+    // changed them before, even if this item itself doesn't have any special
+    // attributes as otherwise it would reuse the attributes from the previous
+    // cell rendered using the same renderer
+    NSFont *font = NULL;
+    NSColor *colText = NULL;
+
+    if ( attr.HasFont() )
+    {
+        font = data->GetOriginalFont();
+        if ( !font )
+        {
+            // this is the first time we're setting the font, remember the
+            // original one before changing it
+            font = [cell font];
+            data->SaveOriginalFont(font);
+        }
+
+        if ( font )
+        {
+            // FIXME: using wxFont methods here doesn't work for some reason
+            NSFontManager * const fm = [NSFontManager sharedFontManager];
+            if ( attr.GetBold() )
+                font = [fm convertFont:font toHaveTrait:NSBoldFontMask];
+            if ( attr.GetItalic() )
+                font = [fm convertFont:font toHaveTrait:NSItalicFontMask];
+        }
+        //else: can't change font if the cell doesn't have any
+    }
+
+    if ( attr.HasColour() )
+    {
+        // we can set font for any cell but only NSTextFieldCell provides
+        // a method for setting text colour so check that this method is
+        // available before using it
+        if ( [cell respondsToSelector:@selector(setTextColor:)] &&
+                [cell respondsToSelector:@selector(textColor)] )
+        {
+            if ( !data->GetOriginalTextColour() )
+            {
+                // the cast to (untyped) id is safe because of the check above
+                data->SaveOriginalTextColour([(id)cell textColor]);
+            }
+
+            const wxColour& c = attr.GetColour();
+            colText = [NSColor colorWithCalibratedRed:c.Red() / 255.
+                green:c.Green() / 255.
+                blue:c.Blue() / 255.
+                alpha:c.Alpha() / 255.];
+        }
+    }
+
+    if ( !font )
+        font = data->GetOriginalFont();
+    if ( !colText )
+        colText = data->GetOriginalTextColour();
+
+    if ( font )
+        [cell setFont:font];
+
+    if ( colText )
+        [(id)cell setTextColor:colText];
+}
+
+void wxDataViewRenderer::OSXApplyEnabled(bool enabled)
+{
+    [GetNativeData()->GetItemCell() setEnabled:enabled];
 }
 
 IMPLEMENT_ABSTRACT_CLASS(wxDataViewRenderer,wxDataViewRendererBase)
@@ -2100,18 +2742,32 @@ IMPLEMENT_ABSTRACT_CLASS(wxDataViewRenderer,wxDataViewRendererBase)
 // ---------------------------------------------------------
 // wxDataViewCustomRenderer
 // ---------------------------------------------------------
-wxDataViewCustomRenderer::wxDataViewCustomRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align)
-                         :wxDataViewRenderer(varianttype,mode,align), m_editorCtrlPtr(NULL), m_DCPtr(NULL)
+wxDataViewCustomRenderer::wxDataViewCustomRenderer(const wxString& varianttype,
+                                                   wxDataViewCellMode mode,
+                                                   int align)
+    : wxDataViewCustomRendererBase(varianttype, mode, align),
+      m_editorCtrlPtr(NULL),
+      m_DCPtr(NULL)
 {
-  this->SetNativeData(new wxDataViewRendererNativeData([[wxCustomCell alloc] init]));
+    SetNativeData(new wxDataViewRendererNativeData([[wxCustomCell alloc] init]));
 }
 
-bool wxDataViewCustomRenderer::Render()
+bool wxDataViewCustomRenderer::MacRender()
 {
-  [this->GetNativeData()->GetItemCell() setObjectValue:[[[wxCustomRendererObject alloc] initWithRenderer:this
-                                                                                                    item:this->GetNativeData()->GetItem()
-                                                                                                  column:this->GetNativeData()->GetColumnPtr()] autorelease]];
-  return true;
+    [GetNativeData()->GetItemCell() setObjectValue:[[[wxCustomRendererObject alloc] initWithRenderer:this] autorelease]];
+    return true;
+}
+
+void wxDataViewCustomRenderer::OSXApplyAttr(const wxDataViewItemAttr& attr)
+{
+    // simply save the attribute so that it could be reused from our Render()
+    SetAttr(attr);
+
+    // it's not necessary to call the base class version which sets the cell
+    // properties to correspond to this attribute because we currently don't
+    // use any NSCell methods in custom renderers anyhow but if we ever start
+    // doing this (e.g. override RenderText() here to use NSTextFieldCell
+    // methods), then we should pass it on to wxDataViewRenderer here
 }
 
 IMPLEMENT_ABSTRACT_CLASS(wxDataViewCustomRenderer, wxDataViewRenderer)
@@ -2119,31 +2775,41 @@ IMPLEMENT_ABSTRACT_CLASS(wxDataViewCustomRenderer, wxDataViewRenderer)
 // ---------------------------------------------------------
 // wxDataViewTextRenderer
 // ---------------------------------------------------------
-wxDataViewTextRenderer::wxDataViewTextRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align)
-                       :wxDataViewRenderer(varianttype,mode,align)
+wxDataViewTextRenderer::wxDataViewTextRenderer(const wxString& varianttype,
+                                               wxDataViewCellMode mode,
+                                               int align)
+    : wxDataViewRenderer(varianttype,mode,align)
 {
-  NSTextFieldCell* cell;
-  
-  
-  cell = [[NSTextFieldCell alloc] init];
-  [cell setAlignment:ConvertToNativeHorizontalTextAlignment(align)];
-  [cell setLineBreakMode:NSLineBreakByTruncatingMiddle];
-  this->SetNativeData(new wxDataViewRendererNativeData(cell));
-  [cell release];
+    NSTextFieldCell* cell;
+
+
+    cell = [[NSTextFieldCell alloc] init];
+    [cell setAlignment:ConvertToNativeHorizontalTextAlignment(align)];
+    SetNativeData(new wxDataViewRendererNativeData(cell));
+    [cell release];
 }
 
-bool wxDataViewTextRenderer::Render()
+bool wxDataViewTextRenderer::MacRender()
 {
-  if (this->GetValue().GetType() == this->GetVariantType())
-  {
-    [this->GetNativeData()->GetItemCell() setObjectValue:wxCFStringRef(this->GetValue().GetString()).AsNSString()];
-    return true;
-  }
-  else
-  {
-    wxFAIL_MSG(wxString(_("Text renderer cannot render value because of wrong value type; value type: ")) << this->GetValue().GetType());
-    return false;
-  }
+    if (GetValue().GetType() == GetVariantType())
+    {
+        [GetNativeData()->GetItemCell() setObjectValue:wxCFStringRef(GetValue().GetString()).AsNSString()];
+        return true;
+    }
+    else
+    {
+        wxFAIL_MSG(wxString("Text renderer cannot render value because of wrong value type; value type: ") << GetValue().GetType());
+        return false;
+    }
+}
+
+void
+wxDataViewTextRenderer::OSXOnCellChanged(NSObject *value,
+                                         const wxDataViewItem& item,
+                                         unsigned col)
+{
+    wxDataViewModel *model = GetOwner()->GetOwner()->GetModel();
+    model->ChangeValue(ObjectToString(value), item, col);
 }
 
 IMPLEMENT_CLASS(wxDataViewTextRenderer,wxDataViewRenderer)
@@ -2151,31 +2817,35 @@ IMPLEMENT_CLASS(wxDataViewTextRenderer,wxDataViewRenderer)
 // ---------------------------------------------------------
 // wxDataViewBitmapRenderer
 // ---------------------------------------------------------
-wxDataViewBitmapRenderer::wxDataViewBitmapRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align)
-                         :wxDataViewRenderer(varianttype,mode,align)
+wxDataViewBitmapRenderer::wxDataViewBitmapRenderer(const wxString& varianttype,
+                                                   wxDataViewCellMode mode,
+                                                   int align)
+    : wxDataViewRenderer(varianttype,mode,align)
 {
-  NSImageCell* cell;
-  
-  
-  cell = [[NSImageCell alloc] init];
-  this->SetNativeData(new wxDataViewRendererNativeData(cell));
-  [cell release];
+    NSImageCell* cell;
+
+
+    cell = [[NSImageCell alloc] init];
+    SetNativeData(new wxDataViewRendererNativeData(cell));
+    [cell release];
 }
 
-bool wxDataViewBitmapRenderer::Render()
- // This method returns 'true' if
- //  - the passed bitmap is valid and it could be assigned to the native data browser;
- //  - the passed bitmap is invalid (or is not initialized); this case simulates a non-existing bitmap.
- // In all other cases the method returns 'false'.
+// This method returns 'true' if
+//  - the passed bitmap is valid and it could be assigned to the native data
+//  browser;
+//  - the passed bitmap is invalid (or is not initialized); this case
+//  simulates a non-existing bitmap.
+// In all other cases the method returns 'false'.
+bool wxDataViewBitmapRenderer::MacRender()
 {
-  wxCHECK_MSG(this->GetValue().GetType() == this->GetVariantType(),false,wxString(_("Bitmap renderer cannot render value; value type: ")) << this->GetValue().GetType());
+    wxCHECK_MSG(GetValue().GetType() == GetVariantType(),false,wxString("Bitmap renderer cannot render value; value type: ") << GetValue().GetType());
 
-  wxBitmap bitmap;
+    wxBitmap bitmap;
 
-  bitmap << this->GetValue();
-  if (bitmap.IsOk())
-    [this->GetNativeData()->GetItemCell() setObjectValue:[[bitmap.GetNSImage() retain] autorelease]];
-  return true;
+    bitmap << GetValue();
+    if (bitmap.IsOk())
+        [GetNativeData()->GetItemCell() setObjectValue:[[bitmap.GetNSImage() retain] autorelease]];
+    return true;
 }
 
 IMPLEMENT_CLASS(wxDataViewBitmapRenderer,wxDataViewRenderer)
@@ -2183,33 +2853,47 @@ IMPLEMENT_CLASS(wxDataViewBitmapRenderer,wxDataViewRenderer)
 // -------------------------------------
 // wxDataViewChoiceRenderer
 // -------------------------------------
-wxDataViewChoiceRenderer::wxDataViewChoiceRenderer(wxArrayString const& choices, wxDataViewCellMode mode, int alignment)
-                         :wxDataViewRenderer(wxT("string"),mode,alignment), m_Choices(choices)
-{
-  NSPopUpButtonCell* cell;
-  
-  
-  cell = [[NSPopUpButtonCell alloc] init];
-  [cell setControlSize:NSMiniControlSize];
-  [cell setFont:[[NSFont fontWithName:[[cell font] fontName] size:[NSFont systemFontSizeForControlSize:NSMiniControlSize]] autorelease]];
-  for (size_t i=0; i<choices.GetCount(); ++i)
-    [cell addItemWithTitle:[[wxCFStringRef(choices[i]).AsNSString() retain] autorelease]];
-  this->SetNativeData(new wxDataViewRendererNativeData(cell));
-  [cell release];
-}
-
-bool wxDataViewChoiceRenderer::Render()
-{
-  if (this->GetValue().GetType() == this->GetVariantType())
-  {
-    [((NSPopUpButtonCell*) this->GetNativeData()->GetItemCell()) selectItemWithTitle:[[wxCFStringRef(this->GetValue().GetString()).AsNSString() retain] autorelease]];
-    return true;
-  }
-  else
-  {
-    wxFAIL_MSG(wxString(_("Choice renderer cannot render value because of wrong value type; value type: ")) << this->GetValue().GetType());
-    return false;
-  }
+wxDataViewChoiceRenderer::wxDataViewChoiceRenderer(const wxArrayString& choices,
+                                                   wxDataViewCellMode mode,
+                                                   int alignment)
+    : wxDataViewRenderer(wxT("string"), mode, alignment),
+      m_choices(choices)
+{
+    NSPopUpButtonCell* cell;
+
+
+    cell = [[NSPopUpButtonCell alloc] init];
+    [cell setControlSize:NSMiniControlSize];
+    [cell setFont:[NSFont fontWithName:[[cell font] fontName] size:[NSFont systemFontSizeForControlSize:NSMiniControlSize]]];
+    for (size_t i=0; i<choices.GetCount(); ++i)
+        [cell addItemWithTitle:wxCFStringRef(choices[i]).AsNSString()];
+    SetNativeData(new wxDataViewRendererNativeData(cell));
+    [cell release];
+}
+
+void
+wxDataViewChoiceRenderer::OSXOnCellChanged(NSObject *value,
+                                           const wxDataViewItem& item,
+                                           unsigned col)
+{
+    // At least under OS X 10.7 we get the index of the item selected and not
+    // its string.
+    wxDataViewModel *model = GetOwner()->GetOwner()->GetModel();
+    model->ChangeValue(GetChoice(ObjectToLong(value)), item, col);
+}
+
+bool wxDataViewChoiceRenderer::MacRender()
+{
+    if (GetValue().GetType() == GetVariantType())
+    {
+        [((NSPopUpButtonCell*) GetNativeData()->GetItemCell()) selectItemWithTitle:[[wxCFStringRef(GetValue().GetString()).AsNSString() retain] autorelease]];
+        return true;
+    }
+    else
+    {
+        wxFAIL_MSG(wxString("Choice renderer cannot render value because of wrong value type; value type: ") << GetValue().GetType());
+        return false;
+    }
 }
 
 IMPLEMENT_CLASS(wxDataViewChoiceRenderer,wxDataViewRenderer)
@@ -2217,68 +2901,93 @@ IMPLEMENT_CLASS(wxDataViewChoiceRenderer,wxDataViewRenderer)
 // ---------------------------------------------------------
 // wxDataViewDateRenderer
 // ---------------------------------------------------------
-wxDataViewDateRenderer::wxDataViewDateRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align)
-                       :wxDataViewRenderer(varianttype,mode,align)
+
+wxDataViewDateRenderer::wxDataViewDateRenderer(const wxString& varianttype,
+                                               wxDataViewCellMode mode,
+                                               int align)
+    : wxDataViewRenderer(varianttype,mode,align)
 {
-  NSTextFieldCell* cell;
+    NSTextFieldCell* cell;
+
+    NSDateFormatter* dateFormatter;
 
-  NSDateFormatter* dateFormatter;
 
-  
-  dateFormatter = [[NSDateFormatter alloc] init];
-  [dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
-  [dateFormatter setDateStyle:NSDateFormatterShortStyle];
-  cell = [[NSTextFieldCell alloc] init];
-  [cell setFormatter:dateFormatter];
-  [cell setLineBreakMode:NSLineBreakByTruncatingMiddle];
-  this->SetNativeData(new wxDataViewRendererNativeData(cell,[NSDate dateWithString:@"2000-12-30 20:00:00 +0000"]));
-  [cell          release];
-  [dateFormatter release];
+    dateFormatter = [[NSDateFormatter alloc] init];
+    [dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
+    [dateFormatter setDateStyle:NSDateFormatterShortStyle];
+    cell = [[NSTextFieldCell alloc] init];
+    [cell setFormatter:dateFormatter];
+    SetNativeData(new wxDataViewRendererNativeData(cell,[NSDate dateWithString:@"2000-12-30 20:00:00 +0000"]));
+    [cell          release];
+    [dateFormatter release];
 }
 
-bool wxDataViewDateRenderer::Render()
+bool wxDataViewDateRenderer::MacRender()
 {
-  if (this->GetValue().GetType() == this->GetVariantType())
-  {
-    if (this->GetValue().GetDateTime().IsValid())
+    if (GetValue().GetType() == GetVariantType())
     {
-     // -- find best fitting style to show the date --
-     // as the style should be identical for all cells a reference date instead of the actual cell's date
-     // value is used for all cells; this reference date is stored in the renderer's native data section
-     // for speed purposes; otherwise, the reference date's string has to be recalculated for each item that
-     // may become timewise long if a lot of rows using dates exist;
-     // the algorithm has the preference to display as much information as possible in the first instance;
-     // but as this is often impossible due to space restrictions the style is shortened per loop; finally,
-     // if the shortest time and date format does not fit into the cell the time part is dropped;
-     // remark: the time part itself is not modified per iteration loop and only uses the short style,
-     //         means that only the hours and minutes are being shown
-      [this->GetNativeData()->GetItemCell() setObjectValue:this->GetNativeData()->GetObject()]; // GetObject() returns a date for testing the size of a date object
-      [[this->GetNativeData()->GetItemCell() formatter] setTimeStyle:NSDateFormatterShortStyle];
-      for (int dateFormatterStyle=4; dateFormatterStyle>0; --dateFormatterStyle)
-      {
-        [[this->GetNativeData()->GetItemCell() formatter] setDateStyle:(NSDateFormatterStyle)dateFormatterStyle];
-        if (dateFormatterStyle == 1)
+        if (GetValue().GetDateTime().IsValid())
         {
-         // if the shortest style for displaying the date and time is too long to be fully visible remove the time part of the date:
-          if ([this->GetNativeData()->GetItemCell() cellSize].width > [this->GetNativeData()->GetColumnPtr() width])
-            [[this->GetNativeData()->GetItemCell() formatter] setTimeStyle:NSDateFormatterNoStyle];
-          break; // basically not necessary as the loop would end anyway but let's save the last comparison
+            // -- find best fitting style to show the date --
+            // as the style should be identical for all cells a reference date
+            // instead of the actual cell's date value is used for all cells;
+            // this reference date is stored in the renderer's native data
+            // section for speed purposes; otherwise, the reference date's
+            // string has to be recalculated for each item that may become
+            // timewise long if a lot of rows using dates exist; the algorithm
+            // has the preference to display as much information as possible
+            // in the first instance; but as this is often impossible due to
+            // space restrictions the style is shortened per loop; finally, if
+            // the shortest time and date format does not fit into the cell
+            // the time part is dropped; remark: the time part itself is not
+            // modified per iteration loop and only uses the short style,
+            // means that only the hours and minutes are being shown
+
+            // GetObject() returns a date for testing the size of a date object
+            [GetNativeData()->GetItemCell() setObjectValue:GetNativeData()->GetObject()];
+            [[GetNativeData()->GetItemCell() formatter] setTimeStyle:NSDateFormatterShortStyle];
+            for (int dateFormatterStyle=4; dateFormatterStyle>0; --dateFormatterStyle)
+            {
+                [[GetNativeData()->GetItemCell() formatter] setDateStyle:(NSDateFormatterStyle)dateFormatterStyle];
+                if (dateFormatterStyle == 1)
+                {
+                    // if the shortest style for displaying the date and time
+                    // is too long to be fully visible remove the time part of
+                    // the date:
+                    if ([GetNativeData()->GetItemCell() cellSize].width > [GetNativeData()->GetColumnPtr() width])
+                        [[GetNativeData()->GetItemCell() formatter] setTimeStyle:NSDateFormatterNoStyle];
+                    {
+                        // basically not necessary as the loop would end anyway
+                        // but let's save the last comparison
+                        break;
+                    }
+                }
+                else if ([GetNativeData()->GetItemCell() cellSize].width <= [GetNativeData()->GetColumnPtr() width])
+                    break;
+            }
+            // set data (the style is set by the previous loop); on OSX the
+            // date has to be specified with respect to UTC; in wxWidgets the
+            // date is always entered in the local timezone; so, we have to do
+            // a conversion from the local to UTC timezone when adding the
+            // seconds to 1970-01-01 UTC:
+            [GetNativeData()->GetItemCell() setObjectValue:[NSDate dateWithTimeIntervalSince1970:GetValue().GetDateTime().ToUTC().Subtract(wxDateTime(1,wxDateTime::Jan,1970)).GetSeconds().ToDouble()]];
         }
-        else if ([this->GetNativeData()->GetItemCell() cellSize].width <= [this->GetNativeData()->GetColumnPtr() width])
-          break;
-      }
-     // set data (the style is set by the previous loop);
-     // on OSX the date has to be specified with respect to UTC; in wxWidgets the date is always entered in the local timezone; so, we have to do a conversion
-     // from the local to UTC timezone when adding the seconds to 1970-01-01 UTC:
-      [this->GetNativeData()->GetItemCell() setObjectValue:[NSDate dateWithTimeIntervalSince1970:this->GetValue().GetDateTime().ToUTC().Subtract(wxDateTime(1,wxDateTime::Jan,1970)).GetSeconds().ToDouble()]];
+        return true;
     }
-    return true;
-  }
-  else
-  {
-    wxFAIL_MSG(wxString(_("Date renderer cannot render value because of wrong value type; value type: ")) << this->GetValue().GetType());
-    return false;
-  }
+    else
+    {
+        wxFAIL_MSG(wxString("Date renderer cannot render value because of wrong value type; value type: ") << GetValue().GetType());
+        return false;
+    }
+}
+
+void
+wxDataViewDateRenderer::OSXOnCellChanged(NSObject *value,
+                                         const wxDataViewItem& item,
+                                         unsigned col)
+{
+    wxDataViewModel *model = GetOwner()->GetOwner()->GetModel();
+    model->ChangeValue(ObjectToDate(value), item, col);
 }
 
 IMPLEMENT_ABSTRACT_CLASS(wxDataViewDateRenderer,wxDataViewRenderer)
@@ -2286,38 +2995,54 @@ IMPLEMENT_ABSTRACT_CLASS(wxDataViewDateRenderer,wxDataViewRenderer)
 // ---------------------------------------------------------
 // wxDataViewIconTextRenderer
 // ---------------------------------------------------------
-wxDataViewIconTextRenderer::wxDataViewIconTextRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align)
-                           :wxDataViewRenderer(varianttype,mode)
+wxDataViewIconTextRenderer::wxDataViewIconTextRenderer(const wxString& varianttype,
+                                                       wxDataViewCellMode mode,
+                                                       int align)
+     : wxDataViewRenderer(varianttype,mode)
 {
-  wxImageTextCell* cell;
-  
-  
-  cell = [[wxImageTextCell alloc] init];
-  [cell setAlignment:ConvertToNativeHorizontalTextAlignment(align)];
-  this->SetNativeData(new wxDataViewRendererNativeData(cell));
-  [cell release];
+    wxImageTextCell* cell;
+
+
+    cell = [[wxImageTextCell alloc] init];
+    [cell setAlignment:ConvertToNativeHorizontalTextAlignment(align)];
+    SetNativeData(new wxDataViewRendererNativeData(cell));
+    [cell release];
 }
 
-bool wxDataViewIconTextRenderer::Render()
+bool wxDataViewIconTextRenderer::MacRender()
 {
-  if (this->GetValue().GetType() == this->GetVariantType())
-  {
-    wxDataViewIconText iconText;
-    
-    wxImageTextCell* cell;
+    if (GetValue().GetType() == GetVariantType())
+    {
+        wxDataViewIconText iconText;
 
-    cell = (wxImageTextCell*) this->GetNativeData()->GetItemCell();
-    iconText << this->GetValue();
-    if (iconText.GetIcon().IsOk())
-      [cell setImage:[[wxBitmap(iconText.GetIcon()).GetNSImage() retain] autorelease]];
-    [cell setStringValue:[[wxCFStringRef(iconText.GetText()).AsNSString() retain] autorelease]];
-    return true;
-  }
-  else
-  {
-    wxFAIL_MSG(wxString(_("Icon & text renderer cannot render value because of wrong value type; value type: ")) << this->GetValue().GetType());
-    return false;
-  }
+        wxImageTextCell* cell;
+
+        cell = (wxImageTextCell*) GetNativeData()->GetItemCell();
+        iconText << GetValue();
+        if (iconText.GetIcon().IsOk())
+            [cell setImage:[[wxBitmap(iconText.GetIcon()).GetNSImage() retain] autorelease]];
+        else
+            [cell setImage:nil];
+        [cell setStringValue:[[wxCFStringRef(iconText.GetText()).AsNSString() retain] autorelease]];
+        return true;
+    }
+    else
+    {
+        wxFAIL_MSG(wxString("Icon & text renderer cannot render value because of wrong value type; value type: ") << GetValue().GetType());
+        return false;
+    }
+}
+
+void
+wxDataViewIconTextRenderer::OSXOnCellChanged(NSObject *value,
+                                             const wxDataViewItem& item,
+                                             unsigned col)
+{
+    wxVariant valueIconText;
+    valueIconText << wxDataViewIconText(ObjectToString(value));
+
+    wxDataViewModel *model = GetOwner()->GetOwner()->GetModel();
+    model->ChangeValue(valueIconText, item, col);
 }
 
 IMPLEMENT_ABSTRACT_CLASS(wxDataViewIconTextRenderer,wxDataViewRenderer)
@@ -2325,32 +3050,43 @@ IMPLEMENT_ABSTRACT_CLASS(wxDataViewIconTextRenderer,wxDataViewRenderer)
 // ---------------------------------------------------------
 // wxDataViewToggleRenderer
 // ---------------------------------------------------------
-wxDataViewToggleRenderer::wxDataViewToggleRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align)
-                         :wxDataViewRenderer(varianttype,mode)
+wxDataViewToggleRenderer::wxDataViewToggleRenderer(const wxString& varianttype,
+                                                   wxDataViewCellMode mode,
+                                                   int align)
+    : wxDataViewRenderer(varianttype,mode)
 {
-  NSButtonCell* cell;
-  
-  
-  cell = [[NSButtonCell alloc] init];
-  [cell setAlignment:ConvertToNativeHorizontalTextAlignment(align)];
-  [cell setButtonType:NSSwitchButton];
-  [cell setImagePosition:NSImageOnly];
-  this->SetNativeData(new wxDataViewRendererNativeData(cell));
-  [cell release];
+    NSButtonCell* cell;
+
+
+    cell = [[NSButtonCell alloc] init];
+    [cell setAlignment:ConvertToNativeHorizontalTextAlignment(align)];
+    [cell setButtonType:NSSwitchButton];
+    [cell setImagePosition:NSImageOnly];
+    SetNativeData(new wxDataViewRendererNativeData(cell));
+    [cell release];
 }
 
-bool wxDataViewToggleRenderer::Render()
+bool wxDataViewToggleRenderer::MacRender()
 {
-  if (this->GetValue().GetType() == this->GetVariantType())
-  {
-    [this->GetNativeData()->GetItemCell() setIntValue:this->GetValue().GetLong()];
-    return true;
-  }
-  else
-  {
-    wxFAIL_MSG(wxString(_("Toggle renderer cannot render value because of wrong value type; value type: ")) << this->GetValue().GetType());
-    return false;
-  }
+    if (GetValue().GetType() == GetVariantType())
+    {
+        [GetNativeData()->GetItemCell() setIntValue:GetValue().GetLong()];
+        return true;
+    }
+    else
+    {
+        wxFAIL_MSG(wxString("Toggle renderer cannot render value because of wrong value type; value type: ") << GetValue().GetType());
+        return false;
+    }
+}
+
+void
+wxDataViewToggleRenderer::OSXOnCellChanged(NSObject *value,
+                                           const wxDataViewItem& item,
+                                           unsigned col)
+{
+    wxDataViewModel *model = GetOwner()->GetOwner()->GetModel();
+    model->ChangeValue(ObjectToBool(value), item, col);
 }
 
 IMPLEMENT_ABSTRACT_CLASS(wxDataViewToggleRenderer,wxDataViewRenderer)
@@ -2358,31 +3094,44 @@ IMPLEMENT_ABSTRACT_CLASS(wxDataViewToggleRenderer,wxDataViewRenderer)
 // ---------------------------------------------------------
 // wxDataViewProgressRenderer
 // ---------------------------------------------------------
-wxDataViewProgressRenderer::wxDataViewProgressRenderer(wxString const& label, wxString const& varianttype, wxDataViewCellMode mode, int align)
-                           :wxDataViewRenderer(varianttype,mode,align)
+wxDataViewProgressRenderer::wxDataViewProgressRenderer(const wxString& label,
+                                                       const wxString& varianttype,
+                                                       wxDataViewCellMode mode,
+                                                       int align)
+    : wxDataViewRenderer(varianttype,mode,align)
 {
-  NSLevelIndicatorCell* cell;
-  
-  
-  cell = [[NSLevelIndicatorCell alloc] initWithLevelIndicatorStyle:NSContinuousCapacityLevelIndicatorStyle];
-  [cell setMinValue:0];
-  [cell setMaxValue:100];
-  this->SetNativeData(new wxDataViewRendererNativeData(cell));
-  [cell release];
+    wxUnusedVar(label);
+    
+    NSLevelIndicatorCell* cell;
+
+    cell = [[NSLevelIndicatorCell alloc] initWithLevelIndicatorStyle:NSContinuousCapacityLevelIndicatorStyle];
+    [cell setMinValue:0];
+    [cell setMaxValue:100];
+    SetNativeData(new wxDataViewRendererNativeData(cell));
+    [cell release];
 }
 
-bool wxDataViewProgressRenderer::Render()
+bool wxDataViewProgressRenderer::MacRender()
 {
-  if (this->GetValue().GetType() == this->GetVariantType())
-  {
-    [this->GetNativeData()->GetItemCell() setIntValue:this->GetValue().GetLong()];
-    return true;
-  }
-  else
-  {
-    wxFAIL_MSG(wxString(_("Progress renderer cannot render value because of wrong value type; value type: ")) << this->GetValue().GetType());
-    return false;
-  }
+    if (GetValue().GetType() == GetVariantType())
+    {
+        [GetNativeData()->GetItemCell() setIntValue:GetValue().GetLong()];
+        return true;
+    }
+    else
+    {
+        wxFAIL_MSG(wxString("Progress renderer cannot render value because of wrong value type; value type: ") << GetValue().GetType());
+        return false;
+    }
+}
+
+void
+wxDataViewProgressRenderer::OSXOnCellChanged(NSObject *value,
+                                             const wxDataViewItem& item,
+                                             unsigned col)
+{
+    wxDataViewModel *model = GetOwner()->GetOwner()->GetModel();
+    model->ChangeValue(ObjectToLong(value), item, col);
 }
 
 IMPLEMENT_ABSTRACT_CLASS(wxDataViewProgressRenderer,wxDataViewRenderer)
@@ -2390,123 +3139,182 @@ IMPLEMENT_ABSTRACT_CLASS(wxDataViewProgressRenderer,wxDataViewRenderer)
 // ---------------------------------------------------------
 // wxDataViewColumn
 // ---------------------------------------------------------
-wxDataViewColumn::wxDataViewColumn(const wxString& title, wxDataViewRenderer* renderer, unsigned int model_column, int width, wxAlignment align, int flags)
-                 :wxDataViewColumnBase(renderer, model_column), m_NativeDataPtr(new wxDataViewColumnNativeData()), m_title(title)
+
+wxDataViewColumn::wxDataViewColumn(const wxString& title,
+                                   wxDataViewRenderer* renderer,
+                                   unsigned int model_column,
+                                   int width,
+                                   wxAlignment align,
+                                   int flags)
+     : wxDataViewColumnBase(renderer, model_column),
+       m_NativeDataPtr(new wxDataViewColumnNativeData()),
+       m_title(title)
+{
+    InitCommon(width, align, flags);
+    if (renderer && !renderer->IsCustomRenderer() &&
+        (renderer->GetAlignment() == wxDVR_DEFAULT_ALIGNMENT))
+        renderer->SetAlignment(align);
+}
+
+wxDataViewColumn::wxDataViewColumn(const wxBitmap& bitmap,
+                                   wxDataViewRenderer* renderer,
+                                   unsigned int model_column,
+                                   int width,
+                                   wxAlignment align,
+                                   int flags)
+    : wxDataViewColumnBase(bitmap, renderer, model_column),
+      m_NativeDataPtr(new wxDataViewColumnNativeData())
 {
-  this->InitCommon(width, align, flags);
-  if ((renderer != NULL) && (renderer->GetAlignment() == wxDVR_DEFAULT_ALIGNMENT))
-    renderer->SetAlignment(align);
+    InitCommon(width, align, flags);
+    if (renderer && !renderer->IsCustomRenderer() &&
+        (renderer->GetAlignment() == wxDVR_DEFAULT_ALIGNMENT))
+        renderer->SetAlignment(align);
 }
 
-wxDataViewColumn::wxDataViewColumn(const wxBitmap& bitmap, wxDataViewRenderer* renderer, unsigned int model_column, int width, wxAlignment align, int flags)
-                 :wxDataViewColumnBase(bitmap, renderer, model_column), m_NativeDataPtr(new wxDataViewColumnNativeData())
+wxDataViewColumn::~wxDataViewColumn()
 {
-  this->InitCommon(width, align, flags);
-  if ((renderer != NULL) && (renderer->GetAlignment() == wxDVR_DEFAULT_ALIGNMENT))
-    renderer->SetAlignment(align);
+    delete m_NativeDataPtr;
 }
 
-wxDataViewColumn::~wxDataViewColumn(void)
+int wxDataViewColumn::GetWidth() const
 {
-  delete this->m_NativeDataPtr;
+    return [m_NativeDataPtr->GetNativeColumnPtr() width];
 }
 
 bool wxDataViewColumn::IsSortKey() const
 {
-  return ((this->GetNativeData()->GetNativeColumnPtr() != NULL) && ([this->GetNativeData()->GetNativeColumnPtr() sortDescriptorPrototype] != nil));
+    NSTableColumn *nsCol = GetNativeData()->GetNativeColumnPtr();
+    return nsCol && ([nsCol sortDescriptorPrototype] != nil);
 }
 
 void wxDataViewColumn::SetAlignment(wxAlignment align)
 {
-  this->m_alignment = align;
-  [[this->m_NativeDataPtr->GetNativeColumnPtr() headerCell] setAlignment:ConvertToNativeHorizontalTextAlignment(align)];
-  if ((this->m_renderer != NULL) && (this->m_renderer->GetAlignment() == wxDVR_DEFAULT_ALIGNMENT))
-    this->m_renderer->SetAlignment(align);
+    m_alignment = align;
+    [[m_NativeDataPtr->GetNativeColumnPtr() headerCell] setAlignment:ConvertToNativeHorizontalTextAlignment(align)];
+    if (m_renderer && !m_renderer->IsCustomRenderer() &&
+        (m_renderer->GetAlignment() == wxDVR_DEFAULT_ALIGNMENT))
+        m_renderer->SetAlignment(align);
 }
 
-void wxDataViewColumn::SetBitmap(wxBitmap const& bitmap)
+void wxDataViewColumn::SetBitmap(const wxBitmap& bitmap)
 {
- // bitmaps and titles cannot exist at the same time - if the bitmap is set the title is removed:
-  this->m_title = wxEmptyString;
-  this->wxDataViewColumnBase::SetBitmap(bitmap);
-  [[this->m_NativeDataPtr->GetNativeColumnPtr() headerCell] setImage:[[bitmap.GetNSImage() retain] autorelease]];
+    // bitmaps and titles cannot exist at the same time - if the bitmap is set
+    // the title is removed:
+    m_title = wxEmptyString;
+    wxDataViewColumnBase::SetBitmap(bitmap);
+    [[m_NativeDataPtr->GetNativeColumnPtr() headerCell] setImage:[[bitmap.GetNSImage() retain] autorelease]];
 }
 
 void wxDataViewColumn::SetMaxWidth(int maxWidth)
 {
-  this->m_maxWidth = maxWidth;
-  [this->m_NativeDataPtr->GetNativeColumnPtr() setMaxWidth:maxWidth];
+    m_maxWidth = maxWidth;
+    [m_NativeDataPtr->GetNativeColumnPtr() setMaxWidth:maxWidth];
 }
 
 void wxDataViewColumn::SetMinWidth(int minWidth)
 {
-  this->m_minWidth = minWidth;
-  [this->m_NativeDataPtr->GetNativeColumnPtr() setMinWidth:minWidth];
+    m_minWidth = minWidth;
+    [m_NativeDataPtr->GetNativeColumnPtr() setMinWidth:minWidth];
 }
 
 void wxDataViewColumn::SetReorderable(bool reorderable)
 {
+    wxUnusedVar(reorderable);
+}
+
+void wxDataViewColumn::SetHidden(bool hidden)
+{
+    // How to set flag here?
+
+    [m_NativeDataPtr->GetNativeColumnPtr() setHidden:hidden];
 }
 
-void wxDataViewColumn::SetResizeable(bool resizeable)
+bool wxDataViewColumn::IsHidden() const
 {
-  this->wxDataViewColumnBase::SetResizeable(resizeable);
-  if (resizeable)
-    [this->m_NativeDataPtr->GetNativeColumnPtr() setResizingMask:NSTableColumnUserResizingMask];
-  else
-    [this->m_NativeDataPtr->GetNativeColumnPtr() setResizingMask:NSTableColumnNoResizing];
+    return [m_NativeDataPtr->GetNativeColumnPtr() isHidden];
+}
+
+void wxDataViewColumn::SetResizeable(bool resizable)
+{
+    wxDataViewColumnBase::SetResizeable(resizable);
+    if (resizable)
+        [m_NativeDataPtr->GetNativeColumnPtr() setResizingMask:NSTableColumnUserResizingMask];
+    else
+        [m_NativeDataPtr->GetNativeColumnPtr() setResizingMask:NSTableColumnNoResizing];
 }
 
 void wxDataViewColumn::SetSortable(bool sortable)
 {
-  this->wxDataViewColumnBase::SetSortable(sortable);
+    // wxDataViewColumnBase::SetSortable(sortable);
+    // Avoid endless recursion and just set the flag here
+    if (sortable)
+        m_flags |= wxDATAVIEW_COL_SORTABLE;
+    else
+        m_flags &= ~wxDATAVIEW_COL_SORTABLE;
 }
 
 void wxDataViewColumn::SetSortOrder(bool ascending)
 {
-  if (m_ascending != ascending)
-  {
-    m_ascending = ascending;
-    if (this->IsSortKey())
+    if (m_ascending != ascending)
     {
-     // change sorting order:
-      NSArray*          sortDescriptors;
-      NSSortDescriptor* sortDescriptor;
-      NSTableColumn*    tableColumn;
-      
-      tableColumn     = this->m_NativeDataPtr->GetNativeColumnPtr();
-      sortDescriptor  = [[NSSortDescriptor alloc] initWithKey:[[tableColumn sortDescriptorPrototype] key] ascending:m_ascending];
-      sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
-      [tableColumn setSortDescriptorPrototype:sortDescriptor];
-      [[tableColumn tableView] setSortDescriptors:sortDescriptors];
-      [sortDescriptor release];
+        m_ascending = ascending;
+        if (IsSortKey())
+        {
+            // change sorting order:
+            NSArray*          sortDescriptors;
+            NSSortDescriptor* sortDescriptor;
+            NSTableColumn*    tableColumn;
+
+            tableColumn     = m_NativeDataPtr->GetNativeColumnPtr();
+            sortDescriptor  = [[NSSortDescriptor alloc] initWithKey:[[tableColumn sortDescriptorPrototype] key] ascending:m_ascending];
+            sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
+            [tableColumn setSortDescriptorPrototype:sortDescriptor];
+            [[tableColumn tableView] setSortDescriptors:sortDescriptors];
+            [sortDescriptor release];
+        }
     }
-  }
 }
 
-void wxDataViewColumn::SetTitle(wxString const& title)
+void wxDataViewColumn::SetTitle(const wxString& title)
 {
- // bitmaps and titles cannot exist at the same time - if the title is set the bitmap is removed:
-  this->wxDataViewColumnBase::SetBitmap(wxBitmap());
-  this->m_title = title;
-  [[this->m_NativeDataPtr->GetNativeColumnPtr() headerCell] setStringValue:[[wxCFStringRef(title).AsNSString() retain] autorelease]];
+    // bitmaps and titles cannot exist at the same time - if the title is set
+    // the bitmap is removed:
+    wxDataViewColumnBase::SetBitmap(wxBitmap());
+    m_title = title;
+    [[m_NativeDataPtr->GetNativeColumnPtr() headerCell] setStringValue:[[wxCFStringRef(title).AsNSString() retain] autorelease]];
 }
 
 void wxDataViewColumn::SetWidth(int width)
 {
-  [this->m_NativeDataPtr->GetNativeColumnPtr() setWidth:width];
-  this->m_width = width;
-}
+    m_width = width;
 
-void wxDataViewColumn::SetAsSortKey(bool WXUNUSED(sort))
-{
- // see wxGTK native wxDataViewColumn implementation
-  wxFAIL_MSG(_("not implemented"));
+    switch ( width )
+    {
+        case wxCOL_WIDTH_AUTOSIZE:
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
+            if ( GetOwner() )
+            {
+                wxCocoaDataViewControl *peer = static_cast<wxCocoaDataViewControl*>(GetOwner()->GetPeer());
+                peer->FitColumnWidthToContent(GetOwner()->GetColumnPosition(this));
+                break;
+            }
+#endif
+            // fall through if unsupported (OSX < 10.5) or not yet settable
+
+        case wxCOL_WIDTH_DEFAULT:
+            width = wxDVC_DEFAULT_WIDTH;
+            // fall through
+
+        default:
+            [m_NativeDataPtr->GetNativeColumnPtr() setWidth:width];
+            break;
+    }
 }
 
 void wxDataViewColumn::SetNativeData(wxDataViewColumnNativeData* newNativeDataPtr)
 {
-  delete this->m_NativeDataPtr;
-  this->m_NativeDataPtr = newNativeDataPtr;
+    delete m_NativeDataPtr;
+    m_NativeDataPtr = newNativeDataPtr;
 }
+
 #endif // (wxUSE_DATAVIEWCTRL == 1) && !defined(wxUSE_GENERICDATAVIEWCTRL)