]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/treectlg.cpp
fixed wxXmlResource::Load's detection of filenames to be done as early as possible
[wxWidgets.git] / src / generic / treectlg.cpp
index 61e67c5ed77ed11eed30df3257f608a1843e170c..393231673c90d27c3ba5e556de050586668fd151 100644 (file)
@@ -42,7 +42,7 @@
 #include "wx/renderer.h"
 
 #ifdef __WXMAC__
 #include "wx/renderer.h"
 
 #ifdef __WXMAC__
-    #include "wx/mac/private.h"
+    #include "wx/osx/private.h"
 #endif
 
 // -----------------------------------------------------------------------------
 #endif
 
 // -----------------------------------------------------------------------------
@@ -51,7 +51,7 @@
 
 class WXDLLIMPEXP_FWD_CORE wxGenericTreeItem;
 
 
 class WXDLLIMPEXP_FWD_CORE wxGenericTreeItem;
 
-WX_DEFINE_EXPORTED_ARRAY_PTR(wxGenericTreeItem *, wxArrayGenericTreeItems);
+WX_DEFINE_ARRAY_PTR(wxGenericTreeItem *, wxArrayGenericTreeItems);
 
 // ----------------------------------------------------------------------------
 // constants
 
 // ----------------------------------------------------------------------------
 // constants
@@ -61,6 +61,9 @@ static const int NO_IMAGE = -1;
 
 static const int PIXELS_PER_UNIT = 10;
 
 
 static const int PIXELS_PER_UNIT = 10;
 
+// the margin between the item state image and the item normal image
+static const int MARGIN_BETWEEN_STATE_AND_IMAGE = 2;
+
 // the margin between the item image and the item text
 static const int MARGIN_BETWEEN_IMAGE_AND_TEXT = 4;
 
 // the margin between the item image and the item text
 static const int MARGIN_BETWEEN_IMAGE_AND_TEXT = 4;
 
@@ -83,7 +86,7 @@ public:
 private:
     wxGenericTreeCtrl *m_owner;
 
 private:
     wxGenericTreeCtrl *m_owner;
 
-    DECLARE_NO_COPY_CLASS(wxTreeRenameTimer)
+    wxDECLARE_NO_COPY_CLASS(wxTreeRenameTimer);
 };
 
 // control used for in-place edit
 };
 
 // control used for in-place edit
@@ -92,8 +95,8 @@ class WXDLLEXPORT wxTreeTextCtrl: public wxTextCtrl
 public:
     wxTreeTextCtrl(wxGenericTreeCtrl *owner, wxGenericTreeItem *item);
 
 public:
     wxTreeTextCtrl(wxGenericTreeCtrl *owner, wxGenericTreeItem *item);
 
-    void EndEdit(bool discardChanges = false);
-    
+    void EndEdit( bool discardChanges );
+
     const wxGenericTreeItem* item() const { return m_itemEdited; }
 
 protected:
     const wxGenericTreeItem* item() const { return m_itemEdited; }
 
 protected:
@@ -102,7 +105,7 @@ protected:
     void OnKillFocus( wxFocusEvent &event );
 
     bool AcceptChanges();
     void OnKillFocus( wxFocusEvent &event );
 
     bool AcceptChanges();
-    void Finish( bool setfocus = true );
+    void Finish( bool setfocus );
 
 private:
     wxGenericTreeCtrl  *m_owner;
 
 private:
     wxGenericTreeCtrl  *m_owner;
@@ -111,7 +114,7 @@ private:
     bool                m_aboutToFinish;
 
     DECLARE_EVENT_TABLE()
     bool                m_aboutToFinish;
 
     DECLARE_EVENT_TABLE()
-    DECLARE_NO_COPY_CLASS(wxTreeTextCtrl)
+    wxDECLARE_NO_COPY_CLASS(wxTreeTextCtrl);
 };
 
 // timer used to clear wxGenericTreeCtrl::m_findPrefix if no key was pressed
 };
 
 // timer used to clear wxGenericTreeCtrl::m_findPrefix if no key was pressed
@@ -129,7 +132,7 @@ public:
 private:
     wxGenericTreeCtrl *m_owner;
 
 private:
     wxGenericTreeCtrl *m_owner;
 
-    DECLARE_NO_COPY_CLASS(wxTreeFindTimer)
+    wxDECLARE_NO_COPY_CLASS(wxTreeFindTimer);
 };
 
 // a tree item
 };
 
 // a tree item
@@ -137,7 +140,13 @@ class WXDLLEXPORT wxGenericTreeItem
 {
 public:
     // ctors & dtor
 {
 public:
     // ctors & dtor
-    wxGenericTreeItem() { m_data = NULL; }
+    wxGenericTreeItem()
+    {
+        m_data = NULL;
+        m_widthText =
+        m_heightText = -1;
+    }
+
     wxGenericTreeItem( wxGenericTreeItem *parent,
                        const wxString& text,
                        int image,
     wxGenericTreeItem( wxGenericTreeItem *parent,
                        const wxString& text,
                        int image,
@@ -153,18 +162,36 @@ public:
     int GetImage(wxTreeItemIcon which = wxTreeItemIcon_Normal) const
         { return m_images[which]; }
     wxTreeItemData *GetData() const { return m_data; }
     int GetImage(wxTreeItemIcon which = wxTreeItemIcon_Normal) const
         { return m_images[which]; }
     wxTreeItemData *GetData() const { return m_data; }
+    int GetState() const { return m_state; }
 
     // returns the current image for the item (depending on its
     // selected/expanded/whatever state)
     int GetCurrentImage() const;
 
 
     // returns the current image for the item (depending on its
     // selected/expanded/whatever state)
     int GetCurrentImage() const;
 
-    void SetText( const wxString &text );
-    void SetImage(int image, wxTreeItemIcon which) { m_images[which] = image; }
+    void SetText(const wxString& text)
+    {
+        m_text = text;
+
+        ResetTextSize();
+    }
+
+    void SetImage(int image, wxTreeItemIcon which)
+    {
+        m_images[which] = image;
+        m_width = 0;
+    }
+
     void SetData(wxTreeItemData *data) { m_data = data; }
     void SetData(wxTreeItemData *data) { m_data = data; }
+    void SetState(int state) { m_state = state; m_width = 0; }
 
     void SetHasPlus(bool has = true) { m_hasPlus = has; }
 
 
     void SetHasPlus(bool has = true) { m_hasPlus = has; }
 
-    void SetBold(bool bold) { m_isBold = bold; }
+    void SetBold(bool bold)
+    {
+        m_isBold = bold;
+
+        ResetTextSize();
+    }
 
     int GetX() const { return m_x; }
     int GetY() const { return m_y; }
 
     int GetX() const { return m_x; }
     int GetY() const { return m_y; }
@@ -172,14 +199,43 @@ public:
     void SetX(int x) { m_x = x; }
     void SetY(int y) { m_y = y; }
 
     void SetX(int x) { m_x = x; }
     void SetY(int y) { m_y = y; }
 
-    int  GetHeight() const { return m_height; }
-    int  GetWidth()  const { return m_width; }
+    int GetHeight() const { return m_height; }
+    int GetWidth() const { return m_width; }
+
+    int GetTextHeight() const
+    {
+        wxASSERT_MSG( m_heightText != -1, "must call CalculateSize() first" );
 
 
-    void SetHeight(int h) { m_height = h; }
-    void SetWidth(int w) { m_width = w; }
+        return m_heightText;
+    }
+
+    int GetTextWidth() const
+    {
+        wxASSERT_MSG( m_widthText != -1, "must call CalculateSize() first" );
+
+        return m_widthText;
+    }
 
     wxGenericTreeItem *GetParent() const { return m_parent; }
 
 
     wxGenericTreeItem *GetParent() const { return m_parent; }
 
+    // sets the items font for the specified DC if it uses any special font or
+    // simply returns false otherwise
+    bool SetFont(wxGenericTreeCtrl *control, wxDC& dc) const
+    {
+        wxFont font;
+
+        wxTreeItemAttr * const attr = GetAttributes();
+        if ( attr && attr->HasFont() )
+            font = attr->GetFont();
+        else if ( IsBold() )
+            font = control->m_boldFont;
+        else
+            return false;
+
+        dc.SetFont(font);
+        return true;
+    }
+
     // operations
 
     // deletes all children notifying the treectrl about it
     // operations
 
     // deletes all children notifying the treectrl about it
@@ -189,10 +245,22 @@ public:
     size_t GetChildrenCount(bool recursively = true) const;
 
     void Insert(wxGenericTreeItem *child, size_t index)
     size_t GetChildrenCount(bool recursively = true) const;
 
     void Insert(wxGenericTreeItem *child, size_t index)
-    { m_children.Insert(child, index); }
+        { m_children.Insert(child, index); }
+
+    // calculate and cache the item size using either the provided DC (which is
+    // supposed to have wxGenericTreeCtrl::m_normalFont selected into it!) or a
+    // wxClientDC on the control window
+    void CalculateSize(wxGenericTreeCtrl *control, wxDC& dc)
+        { DoCalculateSize(control, dc, true /* dc uses normal font */); }
+    void CalculateSize(wxGenericTreeCtrl *control);
 
     void GetSize( int &x, int &y, const wxGenericTreeCtrl* );
 
 
     void GetSize( int &x, int &y, const wxGenericTreeCtrl* );
 
+    void ResetSize() { m_width = 0; }
+    void ResetTextSize() { m_width = 0; m_widthText = -1; }
+    void RecursiveResetSize();
+    void RecursiveResetTextSize();
+
         // return the item at given position (or NULL if no item), onButton is
         // true if the point belongs to the item's button, otherwise it lies
         // on the item's label
         // return the item at given position (or NULL if no item), onButton is
         // true if the point belongs to the item's button, otherwise it lies
         // on the item's label
@@ -232,22 +300,39 @@ public:
         if ( m_ownsAttr ) delete m_attr;
         m_attr = attr;
         m_ownsAttr = false;
         if ( m_ownsAttr ) delete m_attr;
         m_attr = attr;
         m_ownsAttr = false;
+        m_width = 0;
+        m_widthText = -1;
     }
         // set them and delete when done
     void AssignAttributes(wxTreeItemAttr *attr)
     {
         SetAttributes(attr);
         m_ownsAttr = true;
     }
         // set them and delete when done
     void AssignAttributes(wxTreeItemAttr *attr)
     {
         SetAttributes(attr);
         m_ownsAttr = true;
+        m_width = 0;
+        m_widthText = -1;
     }
 
 private:
     }
 
 private:
+    // calculate the size of this item, i.e. set m_width, m_height and
+    // m_widthText and m_heightText properly
+    //
+    // if dcUsesNormalFont is true, the current dc font must be the normal tree
+    // control font
+    void DoCalculateSize(wxGenericTreeCtrl *control,
+                         wxDC& dc,
+                         bool dcUsesNormalFont);
+
     // since there can be very many of these, we save size by chosing
     // the smallest representation for the elements and by ordering
     // the members to avoid padding.
     wxString            m_text;         // label to be rendered for item
     // since there can be very many of these, we save size by chosing
     // the smallest representation for the elements and by ordering
     // the members to avoid padding.
     wxString            m_text;         // label to be rendered for item
+    int                 m_widthText;
+    int                 m_heightText;
 
     wxTreeItemData     *m_data;         // user-provided data
 
 
     wxTreeItemData     *m_data;         // user-provided data
 
+    int                 m_state;        // item state
+
     wxArrayGenericTreeItems m_children; // list of children
     wxGenericTreeItem  *m_parent;       // parent of this item
 
     wxArrayGenericTreeItems m_children; // list of children
     wxGenericTreeItem  *m_parent;       // parent of this item
 
@@ -270,7 +355,7 @@ private:
     unsigned int        m_isBold      :1; // render the label in bold font
     unsigned int        m_ownsAttr    :1; // delete attribute when done
 
     unsigned int        m_isBold      :1; // render the label in bold font
     unsigned int        m_ownsAttr    :1; // delete attribute when done
 
-    DECLARE_NO_COPY_CLASS(wxGenericTreeItem)
+    wxDECLARE_NO_COPY_CLASS(wxGenericTreeItem);
 };
 
 // =============================================================================
 };
 
 // =============================================================================
@@ -296,7 +381,8 @@ static void EventFlagsToSelType(long style,
 }
 
 // check if the given item is under another one
 }
 
 // check if the given item is under another one
-static bool IsDescendantOf(const wxGenericTreeItem *parent, const wxGenericTreeItem *item)
+static bool
+IsDescendantOf(const wxGenericTreeItem *parent, const wxGenericTreeItem *item)
 {
     while ( item )
     {
 {
     while ( item )
     {
@@ -343,56 +429,43 @@ wxTreeTextCtrl::wxTreeTextCtrl(wxGenericTreeCtrl *owner,
     m_owner = owner;
     m_aboutToFinish = false;
 
     m_owner = owner;
     m_aboutToFinish = false;
 
-    int w = m_itemEdited->GetWidth(),
-        h = m_itemEdited->GetHeight();
-
-    int x, y;
-    m_owner->CalcScrolledPosition(item->GetX(), item->GetY(), &x, &y);
-
-    int image_h = 0,
-        image_w = 0;
-
-    int image = item->GetCurrentImage();
-    if ( image != NO_IMAGE )
-    {
-        if ( m_owner->m_imageListNormal )
-        {
-            m_owner->m_imageListNormal->GetSize( image, image_w, image_h );
-            image_w += MARGIN_BETWEEN_IMAGE_AND_TEXT;
-        }
-        else
-        {
-            wxFAIL_MSG(_T("you must create an image list to use images!"));
-        }
-    }
+    wxRect rect;
+    m_owner->GetBoundingRect(m_itemEdited, rect, true);
 
 
-    // FIXME: what are all these hardcoded 4, 8 and 11s really?
-    x += image_w;
-    w -= image_w + 4;
-#ifdef __WXMAC__
-    wxSize bs = DoGetBestSize() ;
-    // edit control height
-    if ( h > bs.y - 8 )
-    {
-        int diff = h - ( bs.y - 8 ) ;
-        h -= diff ;
-        y += diff / 2 ;
-    }
-#endif
+    // corrects position and size for better appearance
+#ifdef __WXMSW__
+    rect.x -= 5;
+    rect.width += 10;
+#elif defined(__WXGTK__)
+    rect.x -= 5;
+    rect.y -= 2;
+    rect.width  += 8;
+    rect.height += 4;
+#elif defined(__WXMAC__)
+    int bestHeight = GetBestSize().y - 8;
+    if ( rect.height > bestHeight )
+    {
+        int diff = rect.height - bestHeight;
+        rect.height -= diff;
+        rect.y += diff / 2;
+    }
+#endif // platforms
 
     (void)Create(m_owner, wxID_ANY, m_startValue,
 
     (void)Create(m_owner, wxID_ANY, m_startValue,
-                 wxPoint(x - 4, y - 4), wxSize(w + 11, h + 8));
+                 rect.GetPosition(), rect.GetSize());
+
+    SetSelection(-1, -1);
 }
 
 void wxTreeTextCtrl::EndEdit(bool discardChanges)
 {
     m_aboutToFinish = true;
 }
 
 void wxTreeTextCtrl::EndEdit(bool discardChanges)
 {
     m_aboutToFinish = true;
-    
+
     if ( discardChanges )
     {
         m_owner->OnRenameCancelled(m_itemEdited);
     if ( discardChanges )
     {
         m_owner->OnRenameCancelled(m_itemEdited);
-           
-        Finish();
+
+        Finish( true );
     }
     else
     {
     }
     else
     {
@@ -400,7 +473,7 @@ void wxTreeTextCtrl::EndEdit(bool discardChanges)
         AcceptChanges();
 
         // Even if vetoed, close the control (consistent with MSW)
         AcceptChanges();
 
         // Even if vetoed, close the control (consistent with MSW)
-        Finish();
+        Finish( true );
     }
 }
 
     }
 }
 
@@ -485,7 +558,7 @@ void wxTreeTextCtrl::OnKillFocus( wxFocusEvent &event )
     {
         if ( !AcceptChanges() )
             m_owner->OnRenameCancelled( m_itemEdited );
     {
         if ( !AcceptChanges() )
             m_owner->OnRenameCancelled( m_itemEdited );
-            
+
         Finish( false );
     }
 
         Finish( false );
     }
 
@@ -509,6 +582,7 @@ wxGenericTreeItem::wxGenericTreeItem(wxGenericTreeItem *parent,
     m_images[wxTreeItemIcon_SelectedExpanded] = NO_IMAGE;
 
     m_data = data;
     m_images[wxTreeItemIcon_SelectedExpanded] = NO_IMAGE;
 
     m_data = data;
+    m_state = wxTREE_ITEMSTATE_NONE;
     m_x = m_y = 0;
 
     m_isCollapsed = true;
     m_x = m_y = 0;
 
     m_isCollapsed = true;
@@ -518,12 +592,15 @@ wxGenericTreeItem::wxGenericTreeItem(wxGenericTreeItem *parent,
 
     m_parent = parent;
 
 
     m_parent = parent;
 
-    m_attr = (wxTreeItemAttr *)NULL;
+    m_attr = NULL;
     m_ownsAttr = false;
 
     // We don't know the height here yet.
     m_width = 0;
     m_height = 0;
     m_ownsAttr = false;
 
     // We don't know the height here yet.
     m_width = 0;
     m_height = 0;
+
+    m_widthText = -1;
+    m_heightText = -1;
 }
 
 wxGenericTreeItem::~wxGenericTreeItem()
 }
 
 wxGenericTreeItem::~wxGenericTreeItem()
@@ -533,7 +610,7 @@ wxGenericTreeItem::~wxGenericTreeItem()
     if (m_ownsAttr) delete m_attr;
 
     wxASSERT_MSG( m_children.IsEmpty(),
     if (m_ownsAttr) delete m_attr;
 
     wxASSERT_MSG( m_children.IsEmpty(),
-                  wxT("please call DeleteChildren() before deleting the item") );
+                  "must call DeleteChildren() before deleting the item" );
 }
 
 void wxGenericTreeItem::DeleteChildren(wxGenericTreeCtrl *tree)
 }
 
 void wxGenericTreeItem::DeleteChildren(wxGenericTreeCtrl *tree)
@@ -553,11 +630,6 @@ void wxGenericTreeItem::DeleteChildren(wxGenericTreeCtrl *tree)
     m_children.Empty();
 }
 
     m_children.Empty();
 }
 
-void wxGenericTreeItem::SetText( const wxString &text )
-{
-    m_text = text;
-}
-
 size_t wxGenericTreeItem::GetChildrenCount(bool recursively) const
 {
     size_t count = m_children.GetCount();
 size_t wxGenericTreeItem::GetChildrenCount(bool recursively) const
 {
     size_t count = m_children.GetCount();
@@ -634,10 +706,29 @@ wxGenericTreeItem *wxGenericTreeItem::HitTest(const wxPoint& point,
 
                 // assuming every image (normal and selected) has the same size!
                 if ( (GetImage() != NO_IMAGE) && theCtrl->m_imageListNormal )
 
                 // assuming every image (normal and selected) has the same size!
                 if ( (GetImage() != NO_IMAGE) && theCtrl->m_imageListNormal )
+                {
                     theCtrl->m_imageListNormal->GetSize(GetImage(),
                                                         image_w, image_h);
                     theCtrl->m_imageListNormal->GetSize(GetImage(),
                                                         image_w, image_h);
+                }
 
 
-                if ((image_w != -1) && (point.x <= m_x + image_w + 1))
+                int state_w = -1;
+                int state_h;
+
+                if ( (GetState() != wxTREE_ITEMSTATE_NONE) &&
+                        theCtrl->m_imageListState )
+                {
+                    theCtrl->m_imageListState->GetSize(GetState(),
+                                                       state_w, state_h);
+                }
+
+                if ((state_w != -1) && (point.x <= m_x + state_w + 1))
+                    flags |= wxTREE_HITTEST_ONITEMSTATEICON;
+                else if ((image_w != -1) &&
+                         (point.x <= m_x +
+                            (state_w != -1 ? state_w +
+                                                MARGIN_BETWEEN_STATE_AND_IMAGE
+                                           : 0)
+                                            + image_w + 1))
                     flags |= wxTREE_HITTEST_ONITEMICON;
                 else
                     flags |= wxTREE_HITTEST_ONITEMLABEL;
                     flags |= wxTREE_HITTEST_ONITEMICON;
                 else
                     flags |= wxTREE_HITTEST_ONITEMLABEL;
@@ -654,7 +745,7 @@ wxGenericTreeItem *wxGenericTreeItem::HitTest(const wxPoint& point,
         }
 
         // if children are expanded, fall through to evaluate them
         }
 
         // if children are expanded, fall through to evaluate them
-        if (m_isCollapsed) return (wxGenericTreeItem*) NULL;
+        if (m_isCollapsed) return NULL;
     }
 
     // evaluate children
     }
 
     // evaluate children
@@ -669,7 +760,7 @@ wxGenericTreeItem *wxGenericTreeItem::HitTest(const wxPoint& point,
             return res;
     }
 
             return res;
     }
 
-    return (wxGenericTreeItem*) NULL;
+    return NULL;
 }
 
 int wxGenericTreeItem::GetCurrentImage() const
 }
 
 int wxGenericTreeItem::GetCurrentImage() const
@@ -702,6 +793,105 @@ int wxGenericTreeItem::GetCurrentImage() const
     return image;
 }
 
     return image;
 }
 
+void wxGenericTreeItem::CalculateSize(wxGenericTreeCtrl* control)
+{
+    // check if we need to do anything before creating the DC
+    if ( m_width != 0 )
+        return;
+
+    wxClientDC dc(control);
+    DoCalculateSize(control, dc, false /* normal font not used */);
+}
+
+void
+wxGenericTreeItem::DoCalculateSize(wxGenericTreeCtrl* control,
+                                   wxDC& dc,
+                                   bool dcUsesNormalFont)
+{
+    if ( m_width != 0 ) // Size known, nothing to do
+        return;
+
+    if ( m_widthText == -1 )
+    {
+        bool fontChanged;
+        if ( SetFont(control, dc) )
+        {
+            fontChanged = true;
+        }
+        else // we have no special font
+        {
+           if ( !dcUsesNormalFont )
+           {
+               // but we do need to ensure that the normal font is used: notice
+               // that this doesn't count as changing the font as we don't need
+               // to restore it
+               dc.SetFont(control->m_normalFont);
+           }
+
+           fontChanged = false;
+        }
+
+        dc.GetTextExtent( GetText(), &m_widthText, &m_heightText );
+
+        // restore normal font if the DC used it previously and we changed it
+        if ( fontChanged )
+             dc.SetFont(control->m_normalFont);
+    }
+
+    int text_h = m_heightText + 2;
+
+    int image_h = 0, image_w = 0;
+    int image = GetCurrentImage();
+    if ( image != NO_IMAGE && control->m_imageListNormal )
+    {
+        control->m_imageListNormal->GetSize(image, image_w, image_h);
+        image_w += MARGIN_BETWEEN_IMAGE_AND_TEXT;
+    }
+
+    int state_h = 0, state_w = 0;
+    int state = GetState();
+    if ( state != wxTREE_ITEMSTATE_NONE && control->m_imageListState )
+    {
+        control->m_imageListState->GetSize(state, state_w, state_h);
+        if ( image_w != 0 )
+            state_w += MARGIN_BETWEEN_STATE_AND_IMAGE;
+        else
+            state_w += MARGIN_BETWEEN_IMAGE_AND_TEXT;
+    }
+
+    int img_h = wxMax(state_h, image_h);
+    m_height = wxMax(img_h, text_h);
+
+    if (m_height < 30)
+        m_height += 2;            // at least 2 pixels
+    else
+        m_height += m_height / 10;   // otherwise 10% extra spacing
+
+    if (m_height > control->m_lineHeight)
+        control->m_lineHeight = m_height;
+
+    m_width = state_w + image_w + m_widthText + 2;
+}
+
+void wxGenericTreeItem::RecursiveResetSize()
+{
+    m_width = 0;
+
+    const size_t count = m_children.Count();
+    for (size_t i = 0; i < count; i++ )
+        m_children[i]->RecursiveResetSize();
+}
+
+void wxGenericTreeItem::RecursiveResetTextSize()
+{
+    m_width = 0;
+    m_widthText = -1;
+
+    const size_t count = m_children.Count();
+    for (size_t i = 0; i < count; i++ )
+        m_children[i]->RecursiveResetTextSize();
+}
+
 // -----------------------------------------------------------------------------
 // wxGenericTreeCtrl implementation
 // -----------------------------------------------------------------------------
 // -----------------------------------------------------------------------------
 // wxGenericTreeCtrl implementation
 // -----------------------------------------------------------------------------
@@ -736,7 +926,7 @@ void wxGenericTreeCtrl::Init()
     m_current =
     m_key_current =
     m_anchor =
     m_current =
     m_key_current =
     m_anchor =
-    m_select_me = (wxGenericTreeItem *) NULL;
+    m_select_me = NULL;
     m_hasFocus = false;
     m_dirty = false;
 
     m_hasFocus = false;
     m_dirty = false;
 
@@ -750,7 +940,7 @@ void wxGenericTreeCtrl::Init()
                             (
                                 wxSYS_COLOUR_HIGHLIGHT
                             ),
                             (
                                 wxSYS_COLOUR_HIGHLIGHT
                             ),
-                            wxSOLID
+                            wxBRUSHSTYLE_SOLID
                          );
 
     m_hilightUnfocusedBrush = new wxBrush
                          );
 
     m_hilightUnfocusedBrush = new wxBrush
@@ -759,7 +949,7 @@ void wxGenericTreeCtrl::Init()
                                  (
                                      wxSYS_COLOUR_BTNSHADOW
                                  ),
                                  (
                                      wxSYS_COLOUR_BTNSHADOW
                                  ),
-                                 wxSOLID
+                                 wxBRUSHSTYLE_SOLID
                               );
 
     m_imageListButtons = NULL;
                               );
 
     m_imageListButtons = NULL;
@@ -777,10 +967,17 @@ void wxGenericTreeCtrl::Init()
 
     m_dropEffectAboveItem = false;
 
 
     m_dropEffectAboveItem = false;
 
+    m_dndEffect = NoEffect;
+    m_dndEffectItem = NULL;
+
     m_lastOnSame = false;
 
     m_lastOnSame = false;
 
-#ifdef __WXMAC__
+#if defined( __WXMAC__ )
+#if wxOSX_USE_ATSU_TEXT
     m_normalFont.MacCreateFromThemeFont( kThemeViewsFont ) ;
     m_normalFont.MacCreateFromThemeFont( kThemeViewsFont ) ;
+#else
+    m_normalFont.MacCreateFromUIFont( kCTFontViewsFontType ) ;
+#endif
 #else
     m_normalFont = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
 #endif
 #else
     m_normalFont = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
 #endif
@@ -802,21 +999,12 @@ bool wxGenericTreeCtrl::Create(wxWindow *parent,
                                const wxString& name )
 {
 #ifdef __WXMAC__
                                const wxString& name )
 {
 #ifdef __WXMAC__
-    int major,minor;
-    wxGetOsVersion( &major, &minor );
+    int major, minor;
+    wxGetOsVersion(&major, &minor);
 
 
-    style &= ~wxTR_LINES_AT_ROOT;
-    style |= wxTR_NO_LINES;
     if (major < 10)
         style |= wxTR_ROW_LINES;
     if (major < 10)
         style |= wxTR_ROW_LINES;
-        
-    if (style == 0 || style & wxTR_DEFAULT_STYLE)
-        style |= wxTR_FULL_ROW_HIGHLIGHT;
-        
 #endif // __WXMAC__
 #endif // __WXMAC__
-#ifdef __WXGTK20__
-    style |= wxTR_NO_LINES;
-#endif
 
     if ( !wxControl::Create( parent, id, pos, size,
                              style|wxHSCROLL|wxVSCROLL,
 
     if ( !wxControl::Create( parent, id, pos, size,
                              style|wxHSCROLL|wxVSCROLL,
@@ -843,7 +1031,7 @@ bool wxGenericTreeCtrl::Create(wxWindow *parent,
     // style because we apparently get performance problems when using dotted
     // pen for drawing in some ports -- but under MSW it seems to work fine
 #ifdef __WXMSW__
     // style because we apparently get performance problems when using dotted
     // pen for drawing in some ports -- but under MSW it seems to work fine
 #ifdef __WXMSW__
-    m_dottedPen = wxPen(*wxLIGHT_GREY, 0, wxDOT);
+    m_dottedPen = wxPen(*wxLIGHT_GREY, 0, wxPENSTYLE_DOT);
 #else
     m_dottedPen = *wxGREY_PEN;
 #endif
 #else
     m_dottedPen = *wxGREY_PEN;
 #endif
@@ -948,6 +1136,14 @@ wxTreeItemData *wxGenericTreeCtrl::GetItemData(const wxTreeItemId& item) const
     return ((wxGenericTreeItem*) item.m_pItem)->GetData();
 }
 
     return ((wxGenericTreeItem*) item.m_pItem)->GetData();
 }
 
+int wxGenericTreeCtrl::DoGetItemState(const wxTreeItemId& item) const
+{
+    wxCHECK_MSG( item.IsOk(), wxTREE_ITEMSTATE_NONE, wxT("invalid tree item") );
+
+    wxGenericTreeItem *pItem = (wxGenericTreeItem*) item.m_pItem;
+    return pItem->GetState();
+}
+
 wxColour wxGenericTreeCtrl::GetItemTextColour(const wxTreeItemId& item) const
 {
     wxCHECK_MSG( item.IsOk(), wxNullColour, wxT("invalid tree item") );
 wxColour wxGenericTreeCtrl::GetItemTextColour(const wxTreeItemId& item) const
 {
     wxCHECK_MSG( item.IsOk(), wxNullColour, wxT("invalid tree item") );
@@ -956,7 +1152,8 @@ wxColour wxGenericTreeCtrl::GetItemTextColour(const wxTreeItemId& item) const
     return pItem->Attr().GetTextColour();
 }
 
     return pItem->Attr().GetTextColour();
 }
 
-wxColour wxGenericTreeCtrl::GetItemBackgroundColour(const wxTreeItemId& item) const
+wxColour
+wxGenericTreeCtrl::GetItemBackgroundColour(const wxTreeItemId& item) const
 {
     wxCHECK_MSG( item.IsOk(), wxNullColour, wxT("invalid tree item") );
 
 {
     wxCHECK_MSG( item.IsOk(), wxNullColour, wxT("invalid tree item") );
 
@@ -972,14 +1169,14 @@ wxFont wxGenericTreeCtrl::GetItemFont(const wxTreeItemId& item) const
     return pItem->Attr().GetFont();
 }
 
     return pItem->Attr().GetFont();
 }
 
-void wxGenericTreeCtrl::SetItemText(const wxTreeItemId& item, const wxString& text)
+void
+wxGenericTreeCtrl::SetItemText(const wxTreeItemId& item, const wxString& text)
 {
     wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
 
 {
     wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
 
-    wxClientDC dc(this);
     wxGenericTreeItem *pItem = (wxGenericTreeItem*) item.m_pItem;
     pItem->SetText(text);
     wxGenericTreeItem *pItem = (wxGenericTreeItem*) item.m_pItem;
     pItem->SetText(text);
-    CalculateSize(pItem, dc);
+    pItem->CalculateSize(this);
     RefreshLine(pItem);
 }
 
     RefreshLine(pItem);
 }
 
@@ -991,13 +1188,12 @@ void wxGenericTreeCtrl::SetItemImage(const wxTreeItemId& item,
 
     wxGenericTreeItem *pItem = (wxGenericTreeItem*) item.m_pItem;
     pItem->SetImage(image, which);
 
     wxGenericTreeItem *pItem = (wxGenericTreeItem*) item.m_pItem;
     pItem->SetImage(image, which);
-
-    wxClientDC dc(this);
-    CalculateSize(pItem, dc);
+    pItem->CalculateSize(this);
     RefreshLine(pItem);
 }
 
     RefreshLine(pItem);
 }
 
-void wxGenericTreeCtrl::SetItemData(const wxTreeItemId& item, wxTreeItemData *data)
+void
+wxGenericTreeCtrl::SetItemData(const wxTreeItemId& item, wxTreeItemData *data)
 {
     wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
 
 {
     wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
 
@@ -1007,6 +1203,16 @@ void wxGenericTreeCtrl::SetItemData(const wxTreeItemId& item, wxTreeItemData *da
     ((wxGenericTreeItem*) item.m_pItem)->SetData(data);
 }
 
     ((wxGenericTreeItem*) item.m_pItem)->SetData(data);
 }
 
+void wxGenericTreeCtrl::DoSetItemState(const wxTreeItemId& item, int state)
+{
+    wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
+
+    wxGenericTreeItem *pItem = (wxGenericTreeItem*) item.m_pItem;
+    pItem->SetState(state);
+    pItem->CalculateSize(this);
+    RefreshLine(pItem);
+}
+
 void wxGenericTreeCtrl::SetItemHasChildren(const wxTreeItemId& item, bool has)
 {
     wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
 void wxGenericTreeCtrl::SetItemHasChildren(const wxTreeItemId& item, bool has)
 {
     wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
@@ -1028,9 +1234,7 @@ void wxGenericTreeCtrl::SetItemBold(const wxTreeItemId& item, bool bold)
 
         // recalculate the item size as bold and non bold fonts have different
         // widths
 
         // recalculate the item size as bold and non bold fonts have different
         // widths
-        wxClientDC dc(this);
-        CalculateSize(pItem, dc);
-
+        pItem->CalculateSize(this);
         RefreshLine(pItem);
     }
 }
         RefreshLine(pItem);
     }
 }
@@ -1074,12 +1278,15 @@ void wxGenericTreeCtrl::SetItemBackgroundColour(const wxTreeItemId& item,
     RefreshLine(pItem);
 }
 
     RefreshLine(pItem);
 }
 
-void wxGenericTreeCtrl::SetItemFont(const wxTreeItemId& item, const wxFont& font)
+void
+wxGenericTreeCtrl::SetItemFont(const wxTreeItemId& item, const wxFont& font)
 {
     wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
 
     wxGenericTreeItem *pItem = (wxGenericTreeItem*) item.m_pItem;
     pItem->Attr().SetFont(font);
 {
     wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
 
     wxGenericTreeItem *pItem = (wxGenericTreeItem*) item.m_pItem;
     pItem->Attr().SetFont(font);
+    pItem->ResetTextSize();
+    pItem->CalculateSize(this);
     RefreshLine(pItem);
 }
 
     RefreshLine(pItem);
 }
 
@@ -1096,6 +1303,9 @@ bool wxGenericTreeCtrl::SetFont( const wxFont &font )
                         m_normalFont.GetFaceName(),
                         m_normalFont.GetEncoding());
 
                         m_normalFont.GetFaceName(),
                         m_normalFont.GetEncoding());
 
+    if (m_anchor)
+        m_anchor->RecursiveResetTextSize();
+
     return true;
 }
 
     return true;
 }
 
@@ -1194,7 +1404,8 @@ wxTreeItemId wxGenericTreeCtrl::GetNextChild(const wxTreeItemId& item,
 {
     wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
 
 {
     wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
 
-    wxArrayGenericTreeItems& children = ((wxGenericTreeItem*) item.m_pItem)->GetChildren();
+    wxArrayGenericTreeItems&
+        children = ((wxGenericTreeItem*) item.m_pItem)->GetChildren();
 
     // it's ok to cast cookie to size_t, we never have indices big enough to
     // overflow "void *"
 
     // it's ok to cast cookie to size_t, we never have indices big enough to
     // overflow "void *"
@@ -1214,8 +1425,9 @@ wxTreeItemId wxGenericTreeCtrl::GetLastChild(const wxTreeItemId& item) const
 {
     wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
 
 {
     wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
 
-    wxArrayGenericTreeItems& children = ((wxGenericTreeItem*) item.m_pItem)->GetChildren();
-    return (children.IsEmpty() ? wxTreeItemId() : wxTreeItemId(children.Last()));
+    wxArrayGenericTreeItems&
+        children = ((wxGenericTreeItem*) item.m_pItem)->GetChildren();
+    return children.IsEmpty() ? wxTreeItemId() : wxTreeItemId(children.Last());
 }
 
 wxTreeItemId wxGenericTreeCtrl::GetNextSibling(const wxTreeItemId& item) const
 }
 
 wxTreeItemId wxGenericTreeCtrl::GetNextSibling(const wxTreeItemId& item) const
@@ -1235,7 +1447,8 @@ wxTreeItemId wxGenericTreeCtrl::GetNextSibling(const wxTreeItemId& item) const
     wxASSERT( index != wxNOT_FOUND ); // I'm not a child of my parent?
 
     size_t n = (size_t)(index + 1);
     wxASSERT( index != wxNOT_FOUND ); // I'm not a child of my parent?
 
     size_t n = (size_t)(index + 1);
-    return n == siblings.GetCount() ? wxTreeItemId() : wxTreeItemId(siblings[n]);
+    return n == siblings.GetCount() ? wxTreeItemId()
+                                    : wxTreeItemId(siblings[n]);
 }
 
 wxTreeItemId wxGenericTreeCtrl::GetPrevSibling(const wxTreeItemId& item) const
 }
 
 wxTreeItemId wxGenericTreeCtrl::GetPrevSibling(const wxTreeItemId& item) const
@@ -1397,7 +1610,8 @@ wxTreeItemId wxGenericTreeCtrl::FindItem(const wxTreeItemId& idParent,
         }
 
         // and try all the items (stop when we get to the one we started from)
         }
 
         // and try all the items (stop when we get to the one we started from)
-        while (id.IsOk() && id != idParent && !GetItemText(id).Lower().StartsWith(prefix) )
+        while ( id.IsOk() && id != idParent &&
+                    !GetItemText(id).Lower().StartsWith(prefix) )
         {
             id = GetNext(id);
         }
         {
             id = GetNext(id);
         }
@@ -1448,11 +1662,11 @@ wxTreeItemId wxGenericTreeCtrl::AddRoot(const wxString& text,
                                         int selImage,
                                         wxTreeItemData *data)
 {
                                         int selImage,
                                         wxTreeItemData *data)
 {
-    wxCHECK_MSG( !m_anchor, wxTreeItemId(), wxT("tree can have only one root") );
+    wxCHECK_MSG( !m_anchor, wxTreeItemId(), "tree can have only one root" );
 
     m_dirty = true;     // do this first so stuff below doesn't cause flicker
 
 
     m_dirty = true;     // do this first so stuff below doesn't cause flicker
 
-    m_anchor = new wxGenericTreeItem((wxGenericTreeItem *)NULL, text,
+    m_anchor = new wxGenericTreeItem(NULL, text,
                                    image, selImage, data);
     if ( data != NULL )
     {
                                    image, selImage, data);
     if ( data != NULL )
     {
@@ -1494,9 +1708,11 @@ wxTreeItemId wxGenericTreeCtrl::DoInsertAfter(const wxTreeItemId& parentId,
     int index = -1;
     if (idPrevious.IsOk())
     {
     int index = -1;
     if (idPrevious.IsOk())
     {
-        index = parent->GetChildren().Index((wxGenericTreeItem*) idPrevious.m_pItem);
+        index = parent->GetChildren().Index(
+                    (wxGenericTreeItem*) idPrevious.m_pItem);
         wxASSERT_MSG( index != wxNOT_FOUND,
         wxASSERT_MSG( index != wxNOT_FOUND,
-                      wxT("previous item in wxGenericTreeCtrl::InsertItem() is not a sibling") );
+                      "previous item in wxGenericTreeCtrl::InsertItem() "
+                      "is not a sibling" );
     }
 
     return DoInsertItem(parentId, (size_t)++index, text, image, selImage, data);
     }
 
     return DoInsertItem(parentId, (size_t)++index, text, image, selImage, data);
@@ -1512,16 +1728,24 @@ void wxGenericTreeCtrl::SendDeleteEvent(wxGenericTreeItem *item)
 // Don't leave edit or selection on a child which is about to disappear
 void wxGenericTreeCtrl::ChildrenClosing(wxGenericTreeItem* item)
 {
 // Don't leave edit or selection on a child which is about to disappear
 void wxGenericTreeCtrl::ChildrenClosing(wxGenericTreeItem* item)
 {
-    if (m_textCtrl != NULL && item != m_textCtrl->item() && IsDescendantOf(item, m_textCtrl->item())) {
+    if ( m_textCtrl && item != m_textCtrl->item() &&
+            IsDescendantOf(item, m_textCtrl->item()) )
+    {
         m_textCtrl->EndEdit( true );
     }
         m_textCtrl->EndEdit( true );
     }
-    if (item != m_key_current && IsDescendantOf(item, m_key_current)) {
+
+    if ( item != m_key_current && IsDescendantOf(item, m_key_current) )
+    {
         m_key_current = NULL;
     }
         m_key_current = NULL;
     }
-    if (IsDescendantOf(item, m_select_me)) {
+
+    if ( IsDescendantOf(item, m_select_me) )
+    {
         m_select_me = item;
     }
         m_select_me = item;
     }
-    if (item != m_current && IsDescendantOf(item, m_current)) {
+
+    if ( item != m_current && IsDescendantOf(item, m_current) )
+    {
         m_current->SetHilight( false );
         m_current = NULL;
         m_select_me = item;
         m_current->SetHilight( false );
         m_current = NULL;
         m_select_me = item;
@@ -1551,6 +1775,16 @@ void wxGenericTreeCtrl::Delete(const wxTreeItemId& itemId)
     }
 
     wxGenericTreeItem *parent = item->GetParent();
     }
 
     wxGenericTreeItem *parent = item->GetParent();
+    
+    // if the selected item will be deleted, select the parent ...
+    wxGenericTreeItem *to_be_selected = parent;
+    if (parent)
+    {
+        // .. unless there is a next sibling like wxMSW does it
+        int pos = parent->GetChildren().Index( item );
+        if ((int)(parent->GetChildren().GetCount()) > pos+1)
+            to_be_selected = parent->GetChildren().Item( pos+1 );
+    }
 
     // don't keep stale pointers around!
     if ( IsDescendantOf(item, m_key_current) )
 
     // don't keep stale pointers around!
     if ( IsDescendantOf(item, m_key_current) )
@@ -1567,7 +1801,7 @@ void wxGenericTreeCtrl::Delete(const wxTreeItemId& itemId)
     // a different item, in idle time.
     if ( m_select_me && IsDescendantOf(item, m_select_me) )
     {
     // a different item, in idle time.
     if ( m_select_me && IsDescendantOf(item, m_select_me) )
     {
-        m_select_me = parent;
+        m_select_me = to_be_selected;
     }
 
     if ( IsDescendantOf(item, m_current) )
     }
 
     if ( IsDescendantOf(item, m_current) )
@@ -1578,7 +1812,7 @@ void wxGenericTreeCtrl::Delete(const wxTreeItemId& itemId)
 
         // m_current = parent;
         m_current = NULL;
 
         // m_current = parent;
         m_current = NULL;
-        m_select_me = parent;
+        m_select_me = to_be_selected;
     }
 
     // remove the item from the tree
     }
 
     // remove the item from the tree
@@ -1751,7 +1985,10 @@ void wxGenericTreeCtrl::UnselectAll()
 // Tag all next children, when no more children,
 // Move to parent (not to tag)
 // Keep going... if we found last_item, we stop.
 // Tag all next children, when no more children,
 // Move to parent (not to tag)
 // Keep going... if we found last_item, we stop.
-bool wxGenericTreeCtrl::TagNextChildren(wxGenericTreeItem *crt_item, wxGenericTreeItem *last_item, bool select)
+bool
+wxGenericTreeCtrl::TagNextChildren(wxGenericTreeItem *crt_item,
+                                   wxGenericTreeItem *last_item,
+                                   bool select)
 {
     wxGenericTreeItem *parent = crt_item->GetParent();
 
 {
     wxGenericTreeItem *parent = crt_item->GetParent();
 
@@ -1765,13 +2002,17 @@ bool wxGenericTreeCtrl::TagNextChildren(wxGenericTreeItem *crt_item, wxGenericTr
     size_t count = children.GetCount();
     for (size_t n=(size_t)(index+1); n<count; ++n)
     {
     size_t count = children.GetCount();
     for (size_t n=(size_t)(index+1); n<count; ++n)
     {
-        if (TagAllChildrenUntilLast(children[n], last_item, select)) return true;
+        if ( TagAllChildrenUntilLast(children[n], last_item, select) )
+            return true;
     }
 
     return TagNextChildren(parent, last_item, select);
 }
 
     }
 
     return TagNextChildren(parent, last_item, select);
 }
 
-bool wxGenericTreeCtrl::TagAllChildrenUntilLast(wxGenericTreeItem *crt_item, wxGenericTreeItem *last_item, bool select)
+bool
+wxGenericTreeCtrl::TagAllChildrenUntilLast(wxGenericTreeItem *crt_item,
+                                           wxGenericTreeItem *last_item,
+                                           bool select)
 {
     crt_item->SetHilight(select);
     RefreshLine(crt_item);
 {
     crt_item->SetHilight(select);
     RefreshLine(crt_item);
@@ -1793,7 +2034,9 @@ bool wxGenericTreeCtrl::TagAllChildrenUntilLast(wxGenericTreeItem *crt_item, wxG
   return false;
 }
 
   return false;
 }
 
-void wxGenericTreeCtrl::SelectItemRange(wxGenericTreeItem *item1, wxGenericTreeItem *item2)
+void
+wxGenericTreeCtrl::SelectItemRange(wxGenericTreeItem *item1,
+                                   wxGenericTreeItem *item2)
 {
     m_select_me = NULL;
 
 {
     m_select_me = NULL;
 
@@ -1868,7 +2111,8 @@ void wxGenericTreeCtrl::DoSelectItem(const wxTreeItemId& itemId,
     {
         if ( !m_current )
         {
     {
         if ( !m_current )
         {
-            m_current = m_key_current = (wxGenericTreeItem*) GetRootItem().m_pItem;
+            m_current =
+            m_key_current = (wxGenericTreeItem*) GetRootItem().m_pItem;
         }
 
         // don't change the mark (m_current)
         }
 
         // don't change the mark (m_current)
@@ -1906,7 +2150,7 @@ void wxGenericTreeCtrl::SelectItem(const wxTreeItemId& itemId, bool select)
     {
         wxGenericTreeItem *item = (wxGenericTreeItem*) itemId.m_pItem;
         wxCHECK_RET( item, wxT("SelectItem(): invalid tree item") );
     {
         wxGenericTreeItem *item = (wxGenericTreeItem*) itemId.m_pItem;
         wxCHECK_RET( item, wxT("SelectItem(): invalid tree item") );
-        
+
         wxTreeEvent event(wxEVT_COMMAND_TREE_SEL_CHANGING, this, item);
         if ( GetEventHandler()->ProcessEvent( event ) && !event.IsAllowed() )
             return;
         wxTreeEvent event(wxEVT_COMMAND_TREE_SEL_CHANGING, this, item);
         if ( GetEventHandler()->ProcessEvent( event ) && !event.IsAllowed() )
             return;
@@ -2017,7 +2261,9 @@ void wxGenericTreeCtrl::ScrollTo(const wxTreeItemId &item)
         x += PIXELS_PER_UNIT+2; // one more scrollbar unit + 2 pixels
         int x_pos = GetScrollPos( wxHORIZONTAL );
         // Item should appear at top
         x += PIXELS_PER_UNIT+2; // one more scrollbar unit + 2 pixels
         int x_pos = GetScrollPos( wxHORIZONTAL );
         // Item should appear at top
-        SetScrollbars( PIXELS_PER_UNIT, PIXELS_PER_UNIT, x/PIXELS_PER_UNIT, y/PIXELS_PER_UNIT, x_pos, item_y/PIXELS_PER_UNIT );
+        SetScrollbars( PIXELS_PER_UNIT, PIXELS_PER_UNIT,
+                       x/PIXELS_PER_UNIT, y/PIXELS_PER_UNIT,
+                       x_pos, item_y/PIXELS_PER_UNIT );
     }
     else if (item_y+GetLineHeight(gitem) > start_y+client_h)
     {
     }
     else if (item_y+GetLineHeight(gitem) > start_y+client_h)
     {
@@ -2030,7 +2276,10 @@ void wxGenericTreeCtrl::ScrollTo(const wxTreeItemId &item)
         item_y += PIXELS_PER_UNIT+2;
         int x_pos = GetScrollPos( wxHORIZONTAL );
         // Item should appear at bottom
         item_y += PIXELS_PER_UNIT+2;
         int x_pos = GetScrollPos( wxHORIZONTAL );
         // Item should appear at bottom
-        SetScrollbars( PIXELS_PER_UNIT, PIXELS_PER_UNIT, x/PIXELS_PER_UNIT, y/PIXELS_PER_UNIT, x_pos, (item_y+GetLineHeight(gitem)-client_h)/PIXELS_PER_UNIT );
+        SetScrollbars( PIXELS_PER_UNIT, PIXELS_PER_UNIT,
+                       x/PIXELS_PER_UNIT, y/PIXELS_PER_UNIT,
+                       x_pos,
+                       (item_y+GetLineHeight(gitem)-client_h)/PIXELS_PER_UNIT );
     }
 }
 
     }
 }
 
@@ -2040,7 +2289,8 @@ static wxGenericTreeCtrl *s_treeBeingSorted = NULL;
 static int LINKAGEMODE tree_ctrl_compare_func(wxGenericTreeItem **item1,
                                   wxGenericTreeItem **item2)
 {
 static int LINKAGEMODE tree_ctrl_compare_func(wxGenericTreeItem **item1,
                                   wxGenericTreeItem **item2)
 {
-    wxCHECK_MSG( s_treeBeingSorted, 0, wxT("bug in wxGenericTreeCtrl::SortChildren()") );
+    wxCHECK_MSG( s_treeBeingSorted, 0,
+                 "bug in wxGenericTreeCtrl::SortChildren()" );
 
     return s_treeBeingSorted->OnCompareItems(*item1, *item2);
 }
 
     return s_treeBeingSorted->OnCompareItems(*item1, *item2);
 }
@@ -2085,6 +2335,20 @@ void wxGenericTreeCtrl::CalculateLineHeight()
         }
     }
 
         }
     }
 
+    if ( m_imageListState )
+    {
+        // Calculate a m_lineHeight value from the state Image sizes.
+        // May be toggle off. Then wxGenericTreeCtrl will spread when
+        // necessary (which might look ugly).
+        int n = m_imageListState->GetImageCount();
+        for (int i = 0; i < n ; i++)
+        {
+            int width = 0, height = 0;
+            m_imageListState->GetSize(i, width, height);
+            if (height > m_lineHeight) m_lineHeight = height;
+        }
+    }
+
     if (m_imageListButtons)
     {
         // Calculate a m_lineHeight value from the Button image sizes.
     if (m_imageListButtons)
     {
         // Calculate a m_lineHeight value from the Button image sizes.
@@ -2111,6 +2375,10 @@ void wxGenericTreeCtrl::SetImageList(wxImageList *imageList)
     m_imageListNormal = imageList;
     m_ownsImageListNormal = false;
     m_dirty = true;
     m_imageListNormal = imageList;
     m_ownsImageListNormal = false;
     m_dirty = true;
+
+    if (m_anchor)
+        m_anchor->RecursiveResetSize();
+
     // Don't do any drawing if we're setting the list to NULL,
     // since we may be in the process of deleting the tree control.
     if (imageList)
     // Don't do any drawing if we're setting the list to NULL,
     // since we may be in the process of deleting the tree control.
     if (imageList)
@@ -2122,6 +2390,15 @@ void wxGenericTreeCtrl::SetStateImageList(wxImageList *imageList)
     if (m_ownsImageListState) delete m_imageListState;
     m_imageListState = imageList;
     m_ownsImageListState = false;
     if (m_ownsImageListState) delete m_imageListState;
     m_imageListState = imageList;
     m_ownsImageListState = false;
+    m_dirty = true;
+
+    if (m_anchor)
+        m_anchor->RecursiveResetSize();
+
+    // Don't do any drawing if we're setting the list to NULL,
+    // since we may be in the process of deleting the tree control.
+    if (imageList)
+        CalculateLineHeight();
 }
 
 void wxGenericTreeCtrl::SetButtonsImageList(wxImageList *imageList)
 }
 
 void wxGenericTreeCtrl::SetButtonsImageList(wxImageList *imageList)
@@ -2130,6 +2407,10 @@ void wxGenericTreeCtrl::SetButtonsImageList(wxImageList *imageList)
     m_imageListButtons = imageList;
     m_ownsImageListButtons = false;
     m_dirty = true;
     m_imageListButtons = imageList;
     m_ownsImageListButtons = false;
     m_dirty = true;
+
+    if (m_anchor)
+        m_anchor->RecursiveResetSize();
+
     CalculateLineHeight();
 }
 
     CalculateLineHeight();
 }
 
@@ -2153,7 +2434,9 @@ void wxGenericTreeCtrl::AdjustMyScrollbars()
         x += PIXELS_PER_UNIT+2; // one more scrollbar unit + 2 pixels
         int x_pos = GetScrollPos( wxHORIZONTAL );
         int y_pos = GetScrollPos( wxVERTICAL );
         x += PIXELS_PER_UNIT+2; // one more scrollbar unit + 2 pixels
         int x_pos = GetScrollPos( wxHORIZONTAL );
         int y_pos = GetScrollPos( wxVERTICAL );
-        SetScrollbars( PIXELS_PER_UNIT, PIXELS_PER_UNIT, x/PIXELS_PER_UNIT, y/PIXELS_PER_UNIT, x_pos, y_pos );
+        SetScrollbars( PIXELS_PER_UNIT, PIXELS_PER_UNIT,
+                       x/PIXELS_PER_UNIT, y/PIXELS_PER_UNIT,
+                       x_pos, y_pos );
     }
     else
     {
     }
     else
     {
@@ -2171,16 +2454,10 @@ int wxGenericTreeCtrl::GetLineHeight(wxGenericTreeItem *item) const
 
 void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc)
 {
 
 void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc)
 {
-    // TODO implement "state" icon on items
-
-    wxTreeItemAttr *attr = item->GetAttributes();
-    if ( attr && attr->HasFont() )
-        dc.SetFont(attr->GetFont());
-    else if (item->IsBold())
-        dc.SetFont(m_boldFont);
+    item->SetFont(this, dc);
+    item->CalculateSize(this, dc);
 
 
-    wxCoord text_w = 0, text_h = 0;
-    dc.GetTextExtent( item->GetText(), &text_w, &text_h );
+    wxCoord text_h = item->GetTextHeight();
 
     int image_h = 0, image_w = 0;
     int image = item->GetCurrentImage();
 
     int image_h = 0, image_w = 0;
     int image = item->GetCurrentImage();
@@ -2188,7 +2465,7 @@ void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc)
     {
         if ( m_imageListNormal )
         {
     {
         if ( m_imageListNormal )
         {
-            m_imageListNormal->GetSize( image, image_w, image_h );
+            m_imageListNormal->GetSize(image, image_w, image_h);
             image_w += MARGIN_BETWEEN_IMAGE_AND_TEXT;
         }
         else
             image_w += MARGIN_BETWEEN_IMAGE_AND_TEXT;
         }
         else
@@ -2197,8 +2474,27 @@ void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc)
         }
     }
 
         }
     }
 
+    int state_h = 0, state_w = 0;
+    int state = item->GetState();
+    if ( state != wxTREE_ITEMSTATE_NONE )
+    {
+        if ( m_imageListState )
+        {
+            m_imageListState->GetSize(state, state_w, state_h);
+            if ( image_w != 0 )
+                state_w += MARGIN_BETWEEN_STATE_AND_IMAGE;
+            else
+                state_w += MARGIN_BETWEEN_IMAGE_AND_TEXT;
+        }
+        else
+        {
+            state = wxTREE_ITEMSTATE_NONE;
+        }
+    }
+
     int total_h = GetLineHeight(item);
     int total_h = GetLineHeight(item);
-    bool drawItemBackground = false;
+    bool drawItemBackground = false,
+         hasBgColour = false;
 
     if ( item->IsSelected() )
     {
 
     if ( item->IsSelected() )
     {
@@ -2208,16 +2504,18 @@ void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc)
     else
     {
         wxColour colBg;
     else
     {
         wxColour colBg;
+        wxTreeItemAttr * const attr = item->GetAttributes();
         if ( attr && attr->HasBackgroundColour() )
         {
         if ( attr && attr->HasBackgroundColour() )
         {
-            drawItemBackground = true;
+            drawItemBackground =
+            hasBgColour = true;
             colBg = attr->GetBackgroundColour();
         }
         else
         {
             colBg = GetBackgroundColour();
         }
             colBg = attr->GetBackgroundColour();
         }
         else
         {
             colBg = GetBackgroundColour();
         }
-        dc.SetBrush(wxBrush(colBg, wxSOLID));
+        dc.SetBrush(wxBrush(colBg, wxBRUSHSTYLE_SOLID));
     }
 
     int offset = HasFlag(wxTR_ROW_LINES) ? 1 : 0;
     }
 
     int offset = HasFlag(wxTR_ROW_LINES) ? 1 : 0;
@@ -2228,9 +2526,6 @@ void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc)
         x=0;
         GetVirtualSize(&w, &h);
         wxRect rect( x, item->GetY()+offset, w, total_h-offset);
         x=0;
         GetVirtualSize(&w, &h);
         wxRect rect( x, item->GetY()+offset, w, total_h-offset);
-#if !defined(__WXGTK20__) && !defined(__WXMAC__)
-        dc.DrawRectangle(rect);
-#else
         if (!item->IsSelected())
         {
             dc.DrawRectangle(rect);
         if (!item->IsSelected())
         {
             dc.DrawRectangle(rect);
@@ -2239,38 +2534,43 @@ void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc)
         {
             int flags = wxCONTROL_SELECTED;
             if (m_hasFocus
         {
             int flags = wxCONTROL_SELECTED;
             if (m_hasFocus
-#if defined( __WXMAC__ ) && !defined(__WXUNIVERSAL__)
+#if defined( __WXMAC__ ) && !defined(__WXUNIVERSAL__) && wxOSX_USE_CARBON // TODO CS
                 && IsControlActive( (ControlRef)GetHandle() )
 #endif
             )
                 flags |= wxCONTROL_FOCUSED;
             if ((item == m_current) && (m_hasFocus))
                 flags |= wxCONTROL_CURRENT;
                 && IsControlActive( (ControlRef)GetHandle() )
 #endif
             )
                 flags |= wxCONTROL_FOCUSED;
             if ((item == m_current) && (m_hasFocus))
                 flags |= wxCONTROL_CURRENT;
-            wxRendererNative::Get().DrawItemSelectionRect( this, dc, rect, flags );
+
+            wxRendererNative::Get().
+                DrawItemSelectionRect(this, dc, rect, flags);
         }
         }
-#endif
     }
     }
-    else
+    else // no full row highlight
     {
     {
-        if ( item->IsSelected() && image != NO_IMAGE )
+        if ( item->IsSelected() &&
+                (state != wxTREE_ITEMSTATE_NONE || image != NO_IMAGE) )
         {
         {
-            // If it's selected, and there's an image, then we should
-            // take care to leave the area under the image painted in the
-            // background colour.
-            wxRect rect( item->GetX() + image_w - 2, item->GetY()+offset,
-                         item->GetWidth() - image_w + 2, total_h-offset );
+            // If it's selected, and there's an state image or normal image,
+            // then we should take care to leave the area under the image
+            // painted in the background colour.
+            wxRect rect( item->GetX() + state_w + image_w - 2,
+                         item->GetY() + offset,
+                         item->GetWidth() - state_w - image_w + 2,
+                         total_h - offset );
 #if !defined(__WXGTK20__) && !defined(__WXMAC__)
             dc.DrawRectangle( rect );
 #else
             rect.x -= 1;
             rect.width += 2;
 #if !defined(__WXGTK20__) && !defined(__WXMAC__)
             dc.DrawRectangle( rect );
 #else
             rect.x -= 1;
             rect.width += 2;
-        
+
             int flags = wxCONTROL_SELECTED;
             if (m_hasFocus)
                 flags |= wxCONTROL_FOCUSED;
             if ((item == m_current) && (m_hasFocus))
                 flags |= wxCONTROL_CURRENT;
             int flags = wxCONTROL_SELECTED;
             if (m_hasFocus)
                 flags |= wxCONTROL_FOCUSED;
             if ((item == m_current) && (m_hasFocus))
                 flags |= wxCONTROL_CURRENT;
-            wxRendererNative::Get().DrawItemSelectionRect( this, dc, rect, flags );
+            wxRendererNative::Get().
+                DrawItemSelectionRect(this, dc, rect, flags);
 #endif
         }
         // On GTK+ 2, drawing a 'normal' background is wrong for themes that
 #endif
         }
         // On GTK+ 2, drawing a 'normal' background is wrong for themes that
@@ -2278,53 +2578,104 @@ void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc)
         // except for custom item backgrounds, works for both kinds of theme.
         else if (drawItemBackground)
         {
         // except for custom item backgrounds, works for both kinds of theme.
         else if (drawItemBackground)
         {
-            wxRect rect( item->GetX()-2, item->GetY()+offset,
-                         item->GetWidth()+2, total_h-offset );
-#if !defined(__WXGTK20__) && !defined(__WXMAC__)
-            dc.DrawRectangle( rect );
-#else
-            if ( attr && attr->HasBackgroundColour() )
+            wxRect rect( item->GetX() + state_w + image_w - 2,
+                         item->GetY() + offset,
+                         item->GetWidth() - state_w - image_w + 2,
+                         total_h - offset );
+            if ( hasBgColour )
             {
                 dc.DrawRectangle( rect );
             }
             {
                 dc.DrawRectangle( rect );
             }
-            else
+            else // no specific background colour
             {
                 rect.x -= 1;
                 rect.width += 2;
             {
                 rect.x -= 1;
                 rect.width += 2;
-                
+
                 int flags = wxCONTROL_SELECTED;
                 if (m_hasFocus)
                     flags |= wxCONTROL_FOCUSED;
                 if ((item == m_current) && (m_hasFocus))
                     flags |= wxCONTROL_CURRENT;
                 int flags = wxCONTROL_SELECTED;
                 if (m_hasFocus)
                     flags |= wxCONTROL_FOCUSED;
                 if ((item == m_current) && (m_hasFocus))
                     flags |= wxCONTROL_CURRENT;
-                wxRendererNative::Get().DrawItemSelectionRect( this, dc, rect, flags );
+                wxRendererNative::Get().
+                    DrawItemSelectionRect(this, dc, rect, flags);
             }
             }
-#endif
         }
     }
 
         }
     }
 
+    if ( state != wxTREE_ITEMSTATE_NONE )
+    {
+        dc.SetClippingRegion( item->GetX(), item->GetY(), state_w, total_h );
+        m_imageListState->Draw( state, dc,
+                                item->GetX(),
+                                item->GetY() +
+                                    (total_h > state_h ? (total_h-state_h)/2
+                                                       : 0),
+                                wxIMAGELIST_DRAW_TRANSPARENT );
+        dc.DestroyClippingRegion();
+    }
+
     if ( image != NO_IMAGE )
     {
     if ( image != NO_IMAGE )
     {
-        dc.SetClippingRegion( item->GetX(), item->GetY(), image_w-2, total_h );
+        dc.SetClippingRegion(item->GetX() + state_w, item->GetY(),
+                             image_w, total_h);
         m_imageListNormal->Draw( image, dc,
         m_imageListNormal->Draw( image, dc,
-                                 item->GetX(),
-                                 item->GetY() +((total_h > image_h)?((total_h-image_h)/2):0),
+                                 item->GetX() + state_w,
+                                 item->GetY() +
+                                    (total_h > image_h ? (total_h-image_h)/2
+                                                       : 0),
                                  wxIMAGELIST_DRAW_TRANSPARENT );
         dc.DestroyClippingRegion();
     }
 
                                  wxIMAGELIST_DRAW_TRANSPARENT );
         dc.DestroyClippingRegion();
     }
 
-    dc.SetBackgroundMode(wxTRANSPARENT);
+    dc.SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT);
     int extraH = (total_h > text_h) ? (total_h - text_h)/2 : 0;
     dc.DrawText( item->GetText(),
     int extraH = (total_h > text_h) ? (total_h - text_h)/2 : 0;
     dc.DrawText( item->GetText(),
-                 (wxCoord)(image_w + item->GetX()),
+                 (wxCoord)(state_w + image_w + item->GetX()),
                  (wxCoord)(item->GetY() + extraH));
 
     // restore normal font
     dc.SetFont( m_normalFont );
                  (wxCoord)(item->GetY() + extraH));
 
     // restore normal font
     dc.SetFont( m_normalFont );
+
+    if (item == m_dndEffectItem)
+    {
+        dc.SetPen( *wxBLACK_PEN );
+        // DnD visual effects
+        switch (m_dndEffect)
+        {
+            case BorderEffect:
+            {
+                dc.SetBrush(*wxTRANSPARENT_BRUSH);
+                int w = item->GetWidth() + 2;
+                int h = total_h + 2;
+                dc.DrawRectangle( item->GetX() - 1, item->GetY() - 1, w, h);
+                break;
+            }
+            case AboveEffect:
+            {
+                int x = item->GetX(),
+                    y = item->GetY();
+                dc.DrawLine( x, y, x + item->GetWidth(), y);
+                break;
+            }
+            case BelowEffect:
+            {
+                int x = item->GetX(),
+                    y = item->GetY();
+                y += total_h - 1;
+                dc.DrawLine( x, y, x + item->GetWidth(), y);
+                break;
+            }
+            case NoEffect:
+                break;
+        }
+    }
 }
 
 }
 
-// Now y stands for the top of the item, whereas it used to stand for middle !
-void wxGenericTreeCtrl::PaintLevel( wxGenericTreeItem *item, wxDC &dc, int level, int &y )
+void
+wxGenericTreeCtrl::PaintLevel(wxGenericTreeItem *item,
+                              wxDC &dc,
+                              int level,
+                              int &y)
 {
     int x = level*m_indent;
     if (!HasFlag(wxTR_HIDE_ROOT))
 {
     int x = level*m_indent;
     if (!HasFlag(wxTR_HIDE_ROOT))
@@ -2345,7 +2696,8 @@ void wxGenericTreeCtrl::PaintLevel( wxGenericTreeItem *item, wxDC &dc, int level
                 PaintLevel(children[n], dc, 1, y);
             } while (++n < count);
 
                 PaintLevel(children[n], dc, 1, y);
             } while (++n < count);
 
-            if (!HasFlag(wxTR_NO_LINES) && HasFlag(wxTR_LINES_AT_ROOT) && count > 0)
+            if ( !HasFlag(wxTR_NO_LINES) && HasFlag(wxTR_LINES_AT_ROOT)
+                    && count > 0 )
             {
                 // draw line down to last child
                 origY += GetLineHeight(children[0])>>1;
             {
                 // draw line down to last child
                 origY += GetLineHeight(children[0])>>1;
@@ -2379,7 +2731,7 @@ void wxGenericTreeCtrl::PaintLevel( wxGenericTreeItem *item, wxDC &dc, int level
 
         wxColour colText;
         if ( item->IsSelected()
 
         wxColour colText;
         if ( item->IsSelected()
-#if defined( __WXMAC__ ) && !defined(__WXUNIVERSAL__)
+#if defined( __WXMAC__ ) && !defined(__WXUNIVERSAL__) && wxOSX_USE_CARBON // TODO CS
             // On wxMac, if the tree doesn't have the focus we draw an empty
             // rectangle, so we want to make sure that the text is visible
             // against the normal background, not the highlightbackground, so
             // On wxMac, if the tree doesn't have the focus we draw an empty
             // rectangle, so we want to make sure that the text is visible
             // against the normal background, not the highlightbackground, so
@@ -2500,7 +2852,8 @@ void wxGenericTreeCtrl::PaintLevel( wxGenericTreeItem *item, wxDC &dc, int level
                 oldY += GetLineHeight(children[n-1])>>1;
                 if (HasButtons()) y_mid += 5;
 
                 oldY += GetLineHeight(children[n-1])>>1;
                 if (HasButtons()) y_mid += 5;
 
-                // Only draw the portion of the line that is visible, in case it is huge
+                // Only draw the portion of the line that is visible, in case
+                // it is huge
                 wxCoord xOrigin=0, yOrigin=0, width, height;
                 dc.GetDeviceOrigin(&xOrigin, &yOrigin);
                 yOrigin = abs(yOrigin);
                 wxCoord xOrigin=0, yOrigin=0, width, height;
                 dc.GetDeviceOrigin(&xOrigin, &yOrigin);
                 yOrigin = abs(yOrigin);
@@ -2512,8 +2865,8 @@ void wxGenericTreeCtrl::PaintLevel( wxGenericTreeItem *item, wxDC &dc, int level
                 if (oldY > yOrigin + height)
                     oldY = yOrigin + height;
 
                 if (oldY > yOrigin + height)
                     oldY = yOrigin + height;
 
-                // after the adjustments if y_mid is larger than oldY then the line
-                // isn't visible at all so don't draw anything
+                // after the adjustments if y_mid is larger than oldY then the
+                // line isn't visible at all so don't draw anything
                 if (y_mid < oldY)
                     dc.DrawLine(x, y_mid, x, oldY);
             }
                 if (y_mid < oldY)
                     dc.DrawLine(x, y_mid, x, oldY);
             }
@@ -2537,7 +2890,7 @@ void wxGenericTreeCtrl::DrawDropEffect(wxGenericTreeItem *item)
             DrawLine(item, !m_dropEffectAboveItem );
         }
 
             DrawLine(item, !m_dropEffectAboveItem );
         }
 
-        SetCursor(wxCURSOR_BULLSEYE);
+        SetCursor(*wxSTANDARD_CURSOR);
     }
     else
     {
     }
     else
     {
@@ -2548,39 +2901,49 @@ void wxGenericTreeCtrl::DrawDropEffect(wxGenericTreeItem *item)
 
 void wxGenericTreeCtrl::DrawBorder(const wxTreeItemId &item)
 {
 
 void wxGenericTreeCtrl::DrawBorder(const wxTreeItemId &item)
 {
-    wxCHECK_RET( item.IsOk(), _T("invalid item in wxGenericTreeCtrl::DrawLine") );
+    wxCHECK_RET( item.IsOk(), "invalid item in wxGenericTreeCtrl::DrawLine" );
 
     wxGenericTreeItem *i = (wxGenericTreeItem*) item.m_pItem;
 
 
     wxGenericTreeItem *i = (wxGenericTreeItem*) item.m_pItem;
 
-    wxClientDC dc(this);
-    PrepareDC( dc );
-    dc.SetLogicalFunction(wxINVERT);
-    dc.SetBrush(*wxTRANSPARENT_BRUSH);
-
-    int w = i->GetWidth() + 2;
-    int h = GetLineHeight(i) + 2;
+    if (m_dndEffect == NoEffect)
+    {
+        m_dndEffect = BorderEffect;
+        m_dndEffectItem = i;
+    }
+    else
+    {
+        m_dndEffect = NoEffect;
+        m_dndEffectItem = NULL;
+    }
 
 
-    dc.DrawRectangle( i->GetX() - 1, i->GetY() - 1, w, h);
+    wxRect rect( i->GetX()-1, i->GetY()-1, i->GetWidth()+2, GetLineHeight(i)+2 );
+    CalcScrolledPosition( rect.x, rect.y, &rect.x, &rect.y );
+    RefreshRect( rect );
 }
 
 void wxGenericTreeCtrl::DrawLine(const wxTreeItemId &item, bool below)
 {
 }
 
 void wxGenericTreeCtrl::DrawLine(const wxTreeItemId &item, bool below)
 {
-    wxCHECK_RET( item.IsOk(), _T("invalid item in wxGenericTreeCtrl::DrawLine") );
+    wxCHECK_RET( item.IsOk(), "invalid item in wxGenericTreeCtrl::DrawLine" );
 
     wxGenericTreeItem *i = (wxGenericTreeItem*) item.m_pItem;
 
 
     wxGenericTreeItem *i = (wxGenericTreeItem*) item.m_pItem;
 
-    wxClientDC dc(this);
-    PrepareDC( dc );
-    dc.SetLogicalFunction(wxINVERT);
-
-    int x = i->GetX(),
-        y = i->GetY();
-    if ( below )
+    if (m_dndEffect == NoEffect)
+    {
+        if (below)
+            m_dndEffect = BelowEffect;
+        else
+            m_dndEffect = AboveEffect;
+        m_dndEffectItem = i;
+    }
+    else
     {
     {
-        y += GetLineHeight(i) - 1;
+        m_dndEffect = NoEffect;
+        m_dndEffectItem = NULL;
     }
 
     }
 
-    dc.DrawLine( x, y, x + i->GetWidth(), y);
+    wxRect rect( i->GetX()-1, i->GetY()-1, i->GetWidth()+2, GetLineHeight(i)+2 );
+    CalcScrolledPosition( rect.x, rect.y, &rect.x, &rect.y );
+    RefreshRect( rect );
 }
 
 // -----------------------------------------------------------------------------
 }
 
 // -----------------------------------------------------------------------------
@@ -2707,14 +3070,17 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event )
 
         case WXK_MENU:
             {
 
         case WXK_MENU:
             {
-                // Use the item's bounding rectangle to determine position for the event
+                // Use the item's bounding rectangle to determine position for
+                // the event
                 wxRect ItemRect;
                 GetBoundingRect(m_current, ItemRect, true);
 
                 wxRect ItemRect;
                 GetBoundingRect(m_current, ItemRect, true);
 
-                wxTreeEvent eventMenu(wxEVT_COMMAND_TREE_ITEM_MENU, this, m_current);
+                wxTreeEvent
+                    eventMenu(wxEVT_COMMAND_TREE_ITEM_MENU, this, m_current);
                 // Use the left edge, vertical middle
                 eventMenu.m_pointDrag = wxPoint(ItemRect.GetX(),
                 // Use the left edge, vertical middle
                 eventMenu.m_pointDrag = wxPoint(ItemRect.GetX(),
-                                                ItemRect.GetY() + ItemRect.GetHeight() / 2);
+                                                ItemRect.GetY() +
+                                                    ItemRect.GetHeight() / 2);
                 GetEventHandler()->ProcessEvent( eventMenu );
             }
             break;
                 GetEventHandler()->ProcessEvent( eventMenu );
             }
             break;
@@ -2723,7 +3089,8 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event )
         case WXK_RETURN:
             if ( !event.HasModifiers() )
             {
         case WXK_RETURN:
             if ( !event.HasModifiers() )
             {
-                wxTreeEvent eventAct(wxEVT_COMMAND_TREE_ITEM_ACTIVATED, this, m_current);
+                wxTreeEvent
+                   eventAct(wxEVT_COMMAND_TREE_ITEM_ACTIVATED, this, m_current);
                 GetEventHandler()->ProcessEvent( eventAct );
             }
 
                 GetEventHandler()->ProcessEvent( eventAct );
             }
 
@@ -2751,12 +3118,15 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event )
                     {
                         wxTreeItemIdValue cookie;
                         wxTreeItemId current = m_key_current;
                     {
                         wxTreeItemIdValue cookie;
                         wxTreeItemId current = m_key_current;
-                        // TODO: Huh?  If we get here, we'd better be the first child of our parent.  How else could it be?
+                        // TODO: Huh?  If we get here, we'd better be the first
+                        // child of our parent.  How else could it be?
                         if (current == GetFirstChild( prev, cookie ))
                         {
                             // otherwise we return to where we came from
                         if (current == GetFirstChild( prev, cookie ))
                         {
                             // otherwise we return to where we came from
-                            DoSelectItem( prev, unselect_others, extended_select );
-                            m_key_current= (wxGenericTreeItem*) prev.m_pItem;
+                            DoSelectItem(prev,
+                                         unselect_others,
+                                         extended_select);
+                            m_key_current = (wxGenericTreeItem*) prev.m_pItem;
                             break;
                         }
                     }
                             break;
                         }
                     }
@@ -2952,21 +3322,35 @@ bool wxGenericTreeCtrl::GetBoundingRect(const wxTreeItemId& item,
                                         wxRect& rect,
                                         bool textOnly) const
 {
                                         wxRect& rect,
                                         bool textOnly) const
 {
-    wxCHECK_MSG( item.IsOk(), false, _T("invalid item in wxGenericTreeCtrl::GetBoundingRect") );
+    wxCHECK_MSG( item.IsOk(), false,
+                 "invalid item in wxGenericTreeCtrl::GetBoundingRect" );
 
     wxGenericTreeItem *i = (wxGenericTreeItem*) item.m_pItem;
 
     if ( textOnly )
     {
 
     wxGenericTreeItem *i = (wxGenericTreeItem*) item.m_pItem;
 
     if ( textOnly )
     {
-        rect.x = i->GetX();
-        rect.width = i->GetWidth();
+        int image_h = 0, image_w = 0;
+        int image = ((wxGenericTreeItem*) item.m_pItem)->GetCurrentImage();
+        if ( image != NO_IMAGE && m_imageListNormal )
+        {
+            m_imageListNormal->GetSize( image, image_w, image_h );
+            image_w += MARGIN_BETWEEN_IMAGE_AND_TEXT;
+        }
 
 
-        if ( m_imageListNormal )
+        int state_h = 0, state_w = 0;
+        int state = ((wxGenericTreeItem*) item.m_pItem)->GetState();
+        if ( state != wxTREE_ITEMSTATE_NONE && m_imageListState )
         {
         {
-            int image_w, image_h;
-            m_imageListNormal->GetSize( 0, image_w, image_h );
-            rect.width += image_w + MARGIN_BETWEEN_IMAGE_AND_TEXT;
+            m_imageListState->GetSize( state, state_w, state_h );
+            if ( image_w != 0 )
+                state_w += MARGIN_BETWEEN_STATE_AND_IMAGE;
+            else
+                state_w += MARGIN_BETWEEN_IMAGE_AND_TEXT;
         }
         }
+
+        rect.x = i->GetX() + state_w + image_w;
+        rect.width = i->GetWidth() - state_w - image_w;
+
     }
     else // the entire line
     {
     }
     else // the entire line
     {
@@ -3101,11 +3485,16 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event )
     // Determines what item we are hovering over and need a tooltip for
     wxTreeItemId hoverItem = thisItem;
 
     // Determines what item we are hovering over and need a tooltip for
     wxTreeItemId hoverItem = thisItem;
 
-    // We do not want a tooltip if we are dragging, or if the rename timer is running
-    if (underMouseChanged && hoverItem.IsOk() && !m_isDragging && (!m_renameTimer || !m_renameTimer->IsRunning()))
+    // We do not want a tooltip if we are dragging, or if the rename timer is
+    // running
+    if ( underMouseChanged &&
+            hoverItem.IsOk() &&
+              !m_isDragging &&
+                (!m_renameTimer || !m_renameTimer->IsRunning()) )
     {
         // Ask the tree control what tooltip (if any) should be shown
     {
         // Ask the tree control what tooltip (if any) should be shown
-        wxTreeEvent hevent(wxEVT_COMMAND_TREE_ITEM_GETTOOLTIP,  this, hoverItem);
+        wxTreeEvent
+            hevent(wxEVT_COMMAND_TREE_ITEM_GETTOOLTIP,  this, hoverItem);
 
         if ( GetEventHandler()->ProcessEvent(hevent) && hevent.IsAllowed() )
         {
 
         if ( GetEventHandler()->ProcessEvent(hevent) && hevent.IsAllowed() )
         {
@@ -3197,6 +3586,8 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event )
 #if defined(__WXMSW__) || defined(__WXMAC__) || defined(__WXGTK20__)
             Update();
 #else
 #if defined(__WXMSW__) || defined(__WXMAC__) || defined(__WXGTK20__)
             Update();
 #else
+            // TODO: remove this call or use wxEventLoopBase::GetActive()->YieldFor(wxEVT_CATEGORY_UI)
+            //       instead (needs to be tested!)
             wxYieldIfNeeded();
 #endif
         }
             wxYieldIfNeeded();
 #endif
         }
@@ -3212,7 +3603,7 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event )
         {
             m_oldSelection->SetHilight(true);
             RefreshLine(m_oldSelection);
         {
             m_oldSelection->SetHilight(true);
             RefreshLine(m_oldSelection);
-            m_oldSelection = (wxGenericTreeItem *)NULL;
+            m_oldSelection = NULL;
         }
 
         // generate the drag end event
         }
 
         // generate the drag end event
@@ -3223,23 +3614,27 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event )
         (void)GetEventHandler()->ProcessEvent(eventEndDrag);
 
         m_isDragging = false;
         (void)GetEventHandler()->ProcessEvent(eventEndDrag);
 
         m_isDragging = false;
-        m_dropTarget = (wxGenericTreeItem *)NULL;
+        m_dropTarget = NULL;
 
         SetCursor(m_oldCursor);
 
 
         SetCursor(m_oldCursor);
 
-#if defined( __WXMSW__ ) || defined(__WXMAC__)
+#if defined( __WXMSW__ ) || defined(__WXMAC__) || defined(__WXGTK20__)
         Update();
 #else
         Update();
 #else
+        // TODO: remove this call or use wxEventLoopBase::GetActive()->YieldFor(wxEVT_CATEGORY_UI)
+        //       instead (needs to be tested!)
         wxYieldIfNeeded();
 #endif
     }
     else
     {
         // If we got to this point, we are not dragging or moving the mouse.
         wxYieldIfNeeded();
 #endif
     }
     else
     {
         // If we got to this point, we are not dragging or moving the mouse.
-        // Because the code in carbon/toplevel.cpp will only set focus to the tree
-        // if we skip for EVT_LEFT_DOWN, we MUST skip this event here for focus to work.
+        // Because the code in carbon/toplevel.cpp will only set focus to the
+        // tree if we skip for EVT_LEFT_DOWN, we MUST skip this event here for
+        // focus to work.
         // We skip even if we didn't hit an item because we still should
         // We skip even if we didn't hit an item because we still should
-        // restore focus to the tree control even if we didn't exactly hit an item.
+        // restore focus to the tree control even if we didn't exactly hit an
+        // item.
         if ( event.LeftDown() )
         {
             event.Skip();
         if ( event.LeftDown() )
         {
             event.Skip();
@@ -3254,13 +3649,15 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event )
         if ( event.RightDown() )
         {
             // If the item is already selected, do not update the selection.
         if ( event.RightDown() )
         {
             // If the item is already selected, do not update the selection.
-            // Multi-selections should not be cleared if a selected item is clicked.
+            // Multi-selections should not be cleared if a selected item is
+            // clicked.
             if (!IsSelected(item))
             {
                 DoSelectItem(item, true, false);
             }
 
             if (!IsSelected(item))
             {
                 DoSelectItem(item, true, false);
             }
 
-            wxTreeEvent nevent(wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK,  this, item);
+            wxTreeEvent
+                nevent(wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK,  this, item);
             nevent.m_pointDrag = CalcScrolledPosition(pt);
             event.Skip(!GetEventHandler()->ProcessEvent(nevent));
 
             nevent.m_pointDrag = CalcScrolledPosition(pt);
             event.Skip(!GetEventHandler()->ProcessEvent(nevent));
 
@@ -3272,12 +3669,20 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event )
         }
         else if ( event.MiddleDown() )
         {
         }
         else if ( event.MiddleDown() )
         {
-            wxTreeEvent nevent(wxEVT_COMMAND_TREE_ITEM_MIDDLE_CLICK,  this, item);
+            wxTreeEvent
+                nevent(wxEVT_COMMAND_TREE_ITEM_MIDDLE_CLICK,  this, item);
             nevent.m_pointDrag = CalcScrolledPosition(pt);
             event.Skip(!GetEventHandler()->ProcessEvent(nevent));
         }
         else if ( event.LeftUp() )
         {
             nevent.m_pointDrag = CalcScrolledPosition(pt);
             event.Skip(!GetEventHandler()->ProcessEvent(nevent));
         }
         else if ( event.LeftUp() )
         {
+            if (flags & wxTREE_HITTEST_ONITEMSTATEICON)
+            {
+                wxTreeEvent
+                    nevent(wxEVT_COMMAND_TREE_STATE_IMAGE_CLICK, this, item);
+                GetEventHandler()->ProcessEvent(nevent);
+            }
+
             // this facilitates multiple-item drag-and-drop
 
             if ( /* item && */ HasFlag(wxTR_MULTIPLE))
             // this facilitates multiple-item drag-and-drop
 
             if ( /* item && */ HasFlag(wxTR_MULTIPLE))
@@ -3315,8 +3720,9 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event )
                 m_lastOnSame = false;
             }
         }
                 m_lastOnSame = false;
             }
         }
-        else // !RightDown() && !MiddleDown() && !LeftUp() ==> LeftDown() || LeftDClick()
+        else // !RightDown() && !MiddleDown() && !LeftUp()
         {
         {
+            // ==> LeftDown() || LeftDClick()
             if ( event.LeftDown() )
             {
                 m_lastOnSame = item == m_current;
             if ( event.LeftDown() )
             {
                 m_lastOnSame = item == m_current;
@@ -3348,7 +3754,9 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event )
                 EventFlagsToSelType(GetWindowStyleFlag(),
                                     event.ShiftDown(),
                                     event.CmdDown(),
                 EventFlagsToSelType(GetWindowStyleFlag(),
                                     event.ShiftDown(),
                                     event.CmdDown(),
-                                    is_multiple, extended_select, unselect_others);
+                                    is_multiple,
+                                    extended_select,
+                                    unselect_others);
 
                 DoSelectItem(item, unselect_others, extended_select);
             }
 
                 DoSelectItem(item, unselect_others, extended_select);
             }
@@ -3365,7 +3773,8 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event )
                 m_lastOnSame = false;
 
                 // send activate event first
                 m_lastOnSame = false;
 
                 // send activate event first
-                wxTreeEvent nevent(wxEVT_COMMAND_TREE_ITEM_ACTIVATED,  this, item);
+                wxTreeEvent
+                    nevent(wxEVT_COMMAND_TREE_ITEM_ACTIVATED,  this, item);
                 nevent.m_pointDrag = CalcScrolledPosition(pt);
                 if ( !GetEventHandler()->ProcessEvent( nevent ) )
                 {
                 nevent.m_pointDrag = CalcScrolledPosition(pt);
                 if ( !GetEventHandler()->ProcessEvent( nevent ) )
                 {
@@ -3404,55 +3813,11 @@ void wxGenericTreeCtrl::OnInternalIdle()
         DoDirtyProcessing();
 }
 
         DoDirtyProcessing();
 }
 
-void wxGenericTreeCtrl::CalculateSize( wxGenericTreeItem *item, wxDC &dc )
-{
-    wxCoord text_w = 0;
-    wxCoord text_h = 0;
-
-    wxTreeItemAttr *attr = item->GetAttributes();
-    if ( attr && attr->HasFont() )
-        dc.SetFont(attr->GetFont());
-    else if ( item->IsBold() )
-        dc.SetFont(m_boldFont);
-    else
-        dc.SetFont(m_normalFont);
-
-    dc.GetTextExtent( item->GetText(), &text_w, &text_h );
-    text_h+=2;
-
-    // restore normal font
-    dc.SetFont( m_normalFont );
-
-    int image_h = 0;
-    int image_w = 0;
-    int image = item->GetCurrentImage();
-    if ( image != NO_IMAGE )
-    {
-        if ( m_imageListNormal )
-        {
-            m_imageListNormal->GetSize( image, image_w, image_h );
-            image_w += MARGIN_BETWEEN_IMAGE_AND_TEXT;
-        }
-    }
-
-    int total_h = (image_h > text_h) ? image_h : text_h;
-
-    if (total_h < 30)
-        total_h += 2;            // at least 2 pixels
-    else
-        total_h += total_h/10;   // otherwise 10% extra spacing
-
-    item->SetHeight(total_h);
-    if (total_h>m_lineHeight)
-        m_lineHeight=total_h;
-
-    item->SetWidth(image_w+text_w+2);
-}
-
-// -----------------------------------------------------------------------------
-// for developper : y is now the top of the level
-// not the middle of it !
-void wxGenericTreeCtrl::CalculateLevel( wxGenericTreeItem *item, wxDC &dc, int level, int &y )
+void
+wxGenericTreeCtrl::CalculateLevel(wxGenericTreeItem *item,
+                                  wxDC &dc,
+                                  int level,
+                                  int &y )
 {
     int x = level*m_indent;
     if (!HasFlag(wxTR_HIDE_ROOT))
 {
     int x = level*m_indent;
     if (!HasFlag(wxTR_HIDE_ROOT))
@@ -3466,7 +3831,7 @@ void wxGenericTreeCtrl::CalculateLevel( wxGenericTreeItem *item, wxDC &dc, int l
         goto Recurse;
     }
 
         goto Recurse;
     }
 
-    CalculateSize( item, dc );
+    item->CalculateSize(this, dc);
 
     // set its position
     item->SetX( x+m_spacing );
 
     // set its position
     item->SetX( x+m_spacing );
@@ -3569,6 +3934,8 @@ void wxGenericTreeCtrl::RefreshSelectedUnder(wxGenericTreeItem *item)
 
 void wxGenericTreeCtrl::DoThaw()
 {
 
 void wxGenericTreeCtrl::DoThaw()
 {
+    wxTreeCtrlBase::DoThaw();
+
     if ( m_dirty )
         DoDirtyProcessing();
     else
     if ( m_dirty )
         DoDirtyProcessing();
     else
@@ -3624,7 +3991,7 @@ wxGenericTreeCtrl::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
     return wxListBox::GetClassDefaultAttributes(variant);
 #else
     wxVisualAttributes attr;
     return wxListBox::GetClassDefaultAttributes(variant);
 #else
     wxVisualAttributes attr;
-    attr.colFg = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
+    attr.colFg = wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOXTEXT);
     attr.colBg = wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOX);
     attr.font  = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
     return attr;
     attr.colBg = wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOX);
     attr.font  = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
     return attr;