diff dwt/widgets/Tree.d @ 45:d8635bb48c7c

Merge with SWT 3.5
author Jacob Carlborg <doob@me.com>
date Mon, 01 Dec 2008 17:07:00 +0100
parents e831403a80a9
children cfa563df4fdd
line wrap: on
line diff
--- a/dwt/widgets/Tree.d	Tue Oct 21 15:20:04 2008 +0200
+++ b/dwt/widgets/Tree.d	Mon Dec 01 17:07:00 2008 +0100
@@ -1,5 +1,5 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -12,30 +12,51 @@
 
 import dwt.dwthelper.utils;
 
- 
 import dwt.DWT;
 import dwt.DWTException;
+import dwt.accessibility.ACC;
 import dwt.events.SelectionEvent;
 import dwt.events.SelectionListener;
 import dwt.events.TreeListener;
 import dwt.graphics.Color;
 import dwt.graphics.Font;
+import dwt.graphics.GC;
+import dwt.graphics.GCData;
 import dwt.graphics.Image;
 import dwt.graphics.Point;
 import dwt.graphics.Rectangle;
+import dwt.internal.cocoa.NSArray;
+import dwt.internal.cocoa.NSBezierPath;
 import dwt.internal.cocoa.NSBrowserCell;
 import dwt.internal.cocoa.NSButtonCell;
+import dwt.internal.cocoa.NSColor;
+import dwt.internal.cocoa.NSColorSpace;
+import dwt.internal.cocoa.NSDictionary;
+import dwt.internal.cocoa.NSEvent;
+import dwt.internal.cocoa.NSFont;
+import dwt.internal.cocoa.NSGraphicsContext;
 import dwt.internal.cocoa.NSIndexSet;
+import dwt.internal.cocoa.NSMutableIndexSet;
+import dwt.internal.cocoa.NSNotification;
 import dwt.internal.cocoa.NSNumber;
 import dwt.internal.cocoa.NSOutlineView;
+import dwt.internal.cocoa.NSPoint;
+import dwt.internal.cocoa.NSRange;
 import dwt.internal.cocoa.NSRect;
+import dwt.internal.cocoa.NSScrollView;
+import dwt.internal.cocoa.NSSize;
 import dwt.internal.cocoa.NSString;
 import dwt.internal.cocoa.NSTableColumn;
+import dwt.internal.cocoa.NSTableHeaderCell;
 import dwt.internal.cocoa.NSTableHeaderView;
 import dwt.internal.cocoa.NSTableView;
+import dwt.internal.cocoa.NSView;
 import dwt.internal.cocoa.OS;
+import dwt.internal.cocoa.SWTBrowserCell;
 import dwt.internal.cocoa.SWTOutlineView;
 import dwt.internal.cocoa.SWTScrollView;
+import dwt.internal.cocoa.SWTTableHeaderCell;
+import dwt.internal.cocoa.SWTTableHeaderView;
 import dwt.internal.cocoa.SWTTreeItem;
 import dwt.internal.cocoa.id;
 
@@ -75,12 +96,13 @@
  * </pre></code>
  * </p><p>
  * Note that although this class is a subclass of <code>Composite</code>,
- * it does not make sense to add <code>Control</code> children to it,
- * or set a layout on it.
+ * it does not normally make sense to add <code>Control</code> children to
+ * it, or set a layout on it, unless implementing something like a cell
+ * editor.
  * </p><p>
  * <dl>
  * <dt><b>Styles:</b></dt>
- * <dd>SINGLE, MULTI, CHECK, FULL_SELECTION, VIRTUAL</dd>
+ * <dd>SINGLE, MULTI, CHECK, FULL_SELECTION, VIRTUAL, NO_SCROLL</dd>
  * <dt><b>Events:</b></dt>
  * <dd>Selection, DefaultSelection, Collapse, Expand, SetData, MeasureItem, EraseItem, PaintItem</dd>
  * </dl>
@@ -89,9 +111,14 @@
  * </p><p>
  * IMPORTANT: This class is <em>not</em> intended to be subclassed.
  * </p>
+ *
+ * @see <a href="http://www.eclipse.org/swt/snippets/#tree">Tree, TreeItem, TreeColumn snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">DWT Example: ControlExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
  */
 public class Tree : Composite {
     NSTableColumn firstColumn, checkColumn;
+    NSBrowserCell dataCell;
     NSTableHeaderView headerView;
     TreeItem [] items;
     int itemCount;
@@ -99,6 +126,7 @@
     TreeColumn sortColumn;
     int columnCount;
     int sortDirection;
+    float /*double*/ levelIndent;
     bool ignoreExpand, ignoreSelect;
 
 /**
@@ -128,6 +156,9 @@
  * @see DWT#SINGLE
  * @see DWT#MULTI
  * @see DWT#CHECK
+ * @see DWT#FULL_SELECTION
+ * @see DWT#VIRTUAL
+ * @see DWT#NO_SCROLL
  * @see Widget#checkSubclass
  * @see Widget#getStyle
  */
@@ -135,14 +166,7 @@
     super (parent, checkStyle (style));
 }
 
-void _addListener (int eventType, Listener listener) {
-    super._addListener (eventType, listener);
-    for (int i = 0; i < items.length; i++) {
-        if (items [i] !is null) items [i].width = -1;        
-    }
-}
-
-TreeItem _getItem (TreeItem parentItem, int index) {
+TreeItem _getItem (TreeItem parentItem, int index, bool create) {
     int count;
     TreeItem[] items;
     if (parentItem !is null) {
@@ -154,12 +178,32 @@
     }
     if (index < 0 || index >= count) return null;
     TreeItem item = items [index]; 
-    if (item !is null || (style & DWT.VIRTUAL) is 0) return item;
+    if (item !is null || (style & DWT.VIRTUAL) is 0 || !create) return item;
     item = new TreeItem (this, parentItem, DWT.NONE, index, false);
     items [index] = item;
     return item;
 }
 
+int accessibilityAttributeValue (int /*long*/ id, int /*long*/ sel, int /*long*/ arg0) {
+    
+    if (accessible !is null) {
+        NSString attribute = new NSString(arg0);
+        id returnValue = accessible.internal_accessibilityAttributeValue(attribute, ACC.CHILDID_SELF);
+        if (returnValue !is null) return returnValue.id;
+    }
+    
+    NSString attributeName = new NSString(arg0);
+    
+    // Accessibility Verifier queries for a title or description.  NSOutlineView doesn't
+    // seem to return either, so we return a default description value here.
+    if (attributeName.isEqualToString (OS.NSAccessibilityDescriptionAttribute)) {
+        return NSString.stringWith("").id;
+    }
+    
+    return super.accessibilityAttributeValue(id, sel, arg0);
+}
+
+
 /**
  * Adds the listener to the collection of listeners who will
  * be notified when the user changes the receiver's selection, by sending
@@ -263,36 +307,28 @@
 }
 
 void clear (TreeItem parentItem, int index, bool all) {
-//  int [] ids = parentItem is null ? childIds : parentItem.childIds;
-//  TreeItem item = _getItem (ids [index], false);
-//  if (item !is null) {
-//      item.clear();
-//      if (all) {
-//          clearAll (item, true);
-//      } else {
-//          int container = parentItem is null ? OS.kDataBrowserNoItem : parentItem.id;
-//          OS.UpdateDataBrowserItems (handle, container, 1, new int[] {item.id}, OS.kDataBrowserItemNoProperty, OS.kDataBrowserNoItem);
-//      }
-//  }
+    TreeItem item = _getItem (parentItem, index, false);
+    if (item !is null) {
+        item.clear();
+        ((NSOutlineView) view).reloadItem (item.handle);
+        if (all) {
+            clearAll (item, true);
+        }
+    }
 }
 
 void clearAll (TreeItem parentItem, bool all) {
-//  bool update = !inClearAll;
-//  int count = getItemCount (parentItem);
-//  if (count is 0) return;
-//  inClearAll = true;
-//  int [] ids = parentItem is null ? childIds : parentItem.childIds;
-//  for (int i=0; i<count; i++) {
-//      TreeItem item = _getItem (ids [i], false);
-//      if (item !is null) {
-//          item.clear ();
-//          if (all) clearAll (item, true);
-//      }
-//  }
-//  if (update) {
-//      OS.UpdateDataBrowserItems (handle, 0, 0, null, OS.kDataBrowserItemNoProperty, OS.kDataBrowserNoItem);
-//      inClearAll = false;
-//  }
+    int count = getItemCount (parentItem);
+    if (count is 0) return;
+    TreeItem [] children = parentItem is null ? items : parentItem.items; 
+    for (int i=0; i<count; i++) {
+        TreeItem item = children [i];
+        if (item !is null) {
+            item.clear ();
+            ((NSOutlineView) view).reloadItem (item.handle);
+            if (all) clearAll (item, true);
+        }
+    }
 }
 
 /**
@@ -349,6 +385,13 @@
     clearAll (null, all);
 }
 
+void clearCustomWidths (TreeItem item) {
+    item.customWidth = -1;
+    for (int i = 0; i < item.itemCount; i++) {
+        clearCustomWidths (items[i]);
+    }
+}
+
 public Point computeSize (int wHint, int hHint, bool changed) {
     checkWidget ();
     int width = 0, height = 0;
@@ -374,7 +417,7 @@
         width = wHint;
     }
     if (hHint is DWT.DEFAULT) {
-        height = (cast(NSTableView)view).numberOfRows() * getItemHeight () + getHeaderHeight();
+        height = (int)/*64*/(cast(NSOutlineView) view).numberOfRows () * getItemHeight () + getHeaderHeight ();
     } else {
         height = hHint;
     }
@@ -384,62 +427,105 @@
     return new Point (rect.width, rect.height);
 }
 
+void createColumn (TreeItem item, int index) {
+    if (item.items !is null) {
+        for (int i = 0; i < item.items.length; i++) {
+            if (item.items[i] !is null) createColumn (item.items[i], index);
+        }
+    }
+    String [] strings = item.strings;
+    if (strings !is null) {
+        String [] temp = new String [columnCount];
+        System.arraycopy (strings, 0, temp, 0, index);
+        System.arraycopy (strings, index, temp, index+1, columnCount-index-1);
+        temp [index] = "";
+        item.strings = temp;
+    }
+    if (index is 0) item.text = "";
+    Image [] images = item.images;
+    if (images !is null) {
+        Image [] temp = new Image [columnCount];
+        System.arraycopy (images, 0, temp, 0, index);
+        System.arraycopy (images, index, temp, index+1, columnCount-index-1);
+        item.images = temp;
+    }
+    if (index is 0) item.image = null;
+    Color [] cellBackground = item.cellBackground;
+    if (cellBackground !is null) {
+        Color [] temp = new Color [columnCount];
+        System.arraycopy (cellBackground, 0, temp, 0, index);
+        System.arraycopy (cellBackground, index, temp, index+1, columnCount-index-1);
+        item.cellBackground = temp;
+    }
+    Color [] cellForeground = item.cellForeground;
+    if (cellForeground !is null) {
+        Color [] temp = new Color [columnCount];
+        System.arraycopy (cellForeground, 0, temp, 0, index);
+        System.arraycopy (cellForeground, index, temp, index+1, columnCount-index-1);
+        item.cellForeground = temp;
+    }
+    Font [] cellFont = item.cellFont;
+    if (cellFont !is null) {
+        Font [] temp = new Font [columnCount];
+        System.arraycopy (cellFont, 0, temp, 0, index);
+        System.arraycopy (cellFont, index, temp, index+1, columnCount-index-1);
+        item.cellFont = temp;
+    }
+}
+
 void createHandle () {
-    SWTScrollView scrollWidget = cast(SWTScrollView)new SWTScrollView().alloc();
-    scrollWidget.initWithFrame(new NSRect ());
-    scrollWidget.setHasHorizontalScroller(true);
-    scrollWidget.setHasVerticalScroller(true);
-    scrollWidget.setAutohidesScrollers(true);
-    scrollWidget.setBorderType(hasBorder() ? OS.NSBezelBorder : OS.NSNoBorder);
-    scrollWidget.setTag(jniRef);
-    
-    NSOutlineView widget = cast(NSOutlineView)new SWTOutlineView().alloc();
-    widget.initWithFrame(new NSRect());
-    widget.setAllowsMultipleSelection((style & DWT.MULTI) !is 0);
-    widget.setAutoresizesOutlineColumn(false);
-    widget.setAutosaveExpandedItems(true);
-    widget.setDataSource(widget);
-    widget.setDelegate(widget);
-    widget.setDoubleAction(OS.sel_sendDoubleSelection);
-    if (!hasBorder()) widget.setFocusRingType(OS.NSFocusRingTypeNone);
-    widget.setTag(jniRef);
+    NSScrollView scrollWidget = cast(NSScrollView) new SWTScrollView ().alloc ();
+    scrollWidget.initWithFrame (new NSRect ());
+    scrollWidget.setHasHorizontalScroller (true);
+    scrollWidget.setHasVerticalScroller (true);
+    scrollWidget.setAutohidesScrollers (true);
+    scrollWidget.setBorderType(hasBorder () ? OS.NSBezelBorder : OS.NSNoBorder);
     
-    headerView = widget.headerView();
-    headerView.retain();
-    widget.setHeaderView(null);
+    NSOutlineView widget = cast(NSOutlineView) new SWTOutlineView ().alloc ();
+    widget.initWithFrame (new NSRect ());
+    widget.setAllowsMultipleSelection ((style & DWT.MULTI) !is 0);
+    widget.setAllowsColumnReordering (false);
+    widget.setAutoresizesOutlineColumn (false);
+    widget.setAutosaveExpandedItems (true);
+    widget.setDataSource (widget);
+    widget.setDelegate (widget);
+    widget.setDoubleAction (OS.sel_sendDoubleSelection);
+    if (!hasBorder ()) widget.setFocusRingType (OS.NSFocusRingTypeNone);
     
-    NSString str = NSString.stringWith("");
+    headerView = (NSTableHeaderView)new SWTTableHeaderView ().alloc ().init ();
+    widget.setHeaderView (null);
+    
+    NSString str = NSString.stringWith ("");
     if ((style & DWT.CHECK) !is 0) {
-        checkColumn = cast(NSTableColumn)new NSTableColumn().alloc();
-        checkColumn.initWithIdentifier(str);
-        checkColumn.headerCell().setTitle(str);
+        checkColumn = cast(NSTableColumn) new NSTableColumn ().alloc ();
+        checkColumn.initWithIdentifier (checkColumn);
+        checkColumn.headerCell ().setTitle (str);
         widget.addTableColumn (checkColumn);
-        widget.setOutlineTableColumn(checkColumn);
-        NSButtonCell cell = cast(NSButtonCell)new NSButtonCell().alloc().init();
-        checkColumn.setDataCell(cell);
-        cell.setButtonType(OS.NSSwitchButton);
-        cell.setImagePosition(OS.NSImageOnly);
-        cell.setAllowsMixedState(true);
-        checkColumn.setWidth(getCheckColumnWidth());
-        checkColumn.setResizingMask(OS.NSTableColumnNoResizing);
-        checkColumn.setEditable(false);
-        cell.release();
+        widget.setOutlineTableColumn (checkColumn);
+        NSButtonCell cell = cast(NSButtonCell) new NSButtonCell ().alloc ().init ();
+        checkColumn.setDataCell (cell);
+        cell.setButtonType (OS.NSSwitchButton);
+        cell.setImagePosition (OS.NSImageOnly);
+        cell.setAllowsMixedState (true);
+        checkColumn.setWidth (getCheckColumnWidth ());
+        checkColumn.setResizingMask (OS.NSTableColumnNoResizing);
+        checkColumn.setEditable (false);
+        cell.release ();
     }
     
-    firstColumn = cast(NSTableColumn)new NSTableColumn().alloc();
-    firstColumn.initWithIdentifier(str);
-    firstColumn.headerCell().setTitle(str);
+    firstColumn = cast(NSTableColumn) new NSTableColumn ().alloc ();
+    firstColumn.initWithIdentifier (firstColumn);
+    firstColumn.setMinWidth(0);
+    firstColumn.headerCell ().setTitle (str);
     widget.addTableColumn (firstColumn);
-    widget.setOutlineTableColumn(firstColumn);
-    NSBrowserCell cell = cast(NSBrowserCell)new NSBrowserCell().alloc().init();
-    cell.setLeaf(true);
-    firstColumn.setDataCell(cell);
-    cell.release();
+    widget.setOutlineTableColumn (firstColumn);
+    dataCell = cast(NSBrowserCell)new SWTBrowserCell ().alloc ().init ();
+    dataCell.setLeaf (true);
+    firstColumn.setDataCell (dataCell);
+    levelIndent = widget.indentationPerLevel ();
     
     scrollView = scrollWidget;
     view = widget;
-    scrollView.setDocumentView(widget);
-    parent.contentView().addSubview_(scrollView);
 }
 
 void createItem (TreeColumn column, int index) {
@@ -458,76 +544,47 @@
     if (columnCount is 0) {
         //TODO - clear attributes, alignment etc.
         nsColumn = firstColumn;
+        nsColumn.retain();
         firstColumn = null;
     } else {
         //TODO - set attributes, alignment etc.
-        NSString str = NSString.stringWith("");
-        nsColumn = cast(NSTableColumn)new NSTableColumn().alloc();
-        nsColumn.initWithIdentifier(str);
-        nsColumn.headerCell().setTitle(str);
-        (cast(NSTableView)view).addTableColumn (nsColumn);
+        NSOutlineView outlineView = (NSOutlineView)view;
+        NSString str = NSString.stringWith ("");
+        nsColumn = cast(NSTableColumn) new NSTableColumn ().alloc ();
+        nsColumn.initWithIdentifier (nsColumn);
+        nsColumn.setMinWidth(0);
+        nsColumn.headerCell ().setTitle (str);
+        outlineView.addTableColumn (nsColumn);
         int checkColumn = (style & DWT.CHECK) !is 0 ? 1 : 0;
-        (cast(NSTableView)view).moveColumn (columnCount + checkColumn, index + checkColumn);
-        NSBrowserCell cell = cast(NSBrowserCell)new NSBrowserCell().alloc().init();
-        cell.setLeaf(true);
-        nsColumn.setDataCell(cell);
-        cell.release();
+        outlineView.moveColumn (columnCount + checkColumn, index + checkColumn);
+        nsColumn.setDataCell (dataCell);
+        if (index is 0) {
+            outlineView.setOutlineTableColumn (nsColumn);
+        }
     }
+    column.createJNIRef ();
+    NSTableHeaderCell headerCell = (NSTableHeaderCell)new SWTTableHeaderCell ().alloc ().init ();
+    nsColumn.setHeaderCell (headerCell);
+    display.addWidget (headerCell, column);
     column.nsColumn = nsColumn;
-    nsColumn.headerCell().setTitle(NSString.stringWith(""));
-    nsColumn.setWidth(0);
+    nsColumn.setWidth (0);
     System.arraycopy (columns, index, columns, index + 1, columnCount++ - index);
     columns [index] = column;
     if (columnCount > 1) {
         for (int i=0; i<items.length; i++) {
             TreeItem item = items [i];
-            if (item !is null) {
-                String [] strings = item.strings;
-                if (strings !is null) {
-                    String [] temp = new String [columnCount];
-                    System.arraycopy (strings, 0, temp, 0, index);
-                    System.arraycopy (strings, index, temp, index+1, columnCount-index-1);
-                    temp [index] = "";
-                    item.strings = temp;
-                }
-                if (index is 0) item.text = "";
-                Image [] images = item.images;
-                if (images !is null) {
-                    Image [] temp = new Image [columnCount];
-                    System.arraycopy (images, 0, temp, 0, index);
-                    System.arraycopy (images, index, temp, index+1, columnCount-index-1);
-                    item.images = temp;
-                }
-                if (index is 0) item.image = null;
-                Color [] cellBackground = item.cellBackground;
-                if (cellBackground !is null) {
-                    Color [] temp = new Color [columnCount];
-                    System.arraycopy (cellBackground, 0, temp, 0, index);
-                    System.arraycopy (cellBackground, index, temp, index+1, columnCount-index-1);
-                    item.cellBackground = temp;
-                }
-                Color [] cellForeground = item.cellForeground;
-                if (cellForeground !is null) {
-                    Color [] temp = new Color [columnCount];
-                    System.arraycopy (cellForeground, 0, temp, 0, index);
-                    System.arraycopy (cellForeground, index, temp, index+1, columnCount-index-1);
-                    item.cellForeground = temp;
-                }
-                Font [] cellFont = item.cellFont;
-                if (cellFont !is null) {
-                    Font [] temp = new Font [columnCount];
-                    System.arraycopy (cellFont, 0, temp, 0, index);
-                    System.arraycopy (cellFont, index, temp, index+1, columnCount-index-1);
-                    item.cellFont = temp;
-                }
-            }
+            if (item !is null) createColumn (item, index);
+        }
+    } else {
+        for (int i = 0; i < itemCount; i++) {
+            clearCustomWidths (items[i]);
         }
     }
 }
 
 void createItem (TreeItem item, TreeItem parentItem, int index) {
     int count;
-    TreeItem[] items;
+    TreeItem [] items;
     if (parentItem !is null) {
         count = parentItem.itemCount;
         items = parentItem.items;
@@ -549,18 +606,20 @@
     }
     System.arraycopy (items, index, items, index + 1, count++ - index);
     items [index] = item;
-    item.items = new TreeItem[4];
-    item.createJNIRef();
-    SWTTreeItem handle = cast(SWTTreeItem)new SWTTreeItem().alloc().init();
-    handle.setTag(item.jniRef);
+    item.items = new TreeItem [4];
+    SWTTreeItem handle = (SWTTreeItem) new SWTTreeItem ().alloc ().init ();
     item.handle = handle;
+    item.createJNIRef ();
+    item.register ();
     if (parentItem !is null) {
         parentItem.itemCount = count;
     } else {
         this.itemCount = count;
     }
-    //TODO ?
-    (cast(NSTableView)view).reloadData();
+    ignoreExpand = true;
+    NSOutlineView widget = cast(NSOutlineView)view;
+    widget.reloadItem(parentItem !is null ? parentItem.handle : null, true);
+    ignoreExpand = false;
 }
 
 void createWidget () {
@@ -587,12 +646,35 @@
  */
 public void deselectAll () {
     checkWidget ();
-    NSTableView widget = cast(NSTableView)view;
+    NSTableView widget = cast(NSOutlineView) view;
     ignoreSelect = true;
-    widget.deselectAll(null);
+    widget.deselectAll (null);
     ignoreSelect = false;
 }
 
+void deregister () {
+    super.deregister ();
+    display.removeWidget (headerView);
+    display.removeWidget (dataCell);
+}
+
+/**
+ * Deselects an item in the receiver.  If the item was already
+ * deselected, it remains deselected.
+ *
+ * @param item the item to be deselected
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the item is null</li>
+ *    <li>ERROR_INVALID_ARGUMENT - if the item has been disposed</li>
+ * </ul>
+ * @exception DWTException <ul>
+ *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.4
+ */
 public void deselect (TreeItem item) {
     checkWidget ();
     if (item is null) error (DWT.ERROR_NULL_ARGUMENT);
@@ -683,36 +765,32 @@
             }
         }
     }
-//  if (columnCount is 1) {
-//      column_id = column.id; idCount = 0;
-//      DataBrowserListViewHeaderDesc desc = new DataBrowserListViewHeaderDesc ();
-//      desc.version = OS.kDataBrowserListViewLatestHeaderDesc;
-//      short [] width = new short [1];
-//      OS.GetDataBrowserTableViewNamedColumnWidth (handle, column_id, width);
-//      desc.minimumWidth = desc.maximumWidth = width [0];
-//      int str = OS.CFStringCreateWithCharacters (OS.kCFAllocatorDefault, null, 0);
-//      desc.titleString = str;
-//      OS.SetDataBrowserListViewHeaderDesc (handle, column_id, desc);
-//      OS.CFRelease (str);
-//  } else {
-//      int [] disclosure = new int [1];
-//      bool [] expandableRows = new bool [1];
-//      OS.GetDataBrowserListViewDisclosureColumn (handle, disclosure, expandableRows);
-//      if (disclosure [0] is column.id) {
-//          TreeColumn firstColumn = columns [1];
-//          firstColumn.style &= ~(DWT.LEFT | DWT.RIGHT | DWT.CENTER);
-//          firstColumn.style |= DWT.LEFT;
-//          firstColumn.updateHeader();
-//          OS.SetDataBrowserListViewDisclosureColumn (handle, firstColumn.id, expandableRows [0]);
-//      }
-//      if (OS.RemoveDataBrowserTableViewColumn (handle, column.id) !is OS.noErr) {
-//          error (DWT.ERROR_ITEM_NOT_REMOVED);
-//      }
-//  }
+
+    int oldIndex = (int)/*64*/((NSOutlineView)view).columnWithIdentifier (column.nsColumn);
+
+    if (columnCount is 1) {
+        //TODO - reset attributes
+        firstColumn = column.nsColumn;
+        firstColumn.setWidth (0);
+    } else {
+        if (index is 0) {
+            ((NSOutlineView)view).setOutlineTableColumn(columns[1].nsColumn);
+        }
+        ((NSOutlineView)view).removeTableColumn(column.nsColumn);
+    }
     System.arraycopy (columns, index + 1, columns, index, --columnCount - index);
     columns [columnCount] = null;
-    for (int i=index; i<columnCount; i++) {
-        columns [i].sendEvent (DWT.Move);
+
+    NSArray array = ((NSOutlineView)view).tableColumns ();
+    int arraySize = (int)/*64*/array.count ();
+    for (int i = oldIndex; i < arraySize; i++) {
+        int /*long*/ columnId = array.objectAtIndex (i).id;
+        for (int j = 0; j < columnCount; j++) {
+            if (columns[j].nsColumn.id is columnId) {
+                columns [j].sendEvent (DWT.Move);
+                break;
+            }
+        }
     }
 }
 
@@ -737,10 +815,10 @@
     items [count] = null;
     if (parentItem !is null) {
         parentItem.itemCount = count;
-        (cast(NSOutlineView)view).reloadItem_reloadChildren_(parentItem.handle, true);
+        (cast(NSOutlineView) view).reloadItem (parentItem.handle, true);
     } else {
         this.itemCount = count;
-        (cast(NSOutlineView)view).reloadItem_(null);
+        (cast(NSOutlineView) view).reloadItem (null);
     }
     
     //noteNumberOfRowsChanged was causing crashes whenever
@@ -755,6 +833,205 @@
 //  fixScrollBar ();
 }
 
+void drawInteriorWithFrame_inView (int /*long*/ id, int /*long*/ sel, int /*long*/ cellFrame, int /*long*/ view) {
+    NSRect rect = new NSRect ();
+    OS.memmove (rect, cellFrame, NSRect.sizeof);
+
+    NSOutlineView outlineView = (NSOutlineView)this.view;
+    NSBrowserCell cell = new NSBrowserCell (id);
+    NSRange rowsRange = outlineView.rowsInRect (rect);
+    int rowIndex = (int)/*64*/rowsRange.location;
+    TreeItem item = (TreeItem) display.getWidget (outlineView.itemAtRow (rowIndex).id);
+    int columnIndex = 0;
+    id nsColumn = null;
+    int nsColumnIndex = 0;
+    if (columnCount !is 0) {
+        NSIndexSet columnsSet = outlineView.columnIndexesInRect (rect);
+        nsColumnIndex = (int)/*64*/columnsSet.firstIndex ();
+        NSArray nsColumns = outlineView.tableColumns ();
+        nsColumn = nsColumns.objectAtIndex (nsColumnIndex);
+        for (int i = 0; i < columnCount; i++) {
+            if (columns[i].nsColumn.id is nsColumn.id) {
+                columnIndex = indexOf (columns[i]);
+                break;
+            }
+        }
+    }
+
+    Color background = item.cellBackground !is null ? item.cellBackground [columnIndex] : null;
+    if (background is null) background = item.background;
+    bool drawBackground = background !is null;
+    bool drawForeground = true;
+    bool isSelected = outlineView.isRowSelected (rowIndex);
+    bool drawSelection = isSelected;
+
+    NSColor nsSelectionBackground = null;
+    NSColor nsSelectionForeground = null;
+    if (isSelected) {
+        if (isFocusControl ()) {
+            nsSelectionForeground = NSColor.alternateSelectedControlTextColor ();
+        } else {
+            nsSelectionForeground = NSColor.selectedControlTextColor ();
+        }
+        nsSelectionForeground = nsSelectionForeground.colorUsingColorSpace (NSColorSpace.deviceRGBColorSpace ());
+        nsSelectionBackground = cell.highlightColorInView (outlineView);
+        nsSelectionBackground = nsSelectionBackground.colorUsingColorSpace (NSColorSpace.deviceRGBColorSpace ());
+    }
+
+    NSRect fullRect = new NSRect ();
+    fullRect.y = rect.y; fullRect.height = rect.height;
+    if (columnCount is 0) {
+        fullRect.x = rect.x;
+        if (item.customWidth !is -1) {
+            fullRect.width = item.customWidth;
+        } else {
+            NSSize contentSize = cell.cellSizeForBounds (rect);
+            fullRect.width = contentSize.width;
+        }
+    } else {
+        NSSize spacing = outlineView.intercellSpacing ();
+        if (nsColumn.id is outlineView.outlineTableColumn ().id) {
+            NSRect columnRect = outlineView.rectOfColumn (nsColumnIndex);
+            fullRect.x = columnRect.x; fullRect.width = columnRect.width + spacing.width;
+        } else {
+            fullRect.x = rect.x;
+            fullRect.width = rect.width + spacing.width;
+        }
+    }
+
+    if (hooks (DWT.EraseItem)) {
+        NSRect eraseItemRect = null;
+        // TODO how to handle rearranged columns?  The third clause below ensures that
+        // there are either 0 columns or that column 0 is still the first physical column.
+        if (columnIndex is 0 && (style & DWT.CHECK) !is 0 && (columnCount is 0 || outlineView.columnWithIdentifier (columns[0].nsColumn) is 1)) {
+            eraseItemRect = new NSRect ();
+            eraseItemRect.y = fullRect.y;
+            eraseItemRect.width = fullRect.x + fullRect.width;
+            eraseItemRect.height = fullRect.height;
+        } else {
+            eraseItemRect = fullRect;
+        }
+        GCData data = new GCData ();
+        data.paintRect = eraseItemRect;
+        GC gc = GC.cocoa_new (this, data);
+        gc.setFont (item.getFont (columnIndex));
+        if (isSelected) {
+            float /*double*/[] components = new float /*double*/[(int)/*64*/nsSelectionForeground.numberOfComponents ()];
+            nsSelectionForeground.getComponents (components);   
+            Color selectionForeground = Color.cocoa_new (display, components);
+            gc.setForeground (selectionForeground);
+            components = new float /*double*/[(int)/*64*/nsSelectionBackground.numberOfComponents ()];
+            nsSelectionBackground.getComponents (components);   
+            Color selectionBackground = Color.cocoa_new (display, components);
+            gc.setBackground (selectionBackground);
+        } else {
+            gc.setForeground (item.getForeground (columnIndex));
+            gc.setBackground (item.getBackground (columnIndex));
+        }
+
+        Event event = new Event ();
+        event.item = item;
+        event.gc = gc;
+        event.index = columnIndex;
+        event.detail = DWT.FOREGROUND;
+        if (drawBackground) event.detail |= DWT.BACKGROUND;
+        if (isSelected) event.detail |= DWT.SELECTED;
+        event.x = (int)eraseItemRect.x;
+        event.y = (int)eraseItemRect.y;
+        event.width = (int)eraseItemRect.width;
+        event.height = (int)eraseItemRect.height;
+        sendEvent (DWT.EraseItem, event);
+        gc.dispose ();
+        if (item.isDisposed ()) return;
+        if (!event.doit) {
+            drawForeground = drawBackground = drawSelection = false; 
+        } else {
+            drawBackground = drawBackground && (event.detail & DWT.BACKGROUND) !is 0;
+            drawForeground = (event.detail & DWT.FOREGROUND) !is 0;
+            drawSelection = drawSelection && (event.detail & DWT.SELECTED) !is 0;           
+        }
+        if (drawSelection) {
+            NSRect selectionRect = new NSRect ();
+            selectionRect.y = rect.y; selectionRect.height = rect.height;
+            if (columnCount > 0) {
+                NSRect columnRect = outlineView.rectOfColumn (nsColumnIndex);
+                selectionRect.x = columnRect.x; selectionRect.width = columnRect.width;
+            } else {
+                NSRect rowRect = outlineView.rectOfRow (rowIndex);
+                if ((style & DWT.CHECK) !is 0) {
+                    /* highlighting at this stage draws over the checkbox, so don't include its column */
+                    int checkWidth = (int)/*64*/checkColumn.width ();
+                    selectionRect.x = checkWidth;
+                    selectionRect.width = rowRect.width - checkWidth;
+                } else {
+                    selectionRect.width = rowRect.width;
+                }
+            }
+            callSuper (outlineView.id, OS.sel_highlightSelectionInClipRect_, selectionRect);
+        }
+    }
+
+    if (drawBackground && !drawSelection) {
+        NSGraphicsContext context = NSGraphicsContext.currentContext ();
+        context.saveGraphicsState ();
+        float[] colorRGB = background.handle;
+        NSColor color = NSColor.colorWithDeviceRed (colorRGB[0], colorRGB[1], colorRGB[2], 1f);
+        color.setFill ();
+        NSBezierPath.fillRect (fullRect);
+        context.restoreGraphicsState ();
+    }
+
+    if (drawForeground) {
+        cell.setHighlighted (false);
+        callSuper (id, sel, rect, view);
+    }
+
+    if (hooks (DWT.PaintItem)) {
+        NSRect contentRect = cell.titleRectForBounds (rect);
+        NSSize contentSize = cell.cellSizeForBounds (rect);
+
+        GCData data = new GCData ();
+        // TODO how to handle rearranged columns?  The third clause below ensures that
+        // there are either 0 columns or that column 0 is still the first physical column.
+        if (columnIndex is 0 && (style & DWT.CHECK) !is 0 && (columnCount is 0 || outlineView.columnWithIdentifier (columns[0].nsColumn) is 1)) {
+            NSRect gcRect = new NSRect ();
+            gcRect.y = fullRect.y;
+            gcRect.width = fullRect.x + fullRect.width;
+            gcRect.height = fullRect.height;
+            data.paintRect = gcRect;
+        } else {
+            data.paintRect = fullRect;
+        }
+        GC gc = GC.cocoa_new (this, data);
+        gc.setFont (item.getFont (columnIndex));
+        if (isSelected) {
+            float /*double*/[] components = new float /*double*/[(int)/*64*/nsSelectionForeground.numberOfComponents ()];
+            nsSelectionForeground.getComponents (components);   
+            Color selectionForeground = Color.cocoa_new (display, components);
+            gc.setForeground (selectionForeground);
+            components = new float /*double*/[(int)/*64*/nsSelectionBackground.numberOfComponents ()];
+            nsSelectionBackground.getComponents (components);   
+            Color selectionBackground = Color.cocoa_new (display, components);
+            gc.setBackground (selectionBackground);
+            gc.setBackground (display.getSystemColor (DWT.COLOR_GREEN));
+        } else {
+            gc.setForeground (item.getForeground (columnIndex));
+            gc.setBackground (item.getBackground (columnIndex));
+        }
+
+        Event event = new Event ();
+        event.item = item;
+        event.gc = gc;
+        event.index = columnIndex;
+        if (isSelected) event.detail |= DWT.SELECTED;
+        event.x = (int)contentRect.x;
+        event.y = (int)contentRect.y;
+        event.width = (int)Math.ceil (contentSize.width);
+        event.height = (int)Math.ceil (fullRect.height);
+        sendEvent (DWT.PaintItem, event);
+        gc.dispose ();
+    }
+}
 
 void fixScrollBar () {
     /*
@@ -775,6 +1052,15 @@
     return 20; //TODO - compute width
 }
 
+TreeColumn getColumn (id id) {
+    for (int i = 0; i < columnCount; i++) {
+        if (columns[i].nsColumn.id is id.id) {
+            return columns[i]; 
+        }
+    }
+    return null;
+}
+
 /**
  * Returns the column at the given, zero-relative index in the
  * receiver. Throws an exception if the index is out of range.
@@ -862,12 +1148,11 @@
 public int [] getColumnOrder () {
     checkWidget ();
     int [] order = new int [columnCount];
-    int [] position = new int [1];
-    for (int i=0; i<columnCount; i++) {
+    for (int i = 0; i < columnCount; i++) {
         TreeColumn column = columns [i];
-//      OS.GetDataBrowserTableViewColumnPosition (handle, column.id, position);
-//      if ((style & DWT.CHECK) !is 0) position [0] -= 1;
-        order [position [0]] = i;
+        int index = ((NSOutlineView)view).columnWithIdentifier (column.nsColumn);
+        if ((style & DWT.CHECK) !is 0) index -= 1;
+        order [index] = i;
     }
     return order;
 }
@@ -939,9 +1224,9 @@
  */
 public int getHeaderHeight () {
     checkWidget ();
-    NSTableHeaderView headerView = (cast(NSTableView)view).headerView();
+    NSTableHeaderView headerView = (cast(NSOutlineView) view).headerView ();
     if (headerView is null) return 0;
-    return cast(int)headerView.bounds().height;
+    return cast(int) headerView.bounds ().height;
 }
 
 /**
@@ -965,7 +1250,12 @@
  */
 public bool getHeaderVisible () {
     checkWidget ();
-    return (cast(NSTableView)view).headerView() !is null;
+    return (cast(NSOutlineView) view).headerView () !is null;
+}
+
+int getInsetWidth () {
+    //TODO - wrong
+    return 20;
 }
 
 /**
@@ -989,7 +1279,7 @@
     checkWidget ();
     int count = getItemCount ();
     if (index < 0 || index >= count) error (DWT.ERROR_INVALID_RANGE);
-    return _getItem (null, index);
+    return _getItem (null, index, true);
 }
 
 /**
@@ -1018,58 +1308,17 @@
 public TreeItem getItem (Point point) {
     checkWidget ();
     if (point is null) error (DWT.ERROR_NULL_ARGUMENT);
-//  Rect rect = new Rect ();
-//  dwt.internal.carbon.Point pt = new dwt.internal.carbon.Point ();
-//  OS.SetPt (pt, cast(short) point.x, cast(short) point.y);
-//  if (0 < lastHittest && lastHittest <= items.length && lastHittestColumn !is 0) {
-//      TreeItem item = _getItem (lastHittest, false);
-//      if (item !is null) {
-//          if (OS.GetDataBrowserItemPartBounds (handle, item.id, lastHittestColumn, OS.kDataBrowserPropertyDisclosurePart, rect) is OS.noErr) {
-//              if (OS.PtInRect (pt, rect)) return null;
-//          }
-//          if (OS.GetDataBrowserItemPartBounds (handle, item.id, lastHittestColumn, OS.kDataBrowserPropertyEnclosingPart, rect) is OS.noErr) {
-//              if (rect.top <= pt.v && pt.v <= rect.bottom) {
-//                  if ((style & DWT.FULL_SELECTION) !is 0) {
-//                      return item;
-//                  } else {
-//                      return OS.PtInRect (pt, rect) ? item : null;
-//                  }
-//              }
-//          }
-//      }
-//  }
-//  //TODO - optimize
-//  for (int i=0; i<items.length; i++) {
-//      TreeItem item = items [i];
-//      if (item !is null) {
-//          if (OS.GetDataBrowserItemPartBounds (handle, item.id, column_id, OS.kDataBrowserPropertyDisclosurePart, rect) is OS.noErr) {
-//              if (OS.PtInRect (pt, rect)) return null;
-//          }
-//          if (columnCount is 0) {
-//              if (OS.GetDataBrowserItemPartBounds (handle, item.id, column_id, OS.kDataBrowserPropertyEnclosingPart, rect) is OS.noErr) {
-//                  if (rect.top <= pt.v && pt.v <= rect.bottom) {
-//                      if ((style & DWT.FULL_SELECTION) !is 0) {
-//                          return item;
-//                      } else {
-//                          return OS.PtInRect (pt, rect) ? item : null;
-//                      }
-//                  }
-//              }
-//          } else {
-//              for (int j = 0; j < columnCount; j++) {
-//                  if (OS.GetDataBrowserItemPartBounds (handle, item.id, columns [j].id, OS.kDataBrowserPropertyEnclosingPart, rect) is OS.noErr) {
-//                      if (rect.top <= pt.v && pt.v <= rect.bottom) {
-//                          if ((style & DWT.FULL_SELECTION) !is 0) {
-//                              return item;
-//                          } else {
-//                              return OS.PtInRect (pt, rect) ? item : null;
-//                          }
-//                      }
-//                  }
-//              }
-//          }
-//      }
-//  }
+    NSOutlineView widget = (NSOutlineView)view;
+    NSPoint pt = new NSPoint();
+    pt.x = point.x;
+    pt.y = point.y;
+    int row = (int)/*64*/widget.rowAtPoint(pt);
+    if (row is -1) return null;
+    id id = widget.itemAtRow(row);
+    Widget item = display.getWidget (id.id);
+    if (item !is null && item instanceof TreeItem) {
+        return (TreeItem)item;
+    }
     return null;
 }
 
@@ -1091,6 +1340,10 @@
     return itemCount;
 }
 
+int getItemCount (TreeItem item) {
+    return item is null ? itemCount : item.itemCount;
+}
+
 /**
  * Returns the height of the area which would be used to
  * display <em>one</em> of the items in the tree.
@@ -1104,7 +1357,7 @@
  */
 public int getItemHeight () {
     checkWidget ();
-    return cast(int)(cast(NSTableView)view).rowHeight();
+    return cast(int)(cast(NSOutlineView) view).rowHeight ();
 }
 
 /**
@@ -1128,7 +1381,7 @@
     checkWidget ();
     TreeItem [] result = new TreeItem [itemCount];
     for (int i=0; i<itemCount; i++) {
-        result [i] = _getItem (null, i);
+        result [i] = _getItem (null, i, true);
     }
     return result;
 }
@@ -1154,12 +1407,7 @@
  */
 public bool getLinesVisible () {
     checkWidget ();
-//  if (OS.VERSION >= 0x1040) {
-//      int [] attrib = new int [1];
-//      OS.DataBrowserGetAttributes (handle, attrib);
-//      return (attrib [0] & (OS.kDataBrowserAttributeListViewAlternatingRowColors | OS.kDataBrowserAttributeListViewDrawColumnDividers)) !is 0;
-//  }
-    return false;
+    return ((NSOutlineView) view).usesAlternatingRowBackgroundColors ();
 }
 
 /**
@@ -1197,21 +1445,21 @@
  */
 public TreeItem [] getSelection () {
     checkWidget ();
-    NSOutlineView widget = cast(NSOutlineView)view;
-    if (widget.numberOfSelectedRows() is 0) {
+    NSOutlineView widget = cast(NSOutlineView) view;
+    if (widget.numberOfSelectedRows () is 0) {
         return new TreeItem [0];
     }
-    NSIndexSet selection = widget.selectedRowIndexes();
-    int count = selection.count();
-    int [] indexBuffer = new int [count];
-    selection.getIndexes(indexBuffer, count, 0);
-    TreeItem [] result = new TreeItem  [count];
+    NSIndexSet selection = widget.selectedRowIndexes ();
+    int count = (int)/*64*/selection.count ();
+    int /*long*/ [] indexBuffer = new int /*long*/ [count];
+    selection.getIndexes (indexBuffer, count, 0);
+    TreeItem [] result = new TreeItem [count];
     for (int i=0; i<count; i++) {
-        id item = widget.itemAtRow(indexBuffer [i]);
-        int jniRef = OS.objc_msgSend(item.id, OS.sel_tag);
-        if (jniRef !is -1 && jniRef !is 0) {
+        id id = widget.itemAtRow (indexBuffer [i]);
+        Widget item = display.getWidget (id.id);
+        if (item !is null && item instanceof TreeItem) {
             //TODO virtual
-            result[i] = cast(TreeItem)OS.JNIGetObject(jniRef);
+            result[i] = cast(TreeItem) item;
         }
     }
     return result;
@@ -1229,7 +1477,7 @@
  */
 public int getSelectionCount () {
     checkWidget ();
-    return (cast(NSTableView)view).numberOfSelectedRows();
+    return cast(int)/*64*/(cast(NSOutlineView) view).numberOfSelectedRows ();
 }
 
 /**
@@ -1289,7 +1537,7 @@
  * @since 2.1
  */
 public TreeItem getTopItem () {
-    checkWidget();
+    checkWidget ();
 //  //TODO - optimize
 //  Rect rect = new Rect ();
 //  int y = getBorder () + getHeaderHeight ();
@@ -1305,6 +1553,14 @@
     return null;
 }
 
+void highlightSelectionInClipRect(int /*long*/ id, int /*long*/ sel, int /*long*/ rect) {
+    if (!hooks (DWT.EraseItem)) {
+        NSRect clipRect = new NSRect ();
+        OS.memmove (clipRect, rect, NSRect.sizeof);
+        callSuper (id, sel, clipRect);
+    }
+}
+
 /**
  * Searches the receiver's list starting at the first column
  * (index 0) until a column is found that is equal to the 
@@ -1365,104 +1621,227 @@
     return -1;
 }
 
-int outlineView_child_ofItem(int outlineView, int index, int ref) {
-    TreeItem parent = null;
-    if (ref !is 0) parent = cast(TreeItem)OS.JNIGetObject(OS.objc_msgSend(ref, OS.sel_tag));
-    TreeItem item = _getItem(parent, index);
+bool isTrim (NSView view) {
+    if (super.isTrim (view)) return true;
+    return view.id_ is headerView.id_;
+}
+
+int /*long*/ outlineView_child_ofItem (int /*long*/ id, int /*long*/ sel, int /*long*/ outlineView, int /*long*/ index, int /*long*/ itemID) {
+    TreeItem parent = (TreeItem) display.getWidget (itemID);
+    TreeItem item = _getItem (parent, (int)/*64*/index, true);
+    checkData (item, false);
     return item.handle.id;
 }
 
-int outlineView_objectValueForTableColumn_byItem(int outlineView, int tableColumn, int ref) {
-    TreeItem item = cast(TreeItem)OS.JNIGetObject(OS.objc_msgSend(ref, OS.sel_tag));
+void outlineView_didClickTableColumn (int /*long*/ id, int /*long*/ sel, int /*long*/ outlineView, int /*long*/ tableColumn) {
+    TreeColumn column = getColumn (new id (tableColumn));
+    column.postEvent (DWT.Selection);
+}
+
+int /*long*/ outlineView_objectValueForTableColumn_byItem (int /*long*/ id, int /*long*/ sel, int /*long*/ outlineView, int /*long*/ tableColumn, int /*long*/ itemID) {
+    TreeItem item = (TreeItem) display.getWidget (itemID);
     if (checkColumn !is null && tableColumn is checkColumn.id) {
         NSNumber value;
         if (item.checked && item.grayed) {
-            value = NSNumber.numberWithInt(OS.NSMixedState);
+            value = NSNumber.numberWithInt (OS.NSMixedState);
         } else {
-            value = NSNumber.numberWithInt(item.checked ? OS.NSOnState : OS.NSOffState);
+            value = NSNumber.numberWithInt (item.checked ? OS.NSOnState : OS.NSOffState);
         }
         return value.id;
     }
     for (int i=0; i<columnCount; i++) {
         if (columns [i].nsColumn.id is tableColumn) {
-            return item.createString(i).id;
+            return item.createString (i).id;
         }
     }
-    return item.createString(0).id;
+    return item.createString (0).id;
 }
 
-bool outlineView_isItemExpandable(int outlineView, int ref) {
-    if (ref is 0) return true;
-    return (cast(TreeItem)OS.JNIGetObject(OS.objc_msgSend(ref, OS.sel_tag))).itemCount !is 0;
+bool outlineView_isItemExpandable (int /*long*/ id, int /*long*/ sel, int /*long*/ outlineView, int /*long*/ item) {
+    if (item is 0) return true;
+    return (cast(TreeItem) display.getWidget (item)).itemCount !is 0;
 }
 
-int outlineView_numberOfChildrenOfItem(int outlineView, int ref) {
-    if (ref is 0) return itemCount;
-    return (cast(TreeItem)OS.JNIGetObject(OS.objc_msgSend(ref, OS.sel_tag))).itemCount;
+int /*long*/ outlineView_numberOfChildrenOfItem (int /*long*/ id, int /*long*/ sel, int /*long*/ outlineView, int /*long*/ item) {
+    if (item is 0) return itemCount;
+    return (cast(TreeItem) display.getWidget (item)).itemCount;
 }
 
-void outlineView_willDisplayCell_forTableColumn_item(int outlineView, int cell, int tableColumn, int ref) {
+void outlineView_willDisplayCell_forTableColumn_item (int /*long*/ id, int /*long*/ sel, int /*long*/ outlineView, int /*long*/ cell, int /*long*/ tableColumn, int /*long*/ itemID) {
     if (checkColumn !is null && tableColumn is checkColumn.id) return;
-    TreeItem item = cast(TreeItem)OS.JNIGetObject(OS.objc_msgSend(ref, OS.sel_tag));
+    TreeItem item = cast(TreeItem) display.getWidget(itemID);
     Image image = item.image;
+    int columnIndex = 0;
     for (int i=0; i<columnCount; i++) {
         if (columns [i].nsColumn.id is tableColumn) {
-            image = item.getImage(i);
+            image = item.getImage (i);
+            columnIndex = i;
         }
     }
-    NSBrowserCell browserCell = new NSBrowserCell(cell);
-    browserCell.setImage(image !is null ? image.handle : null);
+    NSBrowserCell browserCell = new NSBrowserCell (cell);
+    browserCell.setImage (image !is null ? image.handle : null);
+    browserCell.setFont (item.getFont (columnIndex).handle);
+
+    if (hooks (DWT.MeasureItem)) {
+        NSOutlineView view = (NSOutlineView)this.view;
+        int nsColumnIndex = (int)/*64*/view.columnWithIdentifier (new id (tableColumn));
+        int rowIndex = (int)/*64*/view.rowForItem (new id (itemID));
+        NSRect rect = view.frameOfCellAtColumn (nsColumnIndex, rowIndex);
+        NSRect contentRect = browserCell.titleRectForBounds (rect);
+        NSSize contentSize = browserCell.cellSizeForBounds (rect);
+
+        GCData data = new GCData ();
+        data.paintRect = view.frame ();
+        GC gc = GC.cocoa_new (this, data);
+        gc.setFont (item.getFont (columnIndex));
+        int rowHeight = (int)view.rowHeight ();
+        Event event = new Event ();
+        event.item = item;
+        event.gc = gc;
+        event.index = columnIndex;
+        event.x = (int)contentRect.x;
+        event.y = (int)contentRect.y;
+        event.width = (int)Math.ceil (contentSize.width);
+        event.height = rowHeight;
+        sendEvent (DWT.MeasureItem, event);
+        gc.dispose ();
+        if (isDisposed ()) return;
+        if (rowHeight < event.height) {
+            view.setRowHeight (event.height);
+        }
+        if (columnCount is 0) {
+            int change = event.width - (item.customWidth !is -1 ? item.customWidth : (int)Math.ceil (contentSize.width));
+            if (item.customWidth !is -1 || event.width !is (int)Math.ceil (contentSize.width)) {
+                item.customWidth = event.width; 
+            }
+            if (change !is 0) setScrollWidth (item, false, false);
+        }
+    }
 }
 
-void outlineViewSelectionDidChange(int notification) {
-    if (ignoreSelect) return;
-    NSOutlineView widget = cast(NSOutlineView)view;
-    int row = widget.selectedRow();
-    if(row is -1)
-        postEvent(DWT.Selection);
-    else {
-        id _id = widget.itemAtRow(row);
-        TreeItem item = cast(TreeItem)OS.JNIGetObject(OS.objc_msgSend(_id.id, OS.sel_tag));
-        Event event = new Event();
-        event.item = item;
-        event.index = row;
-        postEvent(DWT.Selection, event);
+void outlineViewColumnDidMove (int /*long*/ id, int /*long*/ sel, int /*long*/ aNotification) {
+    NSNotification notification = new NSNotification (aNotification);
+    NSDictionary userInfo = notification.userInfo ();
+    id nsOldIndex = userInfo.valueForKey (NSString.stringWith ("NSOldColumn")); //$NON-NLS-1$
+    id nsNewIndex = userInfo.valueForKey (NSString.stringWith ("NSNewColumn")); //$NON-NLS-1$
+    int oldIndex = new NSNumber (nsOldIndex).intValue ();
+    int newIndex = new NSNumber (nsNewIndex).intValue ();
+    int startIndex = Math.min (oldIndex, newIndex);
+    int endIndex = Math.max (oldIndex, newIndex);
+    NSOutlineView outlineView = (NSOutlineView)view;
+    NSArray nsColumns = outlineView.tableColumns ();
+    for (int i = startIndex; i <= endIndex; i++) {
+        id columnId = nsColumns.objectAtIndex (i);
+        TreeColumn column = getColumn (columnId);
+        if (column !is null) {
+            column.sendEvent (DWT.Move);
+            if (isDisposed ()) return;
+        }
     }
 }
 
-bool outlineView_shouldCollapseItem(int outlineView, int ref) {
-    if (!ignoreExpand) {
-        TreeItem item = cast(TreeItem)OS.JNIGetObject(OS.objc_msgSend(ref, OS.sel_tag));
-        Event event = new Event();
-        event.item = item;
-        sendEvent(DWT.Collapse, event);
-        item.expanded = false;
+void outlineViewColumnDidResize (int /*long*/ id, int /*long*/ sel, int /*long*/ aNotification) {
+    NSNotification notification = new NSNotification (aNotification);
+    NSDictionary userInfo = notification.userInfo ();
+    id columnId = userInfo.valueForKey (NSString.stringWith ("NSTableColumn")); //$NON-NLS-1$
+    TreeColumn column = getColumn (columnId);
+    if (column is null) return; /* either CHECK column or firstColumn in 0-column Tree */
+
+    column.sendEvent (DWT.Resize);
+    if (isDisposed ()) return;
+
+    NSOutlineView outlineView = (NSOutlineView)view;
+    int index = (int)/*64*/outlineView.columnWithIdentifier (columnId);
+    if (index is -1) return; /* column was disposed in Resize callback */
+
+    NSArray nsColumns = outlineView.tableColumns ();
+    int columnCount = (int)/*64*/outlineView.numberOfColumns ();
+    for (int i = index + 1; i < columnCount; i++) {
+        columnId = nsColumns.objectAtIndex (i);
+        column = getColumn (columnId);
+        if (column !is null) {
+            column.sendEvent (DWT.Move);
+            if (isDisposed ()) return;
+        }
     }
-    return true;
+}
+
+void outlineViewItemDidExpand (int /*long*/ id, int /*long*/ sel, int /*long*/ notification) {
+    NSNotification nsNotification = new NSNotification (notification);
+    NSDictionary info = nsNotification.userInfo ();
+    NSString key = NSString.stringWith ("NSObject"); //$NON-NLS-1$
+    int /*long*/ itemHandle = info.objectForKey (key).id;
+    TreeItem item = (TreeItem)display.getWidget (itemHandle);
+    setScrollWidth (item.getItems (), true, true);
 }
 
-bool outlineView_shouldExpandItem(int outlineView, int ref) {
-    if (!ignoreExpand) {
-        TreeItem item = cast(TreeItem)OS.JNIGetObject(OS.objc_msgSend(ref, OS.sel_tag));
-        Event event = new Event();
+void outlineViewSelectionDidChange (int /*long*/ id, int /*long*/ sel, int /*long*/ notification) {
+    if (ignoreSelect) return;
+    NSOutlineView widget = cast(NSOutlineView) view;
+    int row = (int)/*64*/widget.selectedRow ();
+    if (row is -1)
+        postEvent (DWT.Selection);
+    else {
+        id _id = widget.itemAtRow (row);
+        TreeItem item = cast(TreeItem) display.getWidget (_id.id);
+        Event event = new Event ();
         event.item = item;
-        sendEvent(DWT.Expand, event);
-        item.expanded = true;
+        event.index = row;
+        postEvent (DWT.Selection, event);
     }
-    return true;
+}
+
+bool outlineView_shouldCollapseItem (int /*long*/ id, int /*long*/ sel, int /*long*/ outlineView, int /*long*/ itemID) {
+    TreeItem item = (TreeItem) display.getWidget (itemID);
+    if (!ignoreExpand) {
+        Event event = new Event ();
+        event.item = item;
+        sendEvent (DWT.Collapse, event);
+        item.expanded = false;
+        ignoreExpand = true;
+        ((NSOutlineView) view).collapseItem (item.handle);
+        ignoreExpand = false;
+        return false;
+    }
+    return !item.expanded;
 }
 
-void outlineView_setObjectValue_forTableColumn_byItem(int outlineView, int object, int tableColumn, int ref) {
-    TreeItem item = cast(TreeItem)OS.JNIGetObject(OS.objc_msgSend(ref, OS.sel_tag));
+bool outlineView_shouldExpandItem (int /*long*/ id, int /*long*/ sel, int /*long*/ outlineView, int /*long*/ itemID) {
+    final TreeItem item = (TreeItem) display.getWidget (itemID);
+    if (!ignoreExpand) {
+        Event event = new Event ();
+        event.item = item;
+        sendEvent (DWT.Expand, event);
+        item.expanded = true;
+        ignoreExpand = true;
+        ((NSOutlineView) view).expandItem (item.handle);
+        ignoreExpand = false;
+        return false;
+    }
+    return item.expanded;
+}
+
+void outlineView_setObjectValue_forTableColumn_byItem (int /*long*/ id, int /*long*/ sel, int /*long*/ outlineView, int /*long*/ object, int /*long*/ tableColumn, int /*long*/ itemID) {
     if (checkColumn !is null && tableColumn is checkColumn.id)  {
+        TreeItem item = (TreeItem) display.getWidget (itemID);
         item.checked = !item.checked;
-        Event event = new Event();
+        Event event = new Event ();
         event.detail = DWT.CHECK;
         event.item = item;
-        postEvent(DWT.Selection, event);
+        postEvent (DWT.Selection, event);
+        NSOutlineView view = (NSOutlineView)this.view;
+        int rowIndex = (int)/*64*/view.rowForItem (new id (itemID));
+        NSRect rect = view.rectOfRow (rowIndex);
+        view.setNeedsDisplayInRect (rect);
     }
 }
 
+void register () {
+    super.register ();
+    display.addWidget (headerView, this);
+    display.addWidget (dataCell, this);
+}
+
 void releaseChildren (bool destroy) {
     for (int i=0; i<items.length; i++) {
         TreeItem item = items [i];
@@ -1485,12 +1864,14 @@
 
 void releaseHandle () {
     super.releaseHandle ();
-    if (headerView !is null) headerView.release();
+    if (headerView !is null) headerView.release ();
     headerView = null;
-    if (firstColumn !is null) firstColumn.release();
+    if (firstColumn !is null) firstColumn.release ();
     firstColumn = null;
-    if (checkColumn !is null) checkColumn.release();
+    if (checkColumn !is null) checkColumn.release ();
     checkColumn = null;
+    if (dataCell !is null) dataCell.release ();
+    dataCell = null;
 }
 
 void releaseWidget () {
@@ -1515,9 +1896,7 @@
     }
     items = new TreeItem [4];
     itemCount = 0;
-    (cast(NSOutlineView)view).reloadItem_(null);
-    //(cast(NSTableView)view).noteNumberOfRowsChanged();
-//  setScrollWidth (true);
+    (cast(NSOutlineView) view).reloadItem (null);
 }
 
 /**
@@ -1561,7 +1940,7 @@
  * @see TreeListener
  * @see #addTreeListener
  */
-public void removeTreeListener(TreeListener listener) {
+public void removeTreeListener (TreeListener listener) {
     checkWidget ();
     if (listener is null) error (DWT.ERROR_NULL_ARGUMENT);
     if (eventTable is null) return;
@@ -1589,7 +1968,7 @@
 public void setInsertMark (TreeItem item, bool before) {
     checkWidget ();
     if (item !is null) {
-        if (item.isDisposed()) error(DWT.ERROR_INVALID_ARGUMENT);
+        if (item.isDisposed ()) error (DWT.ERROR_INVALID_ARGUMENT);
     }
 }
 
@@ -1607,44 +1986,68 @@
 public void selectAll () {
     checkWidget ();
     if ((style & DWT.SINGLE) !is 0) return;
-    NSTableView widget = cast(NSTableView)view;
+    NSOutlineView widget = cast(NSOutlineView) view;
     ignoreSelect = true;
-    widget.selectAll(null);
+    widget.selectAll (null);
     ignoreSelect = false;
 }
 
+/**
+ * Selects an item in the receiver.  If the item was already
+ * selected, it remains selected.
+ *
+ * @param item the item to be selected
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the item is null</li>
+ *    <li>ERROR_INVALID_ARGUMENT - if the item has been disposed</li>
+ * </ul>
+ * @exception DWTException <ul>
+ *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.4
+ */
 public void select (TreeItem item) {
     checkWidget ();
     if (item is null) error (DWT.ERROR_NULL_ARGUMENT);
     if (item.isDisposed ()) error (DWT.ERROR_INVALID_ARGUMENT);
-//  showItem (item, false);
-//  ignoreSelect = true;
-//  /*
-//  * Bug in the Macintosh.  When the DataBroswer selection flags includes
-//  * both kDataBrowserNeverEmptySelectionSet and kDataBrowserSelectOnlyOne,
-//    * two items are selected when SetDataBrowserSelectedItems() is called
-//    * with kDataBrowserItemsAssign to assign a new seletion despite the fact
-//  * that kDataBrowserSelectOnlyOne was specified.  The fix is to save and
-//  * restore kDataBrowserNeverEmptySelectionSet around each call to
-//  * SetDataBrowserSelectedItems().
-//  */
-//  int [] selectionFlags = null;
-//  if ((style & DWT.SINGLE) !is 0) {
-//      selectionFlags = new int [1];
-//      OS.GetDataBrowserSelectionFlags (handle, selectionFlags);
-//      OS.SetDataBrowserSelectionFlags (handle, selectionFlags [0] & ~OS.kDataBrowserNeverEmptySelectionSet);
-//  }
-//  OS.SetDataBrowserSelectedItems (handle, 1, new int [] {item.id}, OS.kDataBrowserItemsAssign);
-//  if ((style & DWT.SINGLE) !is 0) {
-//      OS.SetDataBrowserSelectionFlags (handle, selectionFlags [0]);
-//  }
-//  ignoreSelect = false;
+    showItem (item);
+    NSOutlineView outlineView = (NSOutlineView) view;
+    outlineView.selectRow (outlineView.rowForItem (item.handle), false);
 }
 
 void sendDoubleSelection() {
     postEvent (DWT.DefaultSelection);
 }
 
+bool sendKeyEvent (NSEvent nsEvent, int type) {
+    bool result = super.sendKeyEvent (nsEvent, type);
+    if (!result) return result;
+    if (type !is DWT.KeyDown) return result;
+    short keyCode = nsEvent.keyCode ();
+    switch (keyCode) {
+        case 76: /* KP Enter */
+        case 36: { /* Return */
+            postEvent (DWT.DefaultSelection);
+            break;
+        }
+    }
+    return result;
+}
+
+void setBackground (float [] color) {
+    super.setBackground (color);
+    NSColor nsColor;
+    if (color is null) {
+        nsColor = null;
+    } else {
+        nsColor = NSColor.colorWithDeviceRed (color [0], color [1], color [2], 1);
+    }
+    ((NSOutlineView) view).setBackgroundColor (nsColor);
+}
+
 /**
  * Sets the order that the items in the receiver should 
  * be displayed in to the given argument which is described
@@ -1688,35 +2091,23 @@
         if (order [i] !is oldOrder [i]) reorder = true;
     }
     if (reorder) {
-        int [] disclosure = new int [1];
-        bool [] expandableRows = new bool [1];
-//      OS.GetDataBrowserListViewDisclosureColumn (handle, disclosure, expandableRows);
-        TreeColumn firstColumn = columns [order [0]];
-//      if (disclosure [0] !is firstColumn.id) {
-//          OS.SetDataBrowserListViewDisclosureColumn (handle, firstColumn.id, expandableRows [0]);
-//      }
-        int x = 0;
-        short [] width = new short [1];
+        NSOutlineView outlineView = (NSOutlineView)view;
         int [] oldX = new int [oldOrder.length];
+        int check = (style & DWT.CHECK) !is 0 ? 1 : 0;
         for (int i=0; i<oldOrder.length; i++) {
-            int index = oldOrder [i];
-            TreeColumn column = columns [index];
-            oldX [index] =  x;
-//          OS.GetDataBrowserTableViewNamedColumnWidth(handle, column.id, width);
-            x += width [0];
+            int index = oldOrder[i];
+            oldX [index] = (int)outlineView.rectOfColumn (i + check).x;
         }
-        x = 0;
         int [] newX = new int [order.length];
         for (int i=0; i<order.length; i++) {
             int index = order [i];
-            TreeColumn column = columns [index];
-            int position = (style & DWT.CHECK) !is 0 ? i + 1 : i;
-//          OS.SetDataBrowserTableViewColumnPosition(handle, column.id, position);
-//          column.lastPosition = position;
-            newX [index] =  x;
-//          OS.GetDataBrowserTableViewNamedColumnWidth(handle, column.id, width);
-            x += width [0];
+            TreeColumn column = columns[index];
+            int oldIndex = outlineView.columnWithIdentifier (column.nsColumn);
+            int newIndex = i + check;
+            outlineView.moveColumn (oldIndex, newIndex);
+            newX [index] = (int)outlineView.rectOfColumn (newIndex).x;
         }
+
         TreeColumn[] newColumns = new TreeColumn [columnCount];
         System.arraycopy (columns, 0, newColumns, 0, columnCount);
         for (int i=0; i<columnCount; i++) {
@@ -1730,6 +2121,17 @@
     }
 }
 
+void setFont(NSFont font) {
+    super.setFont (font);
+    if (!hooks (DWT.MeasureItem)) {
+        float ascent = font.ascender ();
+        float descent = -font.descender () + font.leading ();
+        ((NSOutlineView)view).setRowHeight ((int)Math.ceil (ascent + descent) + 1);
+    } else {
+        view.setNeedsDisplay (true);
+    }
+}
+
 /**
  * Marks the receiver's header as visible if the argument is <code>true</code>,
  * and marks it invisible otherwise. 
@@ -1750,7 +2152,7 @@
  */
 public void setHeaderVisible (bool show) {
     checkWidget ();
-    (cast(NSTableView)view).setHeaderView (show ? headerView : null);
+    (cast(NSOutlineView) view).setHeaderView (show ? headerView : null);
 }
 
 /**
@@ -1772,91 +2174,39 @@
 }
 
 void setItemCount (TreeItem parentItem, int count) {
-//  int itemCount = getItemCount (parentItem);
-//  if (count is itemCount) return;
-//  setRedraw (false);
-//  int [] top = new int [1], left = new int [1];
-//    OS.GetDataBrowserScrollPosition (handle, top, left);
-//    DataBrowserCallbacks callbacks = new DataBrowserCallbacks ();
-//  OS.GetDataBrowserCallbacks (handle, callbacks);
-//  callbacks.v1_itemNotificationCallback = 0;
-//  callbacks.v1_itemCompareCallback = 0;
-//  OS.SetDataBrowserCallbacks (handle, callbacks);
-//  int[] ids = parentItem is null ? childIds : parentItem.childIds;
-//  if (count < itemCount) {
-//      for (int index = ids.length - 1; index >= count; index--) {
-//          int id = ids [index];
-//          if (id !is 0) {
-//              TreeItem item = _getItem (id, false);
-//              if (item !is null && !item.isDisposed ()) {
-//                  item.dispose ();
-//              } else {
-//                  if (parentItem is null || parentItem.getExpanded ()) {
-//                      if (OS.RemoveDataBrowserItems (handle, OS.kDataBrowserNoItem, 1, new int [] {id}, 0) !is OS.noErr) {
-//                          error (DWT.ERROR_ITEM_NOT_REMOVED);
-//                          break;
-//                      }
-//                      visibleCount--;
-//                  }
-//              }
-//          }
-//      }
-//      //TODO - move shrink to paint event
-//      // shrink items array
-//      int lastIndex = items.length;
-//      for (int i=items.length; i>0; i--) {
-//          if (items [i-1] !is null) {
-//              lastIndex = i;
-//              break;
-//          }
-//      }
-//      if (lastIndex < items.length - 4) {
-//          int length = Math.max (4, (lastIndex + 3) / 4 * 4);
-//          TreeItem [] newItems = new TreeItem [length];
-//          System.arraycopy(items, 0, newItems, 0, Math.min(items.length, lastIndex));
-//      }
-//  }
-//  
-//  if (parentItem !is null) parentItem.itemCount = count;
-//  int length = Math.max (4, (count + 3) / 4 * 4);
-//  int [] newIds = new int [length];
-//  if (ids !is null) {
-//      System.arraycopy (ids, 0, newIds, 0, Math.min (count, itemCount));
-//  }
-//  ids = newIds;
-//  if (parentItem is null) {
-//      childIds = newIds;
-//  } else {
-//      parentItem.childIds = newIds;
-//  }
-//  
-//  if (count > itemCount) {
-//      if ((getStyle() & DWT.VIRTUAL) is 0) {
-//          int delta = Math.max (4, (count - itemCount + 3) / 4 * 4);
-//          TreeItem [] newItems = new TreeItem [items.length + delta];
-//          System.arraycopy (items, 0, newItems, 0, items.length);
-//          items = newItems;
-//          for (int i=itemCount; i<count; i++) {
-//              items [i] = new TreeItem (this, parentItem, DWT.NONE, i, true);
-//          }
-//      } else {
-//          if (parentItem is null || parentItem.getExpanded ()) {
-//              int parentID = parentItem is null ? OS.kDataBrowserNoItem : parentItem.id;
-//              int [] addIds = _getIds (count - itemCount);
-//              if (OS.AddDataBrowserItems (handle, parentID, addIds.length, addIds, OS.kDataBrowserItemNoProperty) !is OS.noErr) {
-//                  error (DWT.ERROR_ITEM_NOT_ADDED);
-//              }
-//              visibleCount += (count - itemCount);
-//              System.arraycopy (addIds, 0, ids, itemCount, addIds.length);
-//          }
-//      }
-//  }
-//  
-//  callbacks.v1_itemNotificationCallback = display.itemNotificationProc;
-//  callbacks.v1_itemCompareCallback = display.itemCompareProc;
-//  OS.SetDataBrowserCallbacks (handle, callbacks);
-//  setRedraw (true);
-//  if (itemCount is 0 && parentItem !is null) parentItem.redraw (OS.kDataBrowserNoItem);
+    int itemCount = getItemCount (parentItem);
+    if (count is itemCount) return;
+    TreeItem [] children = parentItem is null ? items : parentItem.items;
+    if (count < itemCount) {
+        for (int index = count; index < itemCount; index ++) {
+            TreeItem item = children [index];
+            if (item !is null && !item.isDisposed()) item.release (false);
+        }
+    }
+    if (count > itemCount) {
+        if ((getStyle() & DWT.VIRTUAL) is 0) {
+            for (int i=itemCount; i<count; i++) {
+                new TreeItem (this, parentItem, DWT.NONE, i, true);
+            }
+            return;
+        } 
+    }
+    int length = Math.max (4, (count + 3) / 4 * 4);
+    TreeItem [] newItems = new TreeItem [length];
+    if (children !is null) {
+        System.arraycopy (children, 0, newItems, 0, Math.min (count, itemCount));
+    }
+    children = newItems;
+    if (parentItem is null) {
+        this.items = newItems;
+        this.itemCount = count;
+    } else {
+        parentItem.items = newItems;
+        parentItem.itemCount = count;
+    }
+    NSOutlineView widget = (NSOutlineView) view;
+    widget.reloadItem (parentItem !is null ? parentItem.handle : null, true);
+    widget.noteNumberOfRowsChanged();
 }
 
 /*public*/ void setItemHeight (int itemHeight) {
@@ -1901,57 +2251,56 @@
  */
 public void setLinesVisible (bool show) {
     checkWidget ();
-    (cast(NSTableView)view).setUsesAlternatingRowBackgroundColors(show);
+    (cast(NSOutlineView) view).setUsesAlternatingRowBackgroundColors (show);
 }
 
 public void setRedraw (bool redraw) {
-    checkWidget();
+    checkWidget ();
     super.setRedraw (redraw);
     if (redraw && drawCount is 0) {
-        setScrollWidth (true);
+        setScrollWidth ();
     }
 }
 
-bool setScrollWidth (TreeItem item) {
-//  if (ignoreRedraw || drawCount !is 0) return false;
-    if (columnCount !is 0) return false;
-//  TreeItem parentItem = item.parentItem;
-//  if (parentItem !is null && !parentItem._getExpanded ()) return false;
-//  GC gc = new GC (this);
-//  int newWidth = item.calculateWidth (0, gc);
-//  gc.dispose ();
-//  newWidth += getInsetWidth (column_id, false);
-//  short [] width = new short [1];
-//  OS.GetDataBrowserTableViewNamedColumnWidth (handle, column_id, width);
-//  if (width [0] < newWidth) {
-//      OS.SetDataBrowserTableViewNamedColumnWidth (handle, column_id, cast(short) newWidth);
-//      return true;
-//  }
-//  firstColumn.setWidth(400);
-    return false;
+bool setScrollWidth () {
+    return setScrollWidth (items, true, true);
+}
+
+bool setScrollWidth (TreeItem item, bool recurse, bool callMeasureItem) {
+    return setScrollWidth (new TreeItem[] {item}, recurse, callMeasureItem);
 }
 
-bool setScrollWidth (bool set) {
-//  return setScrollWidth(set, childIds, true);
+bool setScrollWidth (TreeItem[] items, bool recurse, bool callMeasureItem) {
+    if (columnCount !is 0) return false;
+//  if (currentItem !is null) {
+//      if (currentItem !is item) fixScrollWidth = true;
+//      return false;
+//  }
+    if (/*ignoreRedraw ||*/ drawCount !is 0) return false;
+    int newWidth = 0;
+    GC gc = new GC (this);
+    for (int i = 0; i < items.length; i++) {
+        TreeItem item = items[i];
+        if (item !is null && !item.isDisposed ()) {
+            newWidth = Math.max (newWidth, item.calculateWidth (0, gc, recurse, callMeasureItem));
+            if (isDisposed ()) {
+                gc.dispose ();
+                return false;
+            }
+        }
+    }
+    gc.dispose ();
+    if (firstColumn.width () < newWidth) {
+        NSOutlineView outlineView = (NSOutlineView)view;
+        int /*long*/ oldResize = outlineView.columnAutoresizingStyle ();
+        outlineView.setColumnAutoresizingStyle (OS.NSTableViewNoColumnAutoresizing);
+        firstColumn.setWidth (newWidth);
+        outlineView.setColumnAutoresizingStyle (oldResize);
+        return true;
+    }
     return false;
 }
 
-bool setScrollWidth (bool set, int[] childIds, bool recurse) {
-//  if (ignoreRedraw || drawCount !is 0) return false;
-//  if (columnCount !is 0 || childIds is null) return false;
-//  GC gc = new GC (this);
-//  int newWidth = calculateWidth (childIds, gc, recurse, 0, 0);
-//  gc.dispose ();
-//  newWidth += getInsetWidth (column_id, false);
-//  if (!set) {
-//      short [] width = new short [1];
-//      OS.GetDataBrowserTableViewNamedColumnWidth (handle, column_id, width);
-//      if (width [0] >= newWidth) return false;
-//  }
-//  OS.SetDataBrowserTableViewNamedColumnWidth (handle, column_id, cast(short) newWidth);
-    return true;
-}
-
 /**
  * Sets the receiver's selection to the given item.
  * The current selection is cleared before the new item is selected.
@@ -2004,48 +2353,23 @@
     checkWidget ();
     if (items is null) error (DWT.ERROR_NULL_ARGUMENT);
     deselectAll ();
-//  int length = items.length;
-//  if (length is 0 || ((style & DWT.SINGLE) !is 0 && length > 1)) return;
-//  int count = 0;
-//  int[] ids = new int [length];
-//  for (int i=0; i<length; i++) {
-//      if (items [i] !is null) {
-//          if (items [i].isDisposed ()) error (DWT.ERROR_INVALID_ARGUMENT);
-//          ids [count++] = items [i].id;
-//          showItem (items [i], false);
-//      }
-//  }
-//  ignoreSelect = true;
-//  /*
-//  * Bug in the Macintosh.  When the DataBroswer selection flags includes
-//  * both kDataBrowserNeverEmptySelectionSet and kDataBrowserSelectOnlyOne,
-//    * two items are selected when SetDataBrowserSelectedItems() is called
-//    * with kDataBrowserItemsAssign to assign a new seletion despite the fact
-//  * that kDataBrowserSelectOnlyOne was specified.  The fix is to save and
-//  * restore kDataBrowserNeverEmptySelectionSet around each call to
-//  * SetDataBrowserSelectedItems().
-//  */
-//  int [] selectionFlags = null;
-//  if ((style & DWT.SINGLE) !is 0) {
-//      selectionFlags = new int [1];
-//      OS.GetDataBrowserSelectionFlags (handle, selectionFlags);
-//      OS.SetDataBrowserSelectionFlags (handle, selectionFlags [0] & ~OS.kDataBrowserNeverEmptySelectionSet);
-//  }
-//  OS.SetDataBrowserSelectedItems (handle, count, ids, OS.kDataBrowserItemsAssign);
-//  if ((style & DWT.SINGLE) !is 0) {
-//      OS.SetDataBrowserSelectionFlags (handle, selectionFlags [0]);
-//  }
-//  ignoreSelect = false;
-//  if (length > 0) {
-//      int index = -1;
-//      for (int i=0; i<items.length; i++) {
-//          if (items [i] !is null) {
-//              index = i;
-//              break;
-//          }
-//      }
-//      if (index !is -1) showItem (items [index], true);
-//  }
+    int length = items.length;
+    if (length is 0 || ((style & DWT.SINGLE) !is 0 && length > 1)) return;
+    NSOutlineView outlineView = (NSOutlineView) view;
+    NSMutableIndexSet rows = (NSMutableIndexSet) new NSMutableIndexSet ().alloc ().init ();
+    rows.autorelease ();
+    for (int i=0; i<length; i++) {
+        if (items [i] !is null) {
+            if (items [i].isDisposed ()) error (DWT.ERROR_INVALID_ARGUMENT);
+            TreeItem item = items [i];
+            showItem (items [i], false);
+            rows.addIndex (outlineView.rowForItem (item.handle));
+        }
+    }
+    ignoreSelect = true;
+    outlineView.selectRowIndexes (rows, false);
+    ignoreSelect = false;
+    if (items.length > 0) showItem(items[0], true);
 }
 
 /**
@@ -2069,19 +2393,21 @@
     checkWidget ();
     if (column !is null && column.isDisposed ()) error (DWT.ERROR_INVALID_ARGUMENT);
     if (column is sortColumn) return;
-//  if (column is null) {
-//      if (sortColumn !is null  && !sortColumn.isDisposed ()  && sortDirection !is DWT.NONE) {
-//          OS.SetDataBrowserSortOrder (handle, cast(short) OS.kDataBrowserOrderIncreasing);
-//          sortColumn = null; 
-//          OS.SetDataBrowserSortProperty (handle, 0);
-//      }
-//  }
-//  sortColumn = column;
-//  if (sortColumn !is null  && !sortColumn.isDisposed () && sortDirection !is DWT.NONE) {
-//      OS.SetDataBrowserSortProperty (handle, sortColumn.id);
-//      int order = sortDirection is DWT.DOWN ? OS.kDataBrowserOrderDecreasing : OS.kDataBrowserOrderIncreasing;
-//      OS.SetDataBrowserSortOrder (handle, cast(short) order);
-//  }
+    TreeColumn oldSortColumn = sortColumn;
+    sortColumn = column;
+    if (sortDirection is DWT.NONE) return;
+    NSTableHeaderView headerView = ((NSOutlineView)view).headerView ();
+    if (headerView is null) return;
+    if (oldSortColumn !is null) {
+        int /*long*/ index = ((NSOutlineView)view).columnWithIdentifier (oldSortColumn.nsColumn);
+        NSRect rect = headerView.headerRectOfColumn (index);
+        headerView.setNeedsDisplayInRect (rect);
+    }
+    if (sortColumn !is null) {
+        NSInteger index = (cast(NSOutlineView)view).columnWithIdentifier (sortColumn.nsColumn);
+        NSRect rect = headerView.headerRectOfColumn (index);
+        headerView.setNeedsDisplayInRect (rect);
+    }
 }
 
 /**
@@ -2100,22 +2426,14 @@
 public void setSortDirection  (int direction) {
     checkWidget ();
     if (direction !is DWT.UP && direction !is DWT.DOWN && direction !is DWT.NONE) return;
-//  if (direction is sortDirection) return;
-//  sortDirection = direction;
-//  if (sortColumn !is null && !sortColumn.isDisposed ()) {
-//      if (sortDirection is DWT.NONE) {
-//          OS.SetDataBrowserSortOrder (handle, cast(short) OS.kDataBrowserOrderIncreasing);
-//          TreeColumn column = sortColumn;
-//          sortColumn = null; 
-//          OS.SetDataBrowserSortProperty (handle, 0);
-//          sortColumn = column;
-//      } else {
-//          OS.SetDataBrowserSortProperty (handle, 0);
-//          OS.SetDataBrowserSortProperty (handle, sortColumn.id);
-//          int order = sortDirection is DWT.DOWN ? OS.kDataBrowserOrderDecreasing : OS.kDataBrowserOrderIncreasing;
-//          OS.SetDataBrowserSortOrder (handle, cast(short) order);
-//      }
-//  }
+    if (direction is sortDirection) return;
+    sortDirection = direction;
+    if (sortColumn is null) return;
+    NSTableHeaderView headerView = ((NSOutlineView)view).headerView ();
+    if (headerView is null) return;
+    int /*long*/ index = ((NSOutlineView)view).columnWithIdentifier (sortColumn.nsColumn);
+    NSRect rect = headerView.headerRectOfColumn (index);
+    headerView.setNeedsDisplayInRect (rect);
 }
 
 /**
@@ -2142,16 +2460,10 @@
     checkWidget();
     if (item is null) error (DWT.ERROR_NULL_ARGUMENT);
     if (item.isDisposed ()) error (DWT.ERROR_INVALID_ARGUMENT);
-//  showItem (item, false);
-//  int columnId = (columnCount is 0) ? column_id : columns [0].id;
-//  OS.RevealDataBrowserItem (handle, item.id, columnId, cast(byte) OS.kDataBrowserRevealWithoutSelecting);
-//  Rect rect = new Rect ();
-//  if (OS.GetDataBrowserItemPartBounds (handle, item.id, column_id, OS.kDataBrowserPropertyEnclosingPart, rect) is OS.noErr) {
-//      int border = getBorder ();
-//      int [] top = new int [1], left = new int [1];
-//      OS.GetDataBrowserScrollPosition (handle, top, left);
-//      OS.SetDataBrowserScrollPosition (handle, Math.max (0, top [0] + rect.top - border - getHeaderHeight ()), left [0]);
-//  }
+    showItem (item, false);
+    NSOutlineView outlineView = (NSOutlineView) view;
+    //FIXME
+    ((NSOutlineView) view).scrollRowToVisible (outlineView.rowForItem (item.handle));
 }
 
 /**
@@ -2175,11 +2487,12 @@
 public void showColumn (TreeColumn column) {
     checkWidget ();
     if (column is null) error (DWT.ERROR_NULL_ARGUMENT);
-    if (column.isDisposed()) error(DWT.ERROR_INVALID_ARGUMENT);
+    if (column.isDisposed()) error (DWT.ERROR_INVALID_ARGUMENT);
     if (column.parent !is this) return;
-    int index = indexOf (column);
-    if (columnCount <= 1 || !(0 <= index && index < columnCount)) return;
-    (cast(NSTableView)view).scrollColumnToVisible(index + ((style & DWT.CHECK) !is 0 ? 1 : 0));
+    if (columnCount <= 1) return;
+    int index = (int)/*64*/((NSOutlineView)view).columnWithIdentifier (column.nsColumn);
+    if (!(0 <= index && index < columnCount + ((style & DWT.CHECK) !is 0 ? 1 : 0))) return;
+    ((NSOutlineView)view).scrollColumnToVisible (index);
 }
 
 /**
@@ -2208,99 +2521,15 @@
 }
 
 void showItem (TreeItem item, bool scroll) {
-    int count = 0;
-//  TreeItem parentItem = item.parentItem;
-//  while (parentItem !is null && !parentItem._getExpanded ()) {
-//      count++;
-//      parentItem = parentItem.parentItem;
-//  }
-//  int index = 0;
-//  parentItem = item.parentItem;
-//  TreeItem [] path = new TreeItem [count];
-//  while (parentItem !is null && !parentItem._getExpanded ()) {
-//      path [index++] = parentItem;
-//      parentItem = parentItem.parentItem;
-//  }
-//  for (int i=path.length-1; i>=0; --i) {
-//      path [i].setExpanded (true);
-//  }
-//  if (scroll) {
-//      /*
-//      * Bug in the Macintosh.  When there is not room to show a
-//      * single item in the data browser, RevealDataBrowserItem()
-//      * scrolls the item such that it is above the top of the data
-//      * browser.  The fix is to remember the index and scroll when
-//      * the data browser is resized.
-//      * 
-//      * Bug in the Macintosh.  When items are added to the data
-//      * browser after is has been hidden, RevealDataBrowserItem()
-//      * when called before the controls behind the data browser
-//      * are repainted causes a redraw.  This redraw happens right
-//      * away causing pixel corruption.  The fix is to remember the
-//      * index and scroll when the data browser is shown.
-//      */
-//      Rectangle rect = getClientArea ();
-//      if (rect.height < getItemHeight () || !OS.IsControlVisible (handle)) {
-//          showItem = item;
-//          return;
-//      }
-//      showItem = null;
-//      Rectangle itemRect = item.getBounds ();
-//      if (!itemRect.isEmpty()) {
-//          if (rect.contains (itemRect.x, itemRect.y)
-//              && rect.contains (itemRect.x, itemRect.y + itemRect.height)) return;
-//      }
-//      int [] top = new int [1], left = new int [1];
-//      OS.GetDataBrowserScrollPosition (handle, top, left);
-//      int columnId = (columnCount is 0) ? column_id : columns [0].id;
-//      int options = OS.kDataBrowserRevealWithoutSelecting;
-//      /*
-//      * This code is intentionally commented, since kDataBrowserRevealAndCenterInView
-//      * does not scroll the item to the center always (it seems to scroll to the
-//      * end in some cases).
-//      */
-//      //options |= OS.kDataBrowserRevealAndCenterInView;
-//      OS.RevealDataBrowserItem (handle, item.id, columnId, cast(byte) options);
-//      int [] newTop = new int [1], newLeft = new int [1];
-//      if (columnCount is 0) {
-//          bool fixScroll = false;
-//          Rect content = new Rect ();
-//          if (OS.GetDataBrowserItemPartBounds (handle, item.id, columnId, OS.kDataBrowserPropertyContentPart, content) is OS.noErr) {
-//              fixScroll = content.left < rect.x || content.left >= rect.x + rect.width;
-//              if (!fixScroll) {
-//                  GC gc = new GC (this);
-//                  int contentWidth = calculateWidth (new int[]{item.id}, gc, false, 0, 0);
-//                  gc.dispose ();
-//                  fixScroll =  content.left + contentWidth > rect.x + rect.width;
-//              }
-//          }
-//          if (fixScroll) {
-//              int leftScroll = getLeftDisclosureInset (columnId);
-//              int levelIndent = DISCLOSURE_COLUMN_LEVEL_INDENT;
-//              if (OS.VERSION >= 0x1040) {
-//                  float [] metric = new float [1];
-//                  OS.DataBrowserGetMetric (handle, OS.kDataBrowserMetricDisclosureColumnPerDepthGap, null, metric);
-//                  levelIndent = cast(int) metric [0];
-//              }
-//              TreeItem temp = item;
-//              while (temp.parentItem !is null) {
-//                  leftScroll += levelIndent;
-//                  temp = temp.parentItem;
-//              }
-//              OS.GetDataBrowserScrollPosition (handle, newTop, newLeft);
-//              OS.SetDataBrowserScrollPosition (handle, newTop [0], leftScroll);
-//          }
-//      }
-//
-//      /*
-//      * Bug in the Macintosh.  For some reason, when the DataBrowser is scrolled
-//      * by RevealDataBrowserItem(), the scrollbars are not redrawn.  The fix is to
-//      * force a redraw.
-//      */
-//      OS.GetDataBrowserScrollPosition (handle, newTop, newLeft);
-//      if (horizontalBar !is null && newLeft [0] !is left [0]) horizontalBar.redraw ();
-//      if (verticalBar !is null && newTop [0] !is top [0]) verticalBar.redraw ();
-//  }
+    TreeItem parentItem = item.parentItem;
+    if (parentItem !is null && !parentItem.expanded) {
+        showItem (parentItem, false);
+        parentItem.setExpanded (true);
+    }
+    if (scroll) {
+        NSOutlineView outlineView = (NSOutlineView) view;
+        outlineView.scrollRowToVisible (outlineView.rowForItem (item.handle));
+    }
 }
 
 /**
@@ -2324,3 +2553,4 @@
 }
 
 }
+