]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/listctrl.cpp
Fix wchar_t with int comparisons for Apple gcc.
[wxWidgets.git] / src / generic / listctrl.cpp
index a0a2e38abae791e7d7634aad61dab4e01badaf22..4ce0960f73534b1b4e3bca3ade6fd75b05847cf8 100644 (file)
@@ -24,7 +24,6 @@
 #if wxUSE_LISTCTRL
 
 #include "wx/listctrl.h"
-#include "wx/generic/private/listctrl.h"
 
 #if ((!defined(__WXMSW__) && !(defined(__WXMAC__) && wxOSX_USE_CARBON)) || defined(__WXUNIVERSAL__))
     // if we have a native version, its implementation file does all this
 
 #include "wx/imaglist.h"
 #include "wx/renderer.h"
+#include "wx/generic/private/listctrl.h"
 
 #ifdef __WXMAC__
     #include "wx/osx/private.h"
-    // for themeing support
-    #include <Carbon/Carbon.h>
 #endif
 
+#if defined(__WXMSW__) && !defined(__WXWINCE__) && !defined(__WXUNIVERSAL__)
+    #define "wx/msw/wrapwin.h"
+#endif
 
 // NOTE: If using the wxListBox visual attributes works everywhere then this can
 // be removed, as well as the #else case below.
@@ -188,7 +189,7 @@ void wxListItemData::SetItem( const wxListItem &info )
 
 void wxListItemData::SetPosition( int x, int y )
 {
-    wxCHECK_RET( m_rect, _T("unexpected SetPosition() call") );
+    wxCHECK_RET( m_rect, wxT("unexpected SetPosition() call") );
 
     m_rect->x = x;
     m_rect->y = y;
@@ -196,7 +197,7 @@ void wxListItemData::SetPosition( int x, int y )
 
 void wxListItemData::SetSize( int width, int height )
 {
-    wxCHECK_RET( m_rect, _T("unexpected SetSize() call") );
+    wxCHECK_RET( m_rect, wxT("unexpected SetSize() call") );
 
     if ( width != -1 )
         m_rect->width = width;
@@ -206,35 +207,35 @@ void wxListItemData::SetSize( int width, int height )
 
 bool wxListItemData::IsHit( int x, int y ) const
 {
-    wxCHECK_MSG( m_rect, false, _T("can't be called in this mode") );
+    wxCHECK_MSG( m_rect, false, wxT("can't be called in this mode") );
 
     return wxRect(GetX(), GetY(), GetWidth(), GetHeight()).Contains(x, y);
 }
 
 int wxListItemData::GetX() const
 {
-    wxCHECK_MSG( m_rect, 0, _T("can't be called in this mode") );
+    wxCHECK_MSG( m_rect, 0, wxT("can't be called in this mode") );
 
     return m_rect->x;
 }
 
 int wxListItemData::GetY() const
 {
-    wxCHECK_MSG( m_rect, 0, _T("can't be called in this mode") );
+    wxCHECK_MSG( m_rect, 0, wxT("can't be called in this mode") );
 
     return m_rect->y;
 }
 
 int wxListItemData::GetWidth() const
 {
-    wxCHECK_MSG( m_rect, 0, _T("can't be called in this mode") );
+    wxCHECK_MSG( m_rect, 0, wxT("can't be called in this mode") );
 
     return m_rect->width;
 }
 
 int wxListItemData::GetHeight() const
 {
-    wxCHECK_MSG( m_rect, 0, _T("can't be called in this mode") );
+    wxCHECK_MSG( m_rect, 0, wxT("can't be called in this mode") );
 
     return m_rect->height;
 }
@@ -414,7 +415,7 @@ wxListLineData::wxListLineData( wxListMainWindow *owner )
 void wxListLineData::CalculateSize( wxDC *dc, int spacing )
 {
     wxListItemDataList::compatibility_iterator node = m_items.GetFirst();
-    wxCHECK_RET( node, _T("no subitems at all??") );
+    wxCHECK_RET( node, wxT("no subitems at all??") );
 
     wxListItemData *item = node->GetData();
 
@@ -504,11 +505,11 @@ void wxListLineData::CalculateSize( wxDC *dc, int spacing )
             break;
 
         case wxLC_REPORT:
-            wxFAIL_MSG( _T("unexpected call to SetSize") );
+            wxFAIL_MSG( wxT("unexpected call to SetSize") );
             break;
 
         default:
-            wxFAIL_MSG( _T("unknown mode") );
+            wxFAIL_MSG( wxT("unknown mode") );
             break;
     }
 }
@@ -516,7 +517,7 @@ void wxListLineData::CalculateSize( wxDC *dc, int spacing )
 void wxListLineData::SetPosition( int x, int y, int spacing )
 {
     wxListItemDataList::compatibility_iterator node = m_items.GetFirst();
-    wxCHECK_RET( node, _T("no subitems at all??") );
+    wxCHECK_RET( node, wxT("no subitems at all??") );
 
     wxListItemData *item = node->GetData();
 
@@ -572,11 +573,11 @@ void wxListLineData::SetPosition( int x, int y, int spacing )
             break;
 
         case wxLC_REPORT:
-            wxFAIL_MSG( _T("unexpected call to SetPosition") );
+            wxFAIL_MSG( wxT("unexpected call to SetPosition") );
             break;
 
         default:
-            wxFAIL_MSG( _T("unknown mode") );
+            wxFAIL_MSG( wxT("unknown mode") );
             break;
     }
 }
@@ -590,7 +591,7 @@ void wxListLineData::InitItems( int num )
 void wxListLineData::SetItem( int index, const wxListItem &info )
 {
     wxListItemDataList::compatibility_iterator node = m_items.Item( index );
-    wxCHECK_RET( node, _T("invalid column index in SetItem") );
+    wxCHECK_RET( node, wxT("invalid column index in SetItem") );
 
     wxListItemData *item = node->GetData();
     item->SetItem( info );
@@ -633,7 +634,7 @@ void wxListLineData::SetText( int index, const wxString& s )
 void wxListLineData::SetImage( int index, int image )
 {
     wxListItemDataList::compatibility_iterator node = m_items.Item( index );
-    wxCHECK_RET( node, _T("invalid column index in SetImage()") );
+    wxCHECK_RET( node, wxT("invalid column index in SetImage()") );
 
     wxListItemData *item = node->GetData();
     item->SetImage(image);
@@ -642,7 +643,7 @@ void wxListLineData::SetImage( int index, int image )
 int wxListLineData::GetImage( int index ) const
 {
     wxListItemDataList::compatibility_iterator node = m_items.Item( index );
-    wxCHECK_MSG( node, -1, _T("invalid column index in GetImage()") );
+    wxCHECK_MSG( node, -1, wxT("invalid column index in GetImage()") );
 
     wxListItemData *item = node->GetData();
     return item->GetImage();
@@ -651,7 +652,7 @@ int wxListLineData::GetImage( int index ) const
 wxListItemAttr *wxListLineData::GetAttr() const
 {
     wxListItemDataList::compatibility_iterator node = m_items.GetFirst();
-    wxCHECK_MSG( node, NULL, _T("invalid column index in GetAttr()") );
+    wxCHECK_MSG( node, NULL, wxT("invalid column index in GetAttr()") );
 
     wxListItemData *item = node->GetData();
     return item->GetAttr();
@@ -660,17 +661,26 @@ wxListItemAttr *wxListLineData::GetAttr() const
 void wxListLineData::SetAttr(wxListItemAttr *attr)
 {
     wxListItemDataList::compatibility_iterator node = m_items.GetFirst();
-    wxCHECK_RET( node, _T("invalid column index in SetAttr()") );
+    wxCHECK_RET( node, wxT("invalid column index in SetAttr()") );
 
     wxListItemData *item = node->GetData();
     item->SetAttr(attr);
 }
 
-bool wxListLineData::SetAttributes(wxDC *dc,
-                                   const wxListItemAttr *attr,
-                                   bool highlighted)
+void wxListLineData::ApplyAttributes(wxDC *dc,
+                                     const wxRect& rectHL,
+                                     bool highlighted,
+                                     bool current)
 {
-    wxWindow *listctrl = m_owner->GetParent();
+    const wxListItemAttr * const attr = GetAttr();
+
+    wxWindow * const listctrl = m_owner->GetParent();
+
+    const bool hasFocus = listctrl->HasFocus()
+#if defined(__WXMAC__) && !defined(__WXUNIVERSAL__) && wxOSX_USE_CARBON
+                && IsControlActive( (ControlRef)listctrl->GetHandle() )
+#endif
+                ;
 
     // fg colour
 
@@ -679,20 +689,16 @@ bool wxListLineData::SetAttributes(wxDC *dc,
     // arithmetics on wxColour, unfortunately)
     wxColour colText;
     if ( highlighted )
-#ifdef __WXMAC__
     {
-        if (m_owner->HasFocus()
-#if !defined(__WXUNIVERSAL__) && wxOSX_USE_CARBON
-                && IsControlActive( (ControlRef)m_owner->GetHandle() )
-#endif
-        )
+#ifdef __WXMAC__
+        if ( hasFocus )
             colText = *wxWHITE;
         else
             colText = *wxBLACK;
-    }
 #else
         colText = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT);
 #endif
+    }
     else if ( attr && attr->HasTextColour() )
         colText = attr->GetTextColour();
     else
@@ -709,57 +715,26 @@ bool wxListLineData::SetAttributes(wxDC *dc,
 
     dc->SetFont(font);
 
-    // bg colour
-    bool hasBgCol = attr && attr->HasBackgroundColour();
-    if ( highlighted || hasBgCol )
-    {
-        if ( highlighted )
-            dc->SetBrush( *m_owner->GetHighlightBrush() );
-        else
-            dc->SetBrush(wxBrush(attr->GetBackgroundColour(), wxBRUSHSTYLE_SOLID));
-
-        dc->SetPen( *wxTRANSPARENT_PEN );
-
-        return true;
-    }
-
-    return false;
-}
-
-void wxListLineData::Draw( wxDC *dc )
-{
-    wxListItemDataList::compatibility_iterator node = m_items.GetFirst();
-    wxCHECK_RET( node, _T("no subitems at all??") );
-
-    bool highlighted = IsHighlighted();
-
-    wxListItemAttr *attr = GetAttr();
-
-    if ( SetAttributes(dc, attr, highlighted) )
-#if ( !defined(__WXGTK20__) && !defined(__WXMAC__) )
+    // background
+    if ( highlighted )
     {
-        dc->DrawRectangle( m_gi->m_rectHighlight );
+        // Use the renderer method to ensure that the selected items use the
+        // native look.
+        int flags = wxCONTROL_SELECTED;
+        if ( hasFocus )
+            flags |= wxCONTROL_FOCUSED;
+        if (current)
+           flags |= wxCONTROL_CURRENT;
+        wxRendererNative::Get().
+            DrawItemSelectionRect( m_owner, *dc, rectHL, flags );
     }
-#else
+    else if ( attr && attr->HasBackgroundColour() )
     {
-        if (highlighted)
-        {
-            int flags = wxCONTROL_SELECTED;
-            if (m_owner->HasFocus()
-#if defined( __WXMAC__ ) && !defined(__WXUNIVERSAL__) && wxOSX_USE_CARBON
-                && IsControlActive( (ControlRef)m_owner->GetHandle() )
-#endif
-            )
-                flags |= wxCONTROL_FOCUSED;
-            wxRendererNative::Get().DrawItemSelectionRect( m_owner, *dc, m_gi->m_rectHighlight, flags );
-
-        }
-        else
-        {
-            dc->DrawRectangle( m_gi->m_rectHighlight );
-        }
+        // Draw the background using the items custom background colour.
+        dc->SetBrush(attr->GetBackgroundColour());
+        dc->SetPen(*wxTRANSPARENT_PEN);
+        dc->DrawRectangle(rectHL);
     }
-#endif
 
     // just for debugging to better see where the items are
 #if 0
@@ -769,6 +744,14 @@ void wxListLineData::Draw( wxDC *dc )
     dc->SetPen(*wxGREEN_PEN);
     dc->DrawRectangle( m_gi->m_rectIcon );
 #endif
+}
+
+void wxListLineData::Draw(wxDC *dc, bool current)
+{
+    wxListItemDataList::compatibility_iterator node = m_items.GetFirst();
+    wxCHECK_RET( node, wxT("no subitems at all??") );
+
+    ApplyAttributes(dc, m_gi->m_rectHighlight, IsHighlighted(), current);
 
     wxListItemData *item = node->GetData();
     if (item->HasImage())
@@ -798,29 +781,8 @@ void wxListLineData::DrawInReportMode( wxDC *dc,
     // TODO: later we should support setting different attributes for
     //       different columns - to do it, just add "col" argument to
     //       GetAttr() and move these lines into the loop below
-    wxListItemAttr *attr = GetAttr();
-    if ( SetAttributes(dc, attr, highlighted) )
-#if ( !defined(__WXGTK20__) && !defined(__WXMAC__) )
-    {
-        dc->DrawRectangle( rectHL );
-    }
-#else
-    {
-        if (highlighted)
-        {
-            int flags = wxCONTROL_SELECTED;
-            if (m_owner->HasFocus())
-                flags |= wxCONTROL_FOCUSED;
-            if (current)
-               flags |= wxCONTROL_CURRENT;
-            wxRendererNative::Get().DrawItemSelectionRect( m_owner, *dc, rectHL, flags );
-        }
-        else
-        {
-            dc->DrawRectangle( rectHL );
-        }
-    }
-#endif
+
+    ApplyAttributes(dc, rectHL, highlighted, current);
 
     wxCoord x = rect.x + HEADER_OFFSET_X,
             yMid = rect.y + rect.height/2;
@@ -872,7 +834,7 @@ void wxListLineData::DrawTextFormatted(wxDC *dc,
     // we don't support displaying multiple lines currently (and neither does
     // wxMSW FWIW) so just merge all the lines
     wxString text(textOrig);
-    text.Replace(_T("\n"), _T(" "));
+    text.Replace(wxT("\n"), wxT(" "));
 
     wxCoord w, h;
     dc->GetTextExtent(text, &w, &h);
@@ -902,7 +864,7 @@ void wxListLineData::DrawTextFormatted(wxDC *dc,
                 break;
 
             default:
-                wxFAIL_MSG( _T("unknown list item format") );
+                wxFAIL_MSG( wxT("unknown list item format") );
                 break;
         }
 
@@ -944,7 +906,7 @@ void wxListLineData::DrawTextFormatted(wxDC *dc,
 
 bool wxListLineData::Highlight( bool on )
 {
-    wxCHECK_MSG( !IsVirtual(), false, _T("unexpected call to Highlight") );
+    wxCHECK_MSG( !IsVirtual(), false, wxT("unexpected call to Highlight") );
 
     if ( on == m_highlighted )
         return false;
@@ -1139,7 +1101,7 @@ void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
         switch ( wLabel < cw ? item.GetAlign() : wxLIST_FORMAT_LEFT )
         {
             default:
-                wxFAIL_MSG( _T("unknown list item format") );
+                wxFAIL_MSG( wxT("unknown list item format") );
                 // fall through
 
             case wxLIST_FORMAT_LEFT:
@@ -1157,7 +1119,7 @@ void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
 
         // draw the text and image clipping them so that they
         // don't overwrite the column boundary
-        wxDCClipper clipper(dc, x, HEADER_OFFSET_Y, cw, h - 4 );
+        wxDCClipper clipper(dc, x, HEADER_OFFSET_Y, cw, h);
 
         // if we have an image, draw it on the right of the label
         if ( imageList )
@@ -1167,13 +1129,13 @@ void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
                         image,
                         dc,
                         xAligned + wLabel - ix - HEADER_IMAGE_MARGIN_IN_REPORT_MODE,
-                        HEADER_OFFSET_Y + (h - 4 - iy)/2,
+                        HEADER_OFFSET_Y + (h - iy)/2,
                         wxIMAGELIST_DRAW_TRANSPARENT
                        );
         }
 
         dc.DrawText( item.GetText(),
-                     xAligned + EXTRA_WIDTH, h / 2 - hLabel / 2 ); //HEADER_OFFSET_Y + EXTRA_HEIGHT );
+                     xAligned + EXTRA_WIDTH, (h - hLabel) / 2 );
 
         x += wCol;
     }
@@ -1222,7 +1184,7 @@ void wxListHeaderWindow::DrawCurrent()
 
     wxScreenDC dc;
     dc.SetLogicalFunction( wxINVERT );
-    dc.SetPen( wxPen( *wxBLACK, 2, wxSOLID ) );
+    dc.SetPen( wxPen(*wxBLACK, 2) );
     dc.SetBrush( *wxTRANSPARENT_BRUSH );
 
     AdjustDC(dc);
@@ -1521,7 +1483,7 @@ void wxListTextCtrlWrapper::OnKeyUp( wxKeyEvent &event )
         wxPoint myPos = m_text->GetPosition();
         wxSize mySize = m_text->GetSize();
         int sx, sy;
-        m_text->GetTextExtent(m_text->GetValue() + _T("MM"), &sx, &sy);
+        m_text->GetTextExtent(m_text->GetValue() + wxT("MM"), &sx, &sy);
         if (myPos.x + sx > parentSize.x)
             sx = parentSize.x - myPos.x;
        if (mySize.x > sx)
@@ -1550,7 +1512,7 @@ void wxListTextCtrlWrapper::OnKillFocus( wxFocusEvent &event )
 //  wxListMainWindow
 //-----------------------------------------------------------------------------
 
-BEGIN_EVENT_TABLE(wxListMainWindow,wxScrolledCanvas)
+BEGIN_EVENT_TABLE(wxListMainWindow, wxWindow)
   EVT_PAINT          (wxListMainWindow::OnPaint)
   EVT_MOUSE_EVENTS   (wxListMainWindow::OnMouse)
   EVT_CHAR           (wxListMainWindow::OnChar)
@@ -1647,6 +1609,15 @@ wxListMainWindow::~wxListMainWindow()
     delete m_renameTimer;
 }
 
+void wxListMainWindow::SetReportView(bool inReportView)
+{
+    const size_t count = m_lines.size();
+    for ( size_t n = 0; n < count; n++ )
+    {
+        m_lines[n].SetReportView(inReportView);
+    }
+}
+
 void wxListMainWindow::CacheLineData(size_t line)
 {
     wxGenericListCtrl *listctrl = GetListCtrl();
@@ -1665,8 +1636,8 @@ void wxListMainWindow::CacheLineData(size_t line)
 
 wxListLineData *wxListMainWindow::GetDummyLine() const
 {
-    wxASSERT_MSG( !IsEmpty(), _T("invalid line index") );
-    wxASSERT_MSG( IsVirtual(), _T("GetDummyLine() shouldn't be called") );
+    wxASSERT_MSG( !IsEmpty(), wxT("invalid line index") );
+    wxASSERT_MSG( IsVirtual(), wxT("GetDummyLine() shouldn't be called") );
 
     wxListMainWindow *self = wxConstCast(this, wxListMainWindow);
 
@@ -1707,7 +1678,7 @@ wxCoord wxListMainWindow::GetLineHeight() const
         dc.SetFont( GetFont() );
 
         wxCoord y;
-        dc.GetTextExtent(_T("H"), NULL, &y);
+        dc.GetTextExtent(wxT("H"), NULL, &y);
 
         if ( m_small_image_list && m_small_image_list->GetImageCount() )
         {
@@ -1725,7 +1696,7 @@ wxCoord wxListMainWindow::GetLineHeight() const
 
 wxCoord wxListMainWindow::GetLineY(size_t line) const
 {
-    wxASSERT_MSG( InReportView(), _T("only works in report mode") );
+    wxASSERT_MSG( InReportView(), wxT("only works in report mode") );
 
     return LINE_SPACING + line * GetLineHeight();
 }
@@ -1778,7 +1749,7 @@ wxRect wxListMainWindow::GetLineIconRect(size_t line) const
         return GetLine(line)->m_gi->m_rectIcon;
 
     wxListLineData *ld = GetLine(line);
-    wxASSERT_MSG( ld->HasImage(), _T("should have an image") );
+    wxASSERT_MSG( ld->HasImage(), wxT("should have an image") );
 
     wxRect rect;
     rect.x = HEADER_OFFSET_X;
@@ -1796,7 +1767,7 @@ wxRect wxListMainWindow::GetLineHighlightRect(size_t line) const
 
 long wxListMainWindow::HitTestLine(size_t line, int x, int y) const
 {
-    wxASSERT_MSG( line < GetItemCount(), _T("invalid line in HitTestLine") );
+    wxASSERT_MSG( line < GetItemCount(), wxT("invalid line in HitTestLine") );
 
     wxListLineData *ld = GetLine(line);
 
@@ -1831,7 +1802,7 @@ bool wxListMainWindow::IsHighlighted(size_t line) const
     else // !virtual
     {
         wxListLineData *ld = GetLine(line);
-        wxCHECK_MSG( ld, false, _T("invalid index in IsHighlighted") );
+        wxCHECK_MSG( ld, false, wxT("invalid index in IsHighlighted") );
 
         return ld->IsHighlighted();
     }
@@ -1880,7 +1851,7 @@ bool wxListMainWindow::HighlightLine( size_t line, bool highlight )
     else // !virtual
     {
         wxListLineData *ld = GetLine(line);
-        wxCHECK_MSG( ld, false, _T("invalid index in HighlightLine") );
+        wxCHECK_MSG( ld, false, wxT("invalid index in HighlightLine") );
 
         changed = ld->Highlight(highlight);
     }
@@ -1914,9 +1885,9 @@ void wxListMainWindow::RefreshLine( size_t line )
 void wxListMainWindow::RefreshLines( size_t lineFrom, size_t lineTo )
 {
     // we suppose that they are ordered by caller
-    wxASSERT_MSG( lineFrom <= lineTo, _T("indices in disorder") );
+    wxASSERT_MSG( lineFrom <= lineTo, wxT("indices in disorder") );
 
-    wxASSERT_MSG( lineTo < GetItemCount(), _T("invalid line range") );
+    wxASSERT_MSG( lineTo < GetItemCount(), wxT("invalid line range") );
 
     if ( InReportView() )
     {
@@ -2122,31 +2093,31 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
         size_t count = GetItemCount();
         for ( size_t i = 0; i < count; i++ )
         {
-            GetLine(i)->Draw( &dc );
+            GetLine(i)->Draw( &dc, i == m_current );
         }
     }
 
-#if !defined( __WXMAC__) && !defined(__WXGTK20__)
-    // Don't draw rect outline under Mac at all.
-    // Draw it elsewhere under GTK.
+    // DrawFocusRect() is unusable under Mac, it draws outside of the highlight
+    // rectangle somehow and so leaves traces when the item is not selected any
+    // more, see #12229.
+#ifndef __WXMAC__
     if ( HasCurrent() )
     {
-        if ( m_hasFocus )
-        {
-            wxRect rect( GetLineHighlightRect( m_current ) );
-            dc.SetPen( *wxBLACK_PEN );
-            dc.SetBrush( *wxTRANSPARENT_BRUSH );
-            dc.DrawRectangle( rect );
-        }
+        int flags = 0;
+        if ( IsHighlighted(m_current) )
+            flags |= wxCONTROL_SELECTED;
+
+        wxRendererNative::Get().
+            DrawFocusRect(this, dc, GetLineHighlightRect(m_current), flags);
     }
-#endif
+#endif // !__WXMAC__
 }
 
 void wxListMainWindow::HighlightAll( bool on )
 {
     if ( IsSingleSel() )
     {
-        wxASSERT_MSG( !on, _T("can't do this in a single selection control") );
+        wxASSERT_MSG( !on, wxT("can't do this in a single selection control") );
 
         // we just have one item to turn off
         if ( HasCurrent() && IsHighlighted(m_current) )
@@ -2225,7 +2196,7 @@ wxTextCtrl *wxListMainWindow::EditLabel(long item, wxClassInfo* textControlClass
     le.SetEventObject( GetParent() );
     le.m_itemIndex = item;
     wxListLineData *data = GetLine(itemEdit);
-    wxCHECK_MSG( data, NULL, _T("invalid index in EditLabel()") );
+    wxCHECK_MSG( data, NULL, wxT("invalid index in EditLabel()") );
     data->GetItem( 0, le.m_item );
 
     if ( GetParent()->GetEventHandler()->ProcessEvent( le ) && !le.IsAllowed() )
@@ -2238,6 +2209,9 @@ wxTextCtrl *wxListMainWindow::EditLabel(long item, wxClassInfo* textControlClass
     // been added and no screen update taken place.
     if ( m_dirty )
     {
+        // TODO: use wxTheApp->SafeYieldFor(NULL, wxEVT_CATEGORY_UI) instead
+        //       so that no pending events may change the item count (see below)
+        //       IMPORTANT: needs to be tested!
         wxSafeYield();
 
         // Pending events dispatched by wxSafeYield might have changed the item
@@ -2266,7 +2240,7 @@ bool wxListMainWindow::OnRenameAccept(size_t itemEdit, const wxString& value)
 
     wxListLineData *data = GetLine(itemEdit);
 
-    wxCHECK_MSG( data, false, _T("invalid index in OnRenameAccept()") );
+    wxCHECK_MSG( data, false, wxT("invalid index in OnRenameAccept()") );
 
     data->GetItem( 0, le.m_item );
     le.m_item.m_text = value;
@@ -2285,7 +2259,7 @@ void wxListMainWindow::OnRenameCancelled(size_t itemEdit)
     le.m_itemIndex = itemEdit;
 
     wxListLineData *data = GetLine(itemEdit);
-    wxCHECK_RET( data, _T("invalid index in OnRenameCancelled()") );
+    wxCHECK_RET( data, wxT("invalid index in OnRenameCancelled()") );
 
     data->GetItem( 0, le.m_item );
     GetEventHandler()->ProcessEvent( le );
@@ -2293,7 +2267,6 @@ void wxListMainWindow::OnRenameCancelled(size_t itemEdit)
 
 void wxListMainWindow::OnMouse( wxMouseEvent &event )
 {
-
 #ifdef __WXMAC__
     // On wxMac we can't depend on the EVT_KILL_FOCUS event to properly
     // shutdown the edit control when the mouse is clicked elsewhere on the
@@ -2312,7 +2285,7 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event )
 
     if (event.GetEventType() == wxEVT_MOUSEWHEEL)
     {
-        // let the base handle mouse wheel events.
+        // let the base class handle mouse wheel events.
         event.Skip();
         return;
     }
@@ -2323,10 +2296,9 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event )
         {
             SendNotify( (size_t)-1, wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK, event.GetPosition() );
 
-            wxContextMenuEvent evtCtx(
-                wxEVT_CONTEXT_MENU,
-                GetParent()->GetId(),
-                ClientToScreen(event.GetPosition()));
+            wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU,
+                                      GetParent()->GetId(),
+                                      ClientToScreen(event.GetPosition()));
             evtCtx.SetEventObject(GetParent());
             GetParent()->GetEventHandler()->ProcessEvent(evtCtx);
         }
@@ -2553,7 +2525,7 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event )
             else // !ctrl, !shift
             {
                 // test in the enclosing if should make it impossible
-                wxFAIL_MSG( _T("how did we get here?") );
+                wxFAIL_MSG( wxT("how did we get here?") );
             }
         }
 
@@ -2577,8 +2549,8 @@ void wxListMainWindow::MoveToItem(size_t item)
 
     const int hLine = GetLineHeight();
 
-    int view_x = SCROLL_UNIT_X * GetScrollPos( wxHORIZONTAL );
-    int view_y = hLine * GetScrollPos( wxVERTICAL );
+    int view_x = SCROLL_UNIT_X * GetListCtrl()->GetScrollPos( wxHORIZONTAL );
+    int view_y = hLine * GetListCtrl()->GetScrollPos( wxVERTICAL );
 
     if ( InReportView() )
     {
@@ -2656,7 +2628,7 @@ bool wxListMainWindow::ScrollList(int WXUNUSED(dx), int dy)
 void wxListMainWindow::OnArrowChar(size_t newCurrent, const wxKeyEvent& event)
 {
     wxCHECK_RET( newCurrent < (size_t)GetItemCount(),
-                 _T("invalid item index in OnArrowChar()") );
+                 wxT("invalid item index in OnArrowChar()") );
 
     size_t oldCurrent = m_current;
 
@@ -2710,6 +2682,16 @@ void wxListMainWindow::OnKeyDown( wxKeyEvent &event )
     if (parent->GetEventHandler()->ProcessEvent( ke ))
         return;
 
+    // send a list event
+    wxListEvent le( wxEVT_COMMAND_LIST_KEY_DOWN, parent->GetId() );
+    le.m_itemIndex = m_current;
+    if (HasCurrent())
+        GetLine(m_current)->GetItem( 0, le.m_item );
+    le.m_code = event.GetKeyCode();
+    le.SetEventObject( parent );
+    if (parent->GetEventHandler()->ProcessEvent( le ))
+        return;
+
     event.Skip();
 }
 
@@ -2729,32 +2711,11 @@ void wxListMainWindow::OnChar( wxKeyEvent &event )
 {
     wxWindow *parent = GetParent();
 
-    // send a list_key event up
-    if ( HasCurrent() )
-    {
-        wxListEvent le( wxEVT_COMMAND_LIST_KEY_DOWN, GetParent()->GetId() );
-        le.m_itemIndex = m_current;
-        GetLine(m_current)->GetItem( 0, le.m_item );
-        le.m_code = event.GetKeyCode();
-        le.SetEventObject( parent );
-        parent->GetEventHandler()->ProcessEvent( le );
-    }
-
-    if ( (event.GetKeyCode() != WXK_UP) &&
-         (event.GetKeyCode() != WXK_DOWN) &&
-         (event.GetKeyCode() != WXK_RIGHT) &&
-         (event.GetKeyCode() != WXK_LEFT) &&
-         (event.GetKeyCode() != WXK_PAGEUP) &&
-         (event.GetKeyCode() != WXK_PAGEDOWN) &&
-         (event.GetKeyCode() != WXK_END) &&
-         (event.GetKeyCode() != WXK_HOME) )
-    {
-        // propagate the char event upwards
-        wxKeyEvent ke(event);
-        ke.SetEventObject( parent );
-        if (parent->GetEventHandler()->ProcessEvent( ke ))
-            return;
-    }
+    // propagate the char event upwards
+    wxKeyEvent ke(event);
+    ke.SetEventObject( parent );
+    if (parent->GetEventHandler()->ProcessEvent( ke ))
+        return;
 
     if ( HandleAsNavigationKey(event) )
         return;
@@ -2768,7 +2729,7 @@ void wxListMainWindow::OnChar( wxKeyEvent &event )
 
     // don't use m_linesPerPage directly as it might not be computed yet
     const int pageSize = GetCountPerPage();
-    wxCHECK_RET( pageSize, _T("should have non zero page size") );
+    wxCHECK_RET( pageSize, wxT("should have non zero page size") );
 
     if (GetLayoutDirection() == wxLayout_RightToLeft)
     {
@@ -3022,7 +2983,7 @@ void wxListMainWindow::SetColumn( int col, wxListItem &item )
 {
     wxListHeaderDataList::compatibility_iterator node = m_columns.Item( col );
 
-    wxCHECK_RET( node, _T("invalid column index in SetColumn") );
+    wxCHECK_RET( node, wxT("invalid column index in SetColumn") );
 
     if ( item.m_width == wxLIST_AUTOSIZE_USEHEADER )
         item.m_width = GetTextLength( item.m_text );
@@ -3043,10 +3004,10 @@ void wxListMainWindow::SetColumn( int col, wxListItem &item )
 void wxListMainWindow::SetColumnWidth( int col, int width )
 {
     wxCHECK_RET( col >= 0 && col < GetColumnCount(),
-                 _T("invalid column index") );
+                 wxT("invalid column index") );
 
     wxCHECK_RET( InReportView(),
-                 _T("SetColumnWidth() can only be called in report mode.") );
+                 wxT("SetColumnWidth() can only be called in report mode.") );
 
     m_dirty = true;
 
@@ -3055,7 +3016,7 @@ void wxListMainWindow::SetColumnWidth( int col, int width )
         headerWin->m_dirty = true;
 
     wxListHeaderDataList::compatibility_iterator node = m_columns.Item( col );
-    wxCHECK_RET( node, _T("no column?") );
+    wxCHECK_RET( node, wxT("no column?") );
 
     wxListHeaderData *column = node->GetData();
 
@@ -3100,7 +3061,7 @@ void wxListMainWindow::SetColumnWidth( int col, int width )
                     wxListLineData *line = GetLine( i );
                     wxListItemDataList::compatibility_iterator n = line->m_items.Item( col );
 
-                    wxCHECK_RET( n, _T("no subitem?") );
+                    wxCHECK_RET( n, wxT("no subitem?") );
 
                     wxListItemData *itemData = n->GetData();
                     wxListItem      item;
@@ -3145,7 +3106,7 @@ int wxListMainWindow::GetHeaderWidth() const
 void wxListMainWindow::GetColumn( int col, wxListItem &item ) const
 {
     wxListHeaderDataList::compatibility_iterator node = m_columns.Item( col );
-    wxCHECK_RET( node, _T("invalid column index in GetColumn") );
+    wxCHECK_RET( node, wxT("invalid column index in GetColumn") );
 
     wxListHeaderData *column = node->GetData();
     column->GetItem( item );
@@ -3154,7 +3115,7 @@ void wxListMainWindow::GetColumn( int col, wxListItem &item ) const
 int wxListMainWindow::GetColumnWidth( int col ) const
 {
     wxListHeaderDataList::compatibility_iterator node = m_columns.Item( col );
-    wxCHECK_MSG( node, 0, _T("invalid column index") );
+    wxCHECK_MSG( node, 0, wxT("invalid column index") );
 
     wxListHeaderData *column = node->GetData();
     return column->GetWidth();
@@ -3168,7 +3129,7 @@ void wxListMainWindow::SetItem( wxListItem &item )
 {
     long id = item.m_itemId;
     wxCHECK_RET( id >= 0 && (size_t)id < GetItemCount(),
-                 _T("invalid item index in SetItem") );
+                 wxT("invalid item index in SetItem") );
 
     if ( !IsVirtual() )
     {
@@ -3248,7 +3209,7 @@ void wxListMainWindow::SetItemState( long litem, long state, long stateMask )
     }
 
     wxCHECK_RET( litem >= 0 && (size_t)litem < GetItemCount(),
-                 _T("invalid list ctrl item index in SetItem") );
+                 wxT("invalid list ctrl item index in SetItem") );
 
     size_t oldCurrent = m_current;
     size_t item = (size_t)litem;    // safe because of the check above
@@ -3336,7 +3297,7 @@ void wxListMainWindow::SetItemState( long litem, long state, long stateMask )
 int wxListMainWindow::GetItemState( long item, long stateMask ) const
 {
     wxCHECK_MSG( item >= 0 && (size_t)item < GetItemCount(), 0,
-                 _T("invalid list ctrl item index in GetItemState()") );
+                 wxT("invalid list ctrl item index in GetItemState()") );
 
     int ret = wxLIST_STATE_DONTCARE;
 
@@ -3358,7 +3319,7 @@ int wxListMainWindow::GetItemState( long item, long stateMask ) const
 void wxListMainWindow::GetItem( wxListItem &item ) const
 {
     wxCHECK_RET( item.m_itemId >= 0 && (size_t)item.m_itemId < GetItemCount(),
-                 _T("invalid item index in GetItem") );
+                 wxT("invalid item index in GetItem") );
 
     wxListLineData *line = GetLine((size_t)item.m_itemId);
     line->GetItem( item.m_col, item );
@@ -3460,9 +3421,9 @@ wxListMainWindow::GetSubItemRect(long item, long subItem, wxRect& rect) const
 {
     wxCHECK_MSG( subItem == wxLIST_GETSUBITEMRECT_WHOLEITEM || InReportView(),
                  false,
-                 _T("GetSubItemRect only meaningful in report view") );
+                 wxT("GetSubItemRect only meaningful in report view") );
     wxCHECK_MSG( item >= 0 && (size_t)item < GetItemCount(), false,
-                 _T("invalid item in GetSubItemRect") );
+                 wxT("invalid item in GetSubItemRect") );
 
     // ensure that we're laid out, otherwise we could return nonsense
     if ( m_dirty )
@@ -3477,7 +3438,7 @@ wxListMainWindow::GetSubItemRect(long item, long subItem, wxRect& rect) const
     if ( subItem != wxLIST_GETSUBITEMRECT_WHOLEITEM )
     {
         wxCHECK_MSG( subItem >= 0 && subItem < GetColumnCount(), false,
-                     _T("invalid subItem in GetSubItemRect") );
+                     wxT("invalid subItem in GetSubItemRect") );
 
         for (int i = 0; i < subItem; i++)
         {
@@ -3734,7 +3695,7 @@ long wxListMainWindow::GetNextItem( long item,
     long ret = item,
          max = GetItemCount();
     wxCHECK_MSG( (ret == -1) || (ret < max), -1,
-                 _T("invalid listctrl index in GetNextItem()") );
+                 wxT("invalid listctrl index in GetNextItem()") );
 
     // notice that we start with the next item (or the first one if item == -1)
     // and this is intentional to allow writing a simple loop to iterate over
@@ -3771,7 +3732,7 @@ void wxListMainWindow::DeleteItem( long lindex )
     size_t count = GetItemCount();
 
     wxCHECK_RET( (lindex >= 0) && ((size_t)lindex < count),
-                 _T("invalid item index in DeleteItem") );
+                 wxT("invalid item index in DeleteItem") );
 
     size_t index = (size_t)lindex;
 
@@ -3917,7 +3878,7 @@ void wxListMainWindow::DeleteEverything()
 void wxListMainWindow::EnsureVisible( long index )
 {
     wxCHECK_RET( index >= 0 && (size_t)index < GetItemCount(),
-                 _T("invalid index in EnsureVisible") );
+                 wxT("invalid index in EnsureVisible") );
 
     // We have to call this here because the label in question might just have
     // been added and its position is not known yet
@@ -4030,10 +3991,10 @@ long wxListMainWindow::HitTest( int x, int y, int &flags ) const
 
 void wxListMainWindow::InsertItem( wxListItem &item )
 {
-    wxASSERT_MSG( !IsVirtual(), _T("can't be used with virtual control") );
+    wxASSERT_MSG( !IsVirtual(), wxT("can't be used with virtual control") );
 
     int count = GetItemCount();
-    wxCHECK_RET( item.m_itemId >= 0, _T("invalid item index") );
+    wxCHECK_RET( item.m_itemId >= 0, wxT("invalid item index") );
 
     if (item.m_itemId > count)
         item.m_itemId = count;
@@ -4046,8 +4007,11 @@ void wxListMainWindow::InsertItem( wxListItem &item )
     {
         ResetVisibleLinesRange();
 
+        const unsigned col = item.GetColumn();
+        wxCHECK_RET( col < m_aColWidths.size(), "invalid item column" );
+
         // calculate the width of the item and adjust the max column width
-        wxColWidthInfo *pWidthInfo = m_aColWidths.Item(item.GetColumn());
+        wxColWidthInfo *pWidthInfo = m_aColWidths.Item(col);
         int width = GetItemWidthWithImage(&item);
         item.SetWidth(width);
         if (width > pWidthInfo->nMaxWidth)
@@ -4146,7 +4110,7 @@ int wxListMainWindow::GetItemWidthWithImage(wxListItem * item)
 // ----------------------------------------------------------------------------
 
 static wxListCtrlCompare list_ctrl_compare_func_2;
-static long              list_ctrl_compare_data;
+static wxIntPtr          list_ctrl_compare_data;
 
 int LINKAGEMODE list_ctrl_compare_func_1( wxListLineData **arg1, wxListLineData **arg2 )
 {
@@ -4160,7 +4124,7 @@ int LINKAGEMODE list_ctrl_compare_func_1( wxListLineData **arg1, wxListLineData
     return list_ctrl_compare_func_2( data1, data2, list_ctrl_compare_data );
 }
 
-void wxListMainWindow::SortItems( wxListCtrlCompare fn, long data )
+void wxListMainWindow::SortItems( wxListCtrlCompare fn, wxIntPtr data )
 {
     // selections won't make sense any more after sorting the items so reset
     // them
@@ -4186,7 +4150,7 @@ void wxListMainWindow::OnScroll(wxScrollWinEvent& event)
     if ( event.GetOrientation() == wxHORIZONTAL && HasHeader() )
     {
         wxGenericListCtrl* lc = GetListCtrl();
-        wxCHECK_RET( lc, _T("no listctrl window?") );
+        wxCHECK_RET( lc, wxT("no listctrl window?") );
 
         if (lc->m_headerWin) // when we use wxLC_NO_HEADER, m_headerWin==NULL
         {
@@ -4209,14 +4173,14 @@ int wxListMainWindow::GetCountPerPage() const
 
 void wxListMainWindow::GetVisibleLinesRange(size_t *from, size_t *to)
 {
-    wxASSERT_MSG( InReportView(), _T("this is for report mode only") );
+    wxASSERT_MSG( InReportView(), wxT("this is for report mode only") );
 
     if ( m_lineFrom == (size_t)-1 )
     {
         size_t count = GetItemCount();
         if ( count )
         {
-            m_lineFrom = GetScrollPos(wxVERTICAL);
+            m_lineFrom = GetListCtrl()->GetScrollPos(wxVERTICAL);
 
             // this may happen if SetScrollbars() hadn't been called yet
             if ( m_lineFrom >= count )
@@ -4237,7 +4201,7 @@ void wxListMainWindow::GetVisibleLinesRange(size_t *from, size_t *to)
 
     wxASSERT_MSG( IsEmpty() ||
                   (m_lineFrom <= m_lineTo && m_lineTo < GetItemCount()),
-                  _T("GetVisibleLinesRange() returns incorrect result") );
+                  wxT("GetVisibleLinesRange() returns incorrect result") );
 
     if ( from )
         *from = m_lineFrom;
@@ -4268,7 +4232,6 @@ void wxGenericListCtrl::Init()
 
     m_mainWin = NULL;
     m_headerWin = NULL;
-    m_headerHeight = wxRendererNative::Get().GetHeaderButtonHeight(this);
 }
 
 wxGenericListCtrl::~wxGenericListCtrl()
@@ -4295,17 +4258,16 @@ void wxGenericListCtrl::CreateOrDestroyHeaderWindowAsNeeded()
                       (
                         this, wxID_ANY, m_mainWin,
                         wxPoint(0,0),
-                        wxSize(GetClientSize().x, m_headerHeight),
+                        wxSize
+                        (
+                          GetClientSize().x,
+                          wxRendererNative::Get().GetHeaderButtonHeight(this)
+                        ),
                         wxTAB_TRAVERSAL
                       );
 
-#if defined( __WXMAC__ ) && wxOSX_USE_COCOA_OR_CARBON
-        wxFont font;
-#if wxOSX_USE_ATSU_TEXT
-        font.MacCreateFromThemeFont( kThemeSmallSystemFont );
-#else
-        font.MacCreateFromUIFont( kCTFontSystemFontType );
-#endif
+#if defined( __WXMAC__ )
+        static wxFont font( wxOSX_SYSTEM_FONT_SMALL );
         m_headerWin->SetFont( font );
 #endif
 
@@ -4315,9 +4277,7 @@ void wxGenericListCtrl::CreateOrDestroyHeaderWindowAsNeeded()
     {
         GetSizer()->Detach( m_headerWin );
 
-        delete m_headerWin;
-
-        m_headerWin = NULL;
+        wxDELETE(m_headerWin);
     }
 }
 
@@ -4333,7 +4293,7 @@ bool wxGenericListCtrl::Create(wxWindow *parent,
 
     // just like in other ports, an assert will fail if the user doesn't give any type style:
     wxASSERT_MSG( (style & wxLC_MASK_TYPE),
-                  _T("wxListCtrl style should have exactly one mode bit set") );
+                  wxT("wxListCtrl style should have exactly one mode bit set") );
 
     if ( !wxControl::Create( parent, id, pos, size, style|wxVSCROLL|wxHSCROLL, validator, name ) )
         return false;
@@ -4347,6 +4307,11 @@ bool wxGenericListCtrl::Create(wxWindow *parent,
 
     SetTargetWindow( m_mainWin );
 
+    // We use the cursor keys for moving the selection, not scrolling, so call
+    // this method to ensure wxScrollHelperEvtHandler doesn't catch all
+    // keyboard events forwarded to us from wxListMainWindow.
+    DisableKeyboardScrolling();
+
     wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
     sizer->Add( m_mainWin, 1, wxGROW );
     SetSizer( sizer );
@@ -4363,24 +4328,22 @@ wxBorder wxGenericListCtrl::GetDefaultBorder() const
     return wxBORDER_THEME;
 }
 
-#ifdef __WXMSW__
+#if defined(__WXMSW__) && !defined(__WXWINCE__) && !defined(__WXUNIVERSAL__)
 WXLRESULT wxGenericListCtrl::MSWWindowProc(WXUINT nMsg,
                                        WXWPARAM wParam,
                                        WXLPARAM lParam)
 {
     WXLRESULT rc = wxControl::MSWWindowProc(nMsg, wParam, lParam);
 
-#ifndef __WXWINCE__
     // we need to process arrows ourselves for scrolling
     if ( nMsg == WM_GETDLGCODE )
     {
         rc |= DLGC_WANTARROWS;
     }
-#endif
 
     return rc;
 }
-#endif
+#endif // __WXMSW__
 
 wxSize wxGenericListCtrl::GetSizeAvailableForScrollTarget(const wxSize& size)
 {
@@ -4409,7 +4372,7 @@ void wxGenericListCtrl::OnScroll(wxScrollWinEvent& event)
 void wxGenericListCtrl::SetSingleStyle( long style, bool add )
 {
     wxASSERT_MSG( !(style & wxLC_VIRTUAL),
-                  _T("wxLC_VIRTUAL can't be [un]set") );
+                  wxT("wxLC_VIRTUAL can't be [un]set") );
 
     long flag = GetWindowStyle();
 
@@ -4443,16 +4406,33 @@ void wxGenericListCtrl::SetSingleStyle( long style, bool add )
 
 void wxGenericListCtrl::SetWindowStyleFlag( long flag )
 {
+    // we add wxHSCROLL and wxVSCROLL in ctor unconditionally and it never
+    // makes sense to remove them as we'll always add scrollbars anyhow when
+    // needed
+    flag |= wxHSCROLL | wxVSCROLL;
+
+    const bool wasInReportView = HasFlag(wxLC_REPORT);
+
+    // update the window style first so that the header is created or destroyed
+    // corresponding to the new style
+    wxWindow::SetWindowStyleFlag( flag );
+
     if (m_mainWin)
     {
+        const bool inReportView = (flag & wxLC_REPORT) != 0;
+        if ( inReportView != wasInReportView )
+        {
+            // we need to notify the main window about this change as it must
+            // update its data structures
+            m_mainWin->SetReportView(inReportView);
+        }
+
         // m_mainWin->DeleteEverything();  wxMSW doesn't do that
 
         CreateOrDestroyHeaderWindowAsNeeded();
 
         GetSizer()->Layout();
     }
-
-    wxWindow::SetWindowStyleFlag( flag );
 }
 
 bool wxGenericListCtrl::GetColumn(int col, wxListItem &item) const
@@ -4541,9 +4521,9 @@ wxGenericListCtrl::SetItemColumnImage( long item, long column, int image )
     return true;
 }
 
-wxString wxGenericListCtrl::GetItemText( long item ) const
+wxString wxGenericListCtrl::GetItemText( long item, int col ) const
 {
-    return m_mainWin->GetItemText(item);
+    return m_mainWin->GetItemText(item, col);
 }
 
 void wxGenericListCtrl::SetItemText( long item, const wxString& str )
@@ -4589,7 +4569,7 @@ bool wxGenericListCtrl::GetSubItemRect(long item,
         return false;
 
     if ( m_mainWin->HasHeader() )
-        rect.y += m_headerHeight + 1;
+        rect.y += m_headerWin->GetSize().y + 1;
 
     return true;
 }
@@ -4874,7 +4854,7 @@ long wxGenericListCtrl::InsertItem( long index, const wxString &label, int image
 
 long wxGenericListCtrl::InsertColumn( long col, wxListItem &item )
 {
-    wxCHECK_MSG( InReportView(), -1, _T("can't add column in non report mode") );
+    wxCHECK_MSG( InReportView(), -1, wxT("can't add column in non report mode") );
 
     m_mainWin->InsertColumn( col, item );
 
@@ -4918,7 +4898,7 @@ bool wxGenericListCtrl::ScrollList( int dx, int dy )
 // or zero if the two items are equivalent.
 // data is arbitrary data to be passed to the sort function.
 
-bool wxGenericListCtrl::SortItems( wxListCtrlCompare fn, long data )
+bool wxGenericListCtrl::SortItems( wxListCtrlCompare fn, wxIntPtr data )
 {
     m_mainWin->SortItems( fn, data );
     return true;
@@ -5085,12 +5065,63 @@ void wxGenericListCtrl::SetFocus()
         m_mainWin->SetFocus();
 }
 
-wxSize wxGenericListCtrl::DoGetBestSize() const
+wxSize wxGenericListCtrl::DoGetBestClientSize() const
 {
-    // Something is better than nothing...
-    // 100x80 is what the MSW version will get from the default
-    // wxControl::DoGetBestSize
-    return wxSize(100, 80);
+    // Something is better than nothing even if this is completely arbitrary.
+    wxSize sizeBest(100, 80);
+
+    if ( !InReportView() )
+    {
+        // Ensure that our minimal width is at least big enough to show all our
+        // items. This is important for wxListbook to size itself correctly.
+
+        // Remember the offset of the first item: this corresponds to the
+        // margins around the item so we will add it to the minimal size below
+        // to ensure that we have equal margins on all sides.
+        wxPoint ofs;
+
+        // We can iterate over all items as there shouldn't be too many of them
+        // in non-report view. If it ever becomes a problem, we could examine
+        // just the first few items probably, the determination of the best
+        // size is less important if we will need scrollbars anyhow.
+        for ( int n = 0; n < GetItemCount(); n++ )
+        {
+            const wxRect itemRect = m_mainWin->GetLineRect(n);
+            if ( !n )
+            {
+                // Remember the position of the first item as all the rest are
+                // offset by at least this number of pixels too.
+                ofs = itemRect.GetPosition();
+            }
+
+            sizeBest.IncTo(itemRect.GetSize());
+        }
+
+        sizeBest.IncBy(2*ofs);
+
+
+        // If we have the scrollbars we need to account for them too. And to
+        // make sure the scrollbars status is up to date we need to call this
+        // function to set them.
+        m_mainWin->RecalculatePositions(true /* no refresh */);
+
+        // Unfortunately we can't use wxWindow::HasScrollbar() here as we need
+        // to use m_mainWin client/virtual size for determination of whether we
+        // use scrollbars and not the size of this window itself. Maybe that
+        // function should be extended to work correctly in the case when our
+        // scrollbars manage a different window from this one but currently it
+        // doesn't work.
+        const wxSize sizeClient = m_mainWin->GetClientSize();
+        const wxSize sizeVirt = m_mainWin->GetVirtualSize();
+
+        if ( sizeVirt.x > sizeClient.x /* HasScrollbar(wxHORIZONTAL) */ )
+            sizeBest.y += wxSystemSettings::GetMetric(wxSYS_HSCROLL_Y);
+
+        if ( sizeVirt.y > sizeClient.y /* HasScrollbar(wxVERTICAL) */ )
+            sizeBest.x += wxSystemSettings::GetMetric(wxSYS_VSCROLL_X);
+    }
+
+    return sizeBest;
 }
 
 // ----------------------------------------------------------------------------
@@ -5101,7 +5132,7 @@ wxString wxGenericListCtrl::OnGetItemText(long WXUNUSED(item), long WXUNUSED(col
 {
     // this is a pure virtual function, in fact - which is not really pure
     // because the controls which are not virtual don't need to implement it
-    wxFAIL_MSG( _T("wxGenericListCtrl::OnGetItemText not supposed to be called") );
+    wxFAIL_MSG( wxT("wxGenericListCtrl::OnGetItemText not supposed to be called") );
 
     return wxEmptyString;
 }
@@ -5126,7 +5157,7 @@ wxListItemAttr *
 wxGenericListCtrl::OnGetItemAttr(long WXUNUSED_UNLESS_DEBUG(item)) const
 {
     wxASSERT_MSG( item >= 0 && item < GetItemCount(),
-                  _T("invalid item index in OnGetItemAttr()") );
+                  wxT("invalid item index in OnGetItemAttr()") );
 
     // no attributes by default
     return NULL;
@@ -5134,7 +5165,7 @@ wxGenericListCtrl::OnGetItemAttr(long WXUNUSED_UNLESS_DEBUG(item)) const
 
 void wxGenericListCtrl::SetItemCount(long count)
 {
-    wxASSERT_MSG( IsVirtual(), _T("this is for virtual controls only") );
+    wxASSERT_MSG( IsVirtual(), wxT("this is for virtual controls only") );
 
     m_mainWin->SetItemCount(count);
 }
@@ -5198,4 +5229,18 @@ void wxGenericListCtrl::Refresh(bool eraseBackground, const wxRect *rect)
     }
 }
 
+void wxGenericListCtrl::Update()
+{
+    if ( m_mainWin )
+    {
+        if ( m_mainWin->m_dirty )
+            m_mainWin->RecalculatePositions();
+
+        m_mainWin->Update();
+    }
+
+    if ( m_headerWin )
+        m_headerWin->Update();
+}
+
 #endif // wxUSE_LISTCTRL