1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  11     #pragma implementation "listctrl.h" 
  12     #pragma implementation "listctrlbase.h" 
  15 // For compilers that support precompilation, includes "wx.h". 
  16 #include "wx/wxprec.h" 
  22 #include "wx/dcscreen.h" 
  24 #include "wx/listctrl.h" 
  25 #include "wx/generic/imaglist.h" 
  26 #include "wx/dynarray.h" 
  28 #ifndef wxUSE_GENERIC_LIST_EXTENSIONS 
  29 #define wxUSE_GENERIC_LIST_EXTENSIONS 1 
  32 // ============================================================================ 
  34 // ============================================================================ 
  36 //----------------------------------------------------------------------------- 
  37 //  wxListItemData (internal) 
  38 //----------------------------------------------------------------------------- 
  40 class WXDLLEXPORT wxListItemData 
: public wxObject
 
  49     wxListItemAttr 
*m_attr
; 
  53     ~wxListItemData() { delete m_attr
; } 
  55     wxListItemData( const wxListItem 
&info 
); 
  56     void SetItem( const wxListItem 
&info 
); 
  57     void SetText( const wxString 
&s 
); 
  58     void SetImage( int image 
); 
  59     void SetData( long data 
); 
  60     void SetPosition( int x
, int y 
); 
  61     void SetSize( int width
, int height 
); 
  62     bool HasImage() const; 
  64     bool IsHit( int x
, int y 
) const; 
  65     void GetText( wxString 
&s 
); 
  66     const wxString
& GetText() { return m_text
; } 
  67     int GetX( void ) const; 
  68     int GetY( void ) const; 
  70     int GetHeight() const; 
  72     void GetItem( wxListItem 
&info 
) const; 
  74     wxListItemAttr 
*GetAttributes() const { return m_attr
; } 
  77     DECLARE_DYNAMIC_CLASS(wxListItemData
); 
  80 //----------------------------------------------------------------------------- 
  81 //  wxListHeaderData (internal) 
  82 //----------------------------------------------------------------------------- 
  84 class WXDLLEXPORT wxListHeaderData 
: public wxObject
 
  97     wxListHeaderData( const wxListItem 
&info 
); 
  98     void SetItem( const wxListItem 
&item 
); 
  99     void SetPosition( int x
, int y 
); 
 100     void SetWidth( int w 
); 
 101     void SetFormat( int format 
); 
 102     void SetHeight( int h 
); 
 103     bool HasImage() const; 
 104     bool HasText() const; 
 105     bool IsHit( int x
, int y 
) const; 
 106     void GetItem( wxListItem 
&item 
); 
 107     void GetText( wxString 
&s 
); 
 108     int GetImage() const; 
 109     int GetWidth() const; 
 110     int GetFormat() const; 
 113     DECLARE_DYNAMIC_CLASS(wxListHeaderData
); 
 116 //----------------------------------------------------------------------------- 
 117 //  wxListLineData (internal) 
 118 //----------------------------------------------------------------------------- 
 120 class WXDLLEXPORT wxListLineData 
: public wxObject
 
 125     wxRect              m_bound_label
; 
 127     wxRect              m_bound_hilight
; 
 130     wxBrush            
*m_hilightBrush
; 
 132     wxListMainWindow   
*m_owner
; 
 134     void DoDraw( wxDC 
*dc
, bool hilight
, bool paintBG 
); 
 138     wxListLineData( wxListMainWindow 
*owner
, int mode
, wxBrush 
*hilightBrush 
); 
 139     void CalculateSize( wxDC 
*dc
, int spacing 
); 
 140     void SetPosition( wxDC 
*dc
, int x
, int y
,  int window_width 
); 
 141     void SetColumnPosition( int index
, int x 
); 
 142     void GetSize( int &width
, int &height 
); 
 143     void GetExtent( int &x
, int &y
, int &width
, int &height 
); 
 144     void GetLabelExtent( int &x
, int &y
, int &width
, int &height 
); 
 145     long IsHit( int x
, int y 
); 
 146     void InitItems( int num 
); 
 147     void SetItem( int index
, const wxListItem 
&info 
); 
 148     void GetItem( int index
, wxListItem 
&info 
); 
 149     void GetText( int index
, wxString 
&s 
); 
 150     void SetText( int index
, const wxString s 
); 
 151     int GetImage( int index 
); 
 152     void GetRect( wxRect 
&rect 
); 
 153     void Hilight( bool on 
); 
 154     void ReverseHilight(); 
 155     void DrawRubberBand( wxDC 
*dc
, bool on 
); 
 156     void Draw( wxDC 
*dc 
); 
 157     bool IsInRect( int x
, int y
, const wxRect 
&rect 
); 
 159     void AssignRect( wxRect 
&dest
, int x
, int y
, int width
, int height 
); 
 160     void AssignRect( wxRect 
&dest
, const wxRect 
&source 
); 
 163     void SetAttributes(wxDC 
*dc
, 
 164                        const wxListItemAttr 
*attr
, 
 165                        const wxColour
& colText
, const wxFont
& font
, 
 168     DECLARE_DYNAMIC_CLASS(wxListLineData
); 
 172 WX_DECLARE_EXPORTED_OBJARRAY(wxListLineData
, wxListLineDataArray
); 
 173 #include "wx/arrimpl.cpp" 
 174 WX_DEFINE_OBJARRAY(wxListLineDataArray
); 
 176 //----------------------------------------------------------------------------- 
 177 //  wxListHeaderWindow (internal) 
 178 //----------------------------------------------------------------------------- 
 180 class WXDLLEXPORT wxListHeaderWindow 
: public wxWindow
 
 183     wxListMainWindow  
*m_owner
; 
 184     wxCursor          
*m_currentCursor
; 
 185     wxCursor          
*m_resizeCursor
; 
 188     // column being resized 
 191     // divider line position in logical (unscrolled) coords 
 194     // minimal position beyond which the divider line can't be dragged in 
 199     wxListHeaderWindow(); 
 200     virtual ~wxListHeaderWindow(); 
 202     wxListHeaderWindow( wxWindow 
*win
, 
 204                         wxListMainWindow 
*owner
, 
 205                         const wxPoint 
&pos 
= wxDefaultPosition
, 
 206                         const wxSize 
&size 
= wxDefaultSize
, 
 208                         const wxString 
&name 
= "wxlistctrlcolumntitles" ); 
 210     void DoDrawRect( wxDC 
*dc
, int x
, int y
, int w
, int h 
); 
 212     void AdjustDC(wxDC
& dc
); 
 214     void OnPaint( wxPaintEvent 
&event 
); 
 215     void OnMouse( wxMouseEvent 
&event 
); 
 216     void OnSetFocus( wxFocusEvent 
&event 
); 
 222     DECLARE_DYNAMIC_CLASS(wxListHeaderWindow
) 
 223     DECLARE_EVENT_TABLE() 
 226 //----------------------------------------------------------------------------- 
 227 // wxListRenameTimer (internal) 
 228 //----------------------------------------------------------------------------- 
 230 class WXDLLEXPORT wxListRenameTimer
: public wxTimer
 
 233     wxListMainWindow   
*m_owner
; 
 236     wxListRenameTimer( wxListMainWindow 
*owner 
); 
 240 //----------------------------------------------------------------------------- 
 241 //  wxListTextCtrl (internal) 
 242 //----------------------------------------------------------------------------- 
 244 class WXDLLEXPORT wxListTextCtrl
: public wxTextCtrl
 
 249     wxListMainWindow   
*m_owner
; 
 250     wxString            m_startValue
; 
 254     wxListTextCtrl( wxWindow 
*parent
, const wxWindowID id
, 
 255                     bool *accept
, wxString 
*res
, wxListMainWindow 
*owner
, 
 256                     const wxString 
&value 
= "", 
 257                     const wxPoint 
&pos 
= wxDefaultPosition
, const wxSize 
&size 
= wxDefaultSize
, 
 259                     const wxValidator
& validator 
= wxDefaultValidator
, 
 260                     const wxString 
&name 
= "listctrltextctrl" ); 
 261     void OnChar( wxKeyEvent 
&event 
); 
 262     void OnKillFocus( wxFocusEvent 
&event 
); 
 265     DECLARE_DYNAMIC_CLASS(wxListTextCtrl
); 
 266     DECLARE_EVENT_TABLE() 
 269 //----------------------------------------------------------------------------- 
 270 //  wxListMainWindow (internal) 
 271 //----------------------------------------------------------------------------- 
 273 class WXDLLEXPORT wxListMainWindow
: public wxScrolledWindow
 
 277     wxListLineDataArray  m_lines
; 
 279     wxListLineData      
*m_current
; 
 280     wxListLineData      
*m_currentEdit
; 
 282     wxBrush             
*m_hilightBrush
; 
 283     wxColour            
*m_hilightColour
; 
 284     int                  m_xScroll
,m_yScroll
; 
 286     wxImageList         
*m_small_image_list
; 
 287     wxImageList         
*m_normal_image_list
; 
 289     int                  m_normal_spacing
; 
 293     wxTimer             
*m_renameTimer
; 
 295     wxString             m_renameRes
; 
 300     // for double click logic 
 301     wxListLineData      
*m_lineLastClicked
, 
 302                         *m_lineBeforeLastClicked
; 
 306     wxListMainWindow( wxWindow 
*parent
, wxWindowID id
, 
 307       const wxPoint 
&pos 
= wxDefaultPosition
, const wxSize 
&size 
= wxDefaultSize
, 
 308       long style 
= 0, const wxString 
&name 
= "listctrlmainwindow" ); 
 310     void RefreshLine( wxListLineData 
*line 
); 
 311     void OnPaint( wxPaintEvent 
&event 
); 
 312     void HilightAll( bool on 
); 
 313     void SendNotify( wxListLineData 
*line
, wxEventType command 
); 
 314     void FocusLine( wxListLineData 
*line 
); 
 315     void UnfocusLine( wxListLineData 
*line 
); 
 316     void SelectLine( wxListLineData 
*line 
); 
 317     void DeselectLine( wxListLineData 
*line 
); 
 318     void DeleteLine( wxListLineData 
*line 
); 
 320     void EditLabel( long item 
); 
 321     void Edit( long item 
) { EditLabel(item
); }         // deprecated 
 322     void OnRenameTimer(); 
 323     void OnRenameAccept(); 
 325     void OnMouse( wxMouseEvent 
&event 
); 
 327     void OnArrowChar( wxListLineData 
*newCurrent
, bool shiftDown 
); 
 328     void OnChar( wxKeyEvent 
&event 
); 
 329     void OnKeyDown( wxKeyEvent 
&event 
); 
 330     void OnSetFocus( wxFocusEvent 
&event 
); 
 331     void OnKillFocus( wxFocusEvent 
&event 
); 
 332     void OnSize( wxSizeEvent 
&event 
); 
 333     void OnScroll(wxScrollWinEvent
& event
) ; 
 335     void DrawImage( int index
, wxDC 
*dc
, int x
, int y 
); 
 336     void GetImageSize( int index
, int &width
, int &height 
); 
 337     int GetIndexOfLine( const wxListLineData 
*line 
); 
 338     int GetTextLength( wxString 
&s 
);  // should be const 
 340     void SetImageList( wxImageList 
*imageList
, int which 
); 
 341     void SetItemSpacing( int spacing
, bool isSmall 
= FALSE 
); 
 342     int GetItemSpacing( bool isSmall 
= FALSE 
); 
 343     void SetColumn( int col
, wxListItem 
&item 
); 
 344     void SetColumnWidth( int col
, int width 
); 
 345     void GetColumn( int col
, wxListItem 
&item 
); 
 346     int GetColumnWidth( int vol 
); 
 347     int GetColumnCount(); 
 348     int GetCountPerPage(); 
 349     void SetItem( wxListItem 
&item 
); 
 350     void GetItem( wxListItem 
&item 
); 
 351     void SetItemState( long item
, long state
, long stateMask 
); 
 352     int GetItemState( long item
, long stateMask 
); 
 354     void GetItemRect( long index
, wxRect 
&rect 
); 
 355     bool GetItemPosition( long item
, wxPoint
& pos 
); 
 356     int GetSelectedItemCount(); 
 357     void SetMode( long mode 
); 
 358     long GetMode() const; 
 359     void CalculatePositions(); 
 360     void RealizeChanges(); 
 361     long GetNextItem( long item
, int geometry
, int state 
); 
 362     void DeleteItem( long index 
); 
 363     void DeleteAllItems(); 
 364     void DeleteColumn( int col 
); 
 365     void DeleteEverything(); 
 366     void EnsureVisible( long index 
); 
 367     long FindItem( long start
, const wxString
& str
, bool partial 
= FALSE 
); 
 368     long FindItem( long start
, long data
); 
 369     long HitTest( int x
, int y
, int &flags 
); 
 370     void InsertItem( wxListItem 
&item 
); 
 371 //    void AddItem( wxListItem &item ); 
 372     void InsertColumn( long col
, wxListItem 
&item 
); 
 373 //    void AddColumn( wxListItem &item ); 
 374     void SortItems( wxListCtrlCompare fn
, long data 
); 
 377     DECLARE_DYNAMIC_CLASS(wxListMainWindow
); 
 378     DECLARE_EVENT_TABLE() 
 381 // ============================================================================ 
 383 // ============================================================================ 
 385 //----------------------------------------------------------------------------- 
 387 //----------------------------------------------------------------------------- 
 389 IMPLEMENT_DYNAMIC_CLASS(wxListItemData
,wxObject
); 
 391 wxListItemData::wxListItemData() 
 402 wxListItemData::wxListItemData( const wxListItem 
&info 
) 
 411 void wxListItemData::SetItem( const wxListItem 
&info 
) 
 413     if (info
.m_mask 
& wxLIST_MASK_TEXT
) m_text 
= info
.m_text
; 
 414     if (info
.m_mask 
& wxLIST_MASK_IMAGE
) m_image 
= info
.m_image
; 
 415     if (info
.m_mask 
& wxLIST_MASK_DATA
) m_data 
= info
.m_data
; 
 417     if ( info
.HasAttributes() ) 
 420             *m_attr 
= *info
.GetAttributes(); 
 422             m_attr 
= new wxListItemAttr(*info
.GetAttributes()); 
 427     m_width 
= info
.m_width
; 
 431 void wxListItemData::SetText( const wxString 
&s 
) 
 436 void wxListItemData::SetImage( int image 
) 
 441 void wxListItemData::SetData( long data 
) 
 446 void wxListItemData::SetPosition( int x
, int y 
) 
 452 void wxListItemData::SetSize( int width
, int height 
) 
 454     if (width 
!= -1) m_width 
= width
; 
 455     if (height 
!= -1) m_height 
= height
; 
 458 bool wxListItemData::HasImage() const 
 460     return (m_image 
>= 0); 
 463 bool wxListItemData::HasText() const 
 465     return (!m_text
.IsNull()); 
 468 bool wxListItemData::IsHit( int x
, int y 
) const 
 470     return ((x 
>= m_xpos
) && (x 
<= m_xpos
+m_width
) && (y 
>= m_ypos
) && (y 
<= m_ypos
+m_height
)); 
 473 void wxListItemData::GetText( wxString 
&s 
) 
 478 int wxListItemData::GetX() const 
 483 int wxListItemData::GetY() const 
 488 int wxListItemData::GetWidth() const 
 493 int wxListItemData::GetHeight() const 
 498 int wxListItemData::GetImage() const 
 503 void wxListItemData::GetItem( wxListItem 
&info 
) const 
 505     info
.m_text 
= m_text
; 
 506     info
.m_image 
= m_image
; 
 507     info
.m_data 
= m_data
; 
 511         if ( m_attr
->HasTextColour() ) 
 512             info
.SetTextColour(m_attr
->GetTextColour()); 
 513         if ( m_attr
->HasBackgroundColour() ) 
 514             info
.SetBackgroundColour(m_attr
->GetBackgroundColour()); 
 515         if ( m_attr
->HasFont() ) 
 516             info
.SetFont(m_attr
->GetFont()); 
 520 //----------------------------------------------------------------------------- 
 522 //----------------------------------------------------------------------------- 
 524 IMPLEMENT_DYNAMIC_CLASS(wxListHeaderData
,wxObject
); 
 526 wxListHeaderData::wxListHeaderData() 
 537 wxListHeaderData::wxListHeaderData( const wxListItem 
&item 
) 
 545 void wxListHeaderData::SetItem( const wxListItem 
&item 
) 
 547     m_mask 
= item
.m_mask
; 
 548     m_text 
= item
.m_text
; 
 549     m_image 
= item
.m_image
; 
 550     m_format 
= item
.m_format
; 
 551     m_width 
= item
.m_width
; 
 552     if (m_width 
< 0) m_width 
= 80; 
 553     if (m_width 
< 6) m_width 
= 6; 
 556 void wxListHeaderData::SetPosition( int x
, int y 
) 
 562 void wxListHeaderData::SetHeight( int h 
) 
 567 void wxListHeaderData::SetWidth( int w 
) 
 570     if (m_width 
< 0) m_width 
= 80; 
 571     if (m_width 
< 6) m_width 
= 6; 
 574 void wxListHeaderData::SetFormat( int format 
) 
 579 bool wxListHeaderData::HasImage() const 
 581     return (m_image 
!= 0); 
 584 bool wxListHeaderData::HasText() const 
 586     return (m_text
.Length() > 0); 
 589 bool wxListHeaderData::IsHit( int x
, int y 
) const 
 591     return ((x 
>= m_xpos
) && (x 
<= m_xpos
+m_width
) && (y 
>= m_ypos
) && (y 
<= m_ypos
+m_height
)); 
 594 void wxListHeaderData::GetItem( wxListItem 
&item 
) 
 596     item
.m_mask 
= m_mask
; 
 597     item
.m_text 
= m_text
; 
 598     item
.m_image 
= m_image
; 
 599     item
.m_format 
= m_format
; 
 600     item
.m_width 
= m_width
; 
 603 void wxListHeaderData::GetText( wxString 
&s 
) 
 608 int wxListHeaderData::GetImage() const 
 613 int wxListHeaderData::GetWidth() const 
 618 int wxListHeaderData::GetFormat() const 
 623 //----------------------------------------------------------------------------- 
 625 //----------------------------------------------------------------------------- 
 627 IMPLEMENT_DYNAMIC_CLASS(wxListLineData
,wxObject
); 
 629 wxListLineData::wxListLineData( wxListMainWindow 
*owner
, int mode
, wxBrush 
*hilightBrush 
) 
 634     m_hilightBrush 
= hilightBrush
; 
 635     m_items
.DeleteContents( TRUE 
); 
 639 void wxListLineData::CalculateSize( wxDC 
*dc
, int spacing 
) 
 646             m_bound_all
.width 
= m_spacing
; 
 647             wxNode 
*node 
= m_items
.First(); 
 650                 wxListItemData 
*item 
= (wxListItemData
*)node
->Data(); 
 651                 wxString s 
= item
->GetText(); 
 652                 if (s
.IsEmpty()) s 
= wxT("H"); 
 654                 dc
->GetTextExtent( s
, &lw
, &lh 
); 
 655                 if (lh 
< 15) lh 
= 15; 
 659                 m_bound_all
.height 
= m_spacing
+lh
; 
 660                 if (lw 
> m_spacing
) m_bound_all
.width 
= lw
; 
 661                 m_bound_label
.width 
= lw
; 
 662                 m_bound_label
.height 
= lh
; 
 664                 if (item
->HasImage()) 
 668                     m_owner
->GetImageSize( item
->GetImage(), w
, h 
); 
 669                     m_bound_icon
.width 
= w 
+ 8; 
 670                     m_bound_icon
.height 
= h 
+ 8; 
 672                     if ( m_bound_icon
.width 
> m_bound_all
.width 
) 
 673                         m_bound_all
.width 
= m_bound_icon
.width
; 
 674                     if ( h 
+ lh 
> m_bound_all
.height 
- 4 ) 
 675                         m_bound_all
.height 
= h 
+ lh 
+ 4; 
 678                 if (!item
->HasText()) 
 680                     m_bound_hilight
.width 
= m_bound_icon
.width
; 
 681                     m_bound_hilight
.height 
= m_bound_icon
.height
; 
 685                     m_bound_hilight
.width 
= m_bound_label
.width
; 
 686                     m_bound_hilight
.height 
= m_bound_label
.height
; 
 693             wxNode 
*node 
= m_items
.First(); 
 696                 wxListItemData 
*item 
= (wxListItemData
*)node
->Data(); 
 698                 wxString s 
= item
->GetText(); 
 699                 if (s
.IsEmpty()) s 
= wxT("H"); 
 701                 dc
->GetTextExtent( s
, &lw
, &lh 
); 
 702                 if (lh 
< 15) lh 
= 15; 
 705                 m_bound_label
.width 
= lw
; 
 706                 m_bound_label
.height 
= lh
; 
 708                 m_bound_all
.width 
= lw
; 
 709                 m_bound_all
.height 
= lh
; 
 711                 if (item
->HasImage()) 
 715                     m_owner
->GetImageSize( item
->GetImage(), w
, h 
); 
 716                     m_bound_icon
.width 
= w
; 
 717                     m_bound_icon
.height 
= h
; 
 719                     m_bound_all
.width 
+= 4 + w
; 
 720                     if (h 
> m_bound_all
.height
) m_bound_all
.height 
= h
; 
 723                 m_bound_hilight
.width 
= m_bound_all
.width
; 
 724                 m_bound_hilight
.height 
= m_bound_all
.height
; 
 730             m_bound_all
.width 
= 0; 
 731             m_bound_all
.height 
= 0; 
 732             wxNode 
*node 
= m_items
.First(); 
 735                 wxListItemData 
*item 
= (wxListItemData
*)node
->Data(); 
 736                 wxString s 
= item
->GetText(); 
 737                 if (s
.IsEmpty()) s 
= wxT("H"); 
 739                 dc
->GetTextExtent( s
, &lw
, &lh 
); 
 740                 if (lh 
< 15) lh 
= 15; 
 744                 item
->SetSize( item
->GetWidth(), lh 
); 
 745                 m_bound_all
.width 
+= lw
; 
 746                 m_bound_all
.height 
= lh
; 
 754 void wxListLineData::SetPosition( wxDC 
* WXUNUSED(dc
), 
 755                                   int x
, int y
, int window_width 
) 
 763             wxNode 
*node 
= m_items
.First(); 
 766                 wxListItemData 
*item 
= (wxListItemData
*)node
->Data(); 
 767                 if (item
->HasImage()) 
 769                     m_bound_icon
.x 
= m_bound_all
.x 
+ 4 
 770                                         + (m_spacing 
- m_bound_icon
.width
)/2; 
 771                     m_bound_icon
.y 
= m_bound_all
.y 
+ 4; 
 775                     if (m_bound_all
.width 
> m_spacing
) 
 776                         m_bound_label
.x 
= m_bound_all
.x 
+ 2; 
 778                         m_bound_label
.x 
= m_bound_all
.x 
+ 2 + (m_spacing
/2) - (m_bound_label
.width
/2); 
 779                     m_bound_label
.y 
= m_bound_all
.y 
+ m_bound_all
.height 
+ 2 - m_bound_label
.height
; 
 780                     m_bound_hilight
.x 
= m_bound_label
.x 
- 2; 
 781                     m_bound_hilight
.y 
= m_bound_label
.y 
- 2; 
 785                     m_bound_hilight
.x 
= m_bound_icon
.x 
- 4; 
 786                     m_bound_hilight
.y 
= m_bound_icon
.y 
- 4; 
 793             m_bound_hilight
.x 
= m_bound_all
.x
; 
 794             m_bound_hilight
.y 
= m_bound_all
.y
; 
 795             m_bound_label
.y 
= m_bound_all
.y 
+ 2; 
 796             wxNode 
*node 
= m_items
.First(); 
 799                 wxListItemData 
*item 
= (wxListItemData
*)node
->Data(); 
 800                 if (item
->HasImage()) 
 802                     m_bound_icon
.x 
= m_bound_all
.x 
+ 2; 
 803                     m_bound_icon
.y 
= m_bound_all
.y 
+ 2; 
 804                     m_bound_label
.x 
= m_bound_all
.x 
+ 6 + m_bound_icon
.width
; 
 808                     m_bound_label
.x 
= m_bound_all
.x 
+ 2; 
 816             m_bound_all
.width 
= window_width
; 
 817             AssignRect( m_bound_hilight
, m_bound_all 
); 
 818             m_bound_label
.x 
= m_bound_all
.x 
+ 2; 
 819             m_bound_label
.y 
= m_bound_all
.y 
+ 2; 
 820             wxNode 
*node 
= m_items
.First(); 
 823                 wxListItemData 
*item 
= (wxListItemData
*)node
->Data(); 
 824                 if (item
->HasImage()) 
 826                     m_bound_icon
.x 
= m_bound_all
.x 
+ 2; 
 827                     m_bound_icon
.y 
= m_bound_all
.y 
+ 2; 
 828                     m_bound_label
.x 
+= 4 + m_bound_icon
.width
; 
 836 void wxListLineData::SetColumnPosition( int index
, int x 
) 
 838     wxNode 
*node 
= m_items
.Nth( (size_t)index 
); 
 841         wxListItemData 
*item 
= (wxListItemData
*)node
->Data(); 
 842         item
->SetPosition( x
, m_bound_all
.y
+1 ); 
 846 void wxListLineData::GetSize( int &width
, int &height 
) 
 848     width 
= m_bound_all
.width
; 
 849     height 
= m_bound_all
.height
; 
 852 void wxListLineData::GetExtent( int &x
, int &y
, int &width
, int &height 
) 
 856     width 
= m_bound_all
.width
; 
 857     height 
= m_bound_all
.height
; 
 860 void wxListLineData::GetLabelExtent( int &x
, int &y
, int &width
, int &height 
) 
 864     width 
= m_bound_label
.width
; 
 865     height 
= m_bound_label
.height
; 
 868 void wxListLineData::GetRect( wxRect 
&rect 
) 
 870     AssignRect( rect
, m_bound_all 
); 
 873 long wxListLineData::IsHit( int x
, int y 
) 
 875     wxNode 
*node 
= m_items
.First(); 
 878         wxListItemData 
*item 
= (wxListItemData
*)node
->Data(); 
 879         if (item
->HasImage() && IsInRect( x
, y
, m_bound_icon 
)) return wxLIST_HITTEST_ONITEMICON
; 
 880         if (item
->HasText() && IsInRect( x
, y
, m_bound_label 
)) return wxLIST_HITTEST_ONITEMLABEL
; 
 881 //      if (!(item->HasImage() || item->HasText())) return 0; 
 883     // if there is no icon or text = empty 
 884     if (IsInRect( x
, y
, m_bound_all 
)) return wxLIST_HITTEST_ONITEMICON
; 
 888 void wxListLineData::InitItems( int num 
) 
 890     for (int i 
= 0; i 
< num
; i
++) m_items
.Append( new wxListItemData() ); 
 893 void wxListLineData::SetItem( int index
, const wxListItem 
&info 
) 
 895     wxNode 
*node 
= m_items
.Nth( index 
); 
 898        wxListItemData 
*item 
= (wxListItemData
*)node
->Data(); 
 899        item
->SetItem( info 
); 
 903 void wxListLineData::GetItem( int index
, wxListItem 
&info 
) 
 906     wxNode 
*node 
= m_items
.Nth( i 
); 
 909         wxListItemData 
*item 
= (wxListItemData
*)node
->Data(); 
 910         item
->GetItem( info 
); 
 914 void wxListLineData::GetText( int index
, wxString 
&s 
) 
 917     wxNode 
*node 
= m_items
.Nth( i 
); 
 921         wxListItemData 
*item 
= (wxListItemData
*)node
->Data(); 
 926 void wxListLineData::SetText( int index
, const wxString s 
) 
 929     wxNode 
*node 
= m_items
.Nth( i 
); 
 932         wxListItemData 
*item 
= (wxListItemData
*)node
->Data(); 
 937 int wxListLineData::GetImage( int index 
) 
 940     wxNode 
*node 
= m_items
.Nth( i 
); 
 943         wxListItemData 
*item 
= (wxListItemData
*)node
->Data(); 
 944         return item
->GetImage(); 
 949 void wxListLineData::SetAttributes(wxDC 
*dc
, 
 950                                    const wxListItemAttr 
*attr
, 
 951                                    const wxColour
& colText
, 
 955     // don't use foregroud colour for drawing highlighted items - this might 
 956     // make them completely invisible (and there is no way to do bit 
 957     // arithmetics on wxColour, unfortunately) 
 958     if ( !hilight 
&& attr 
&& attr
->HasTextColour() ) 
 960         dc
->SetTextForeground(attr
->GetTextColour()); 
 964         dc
->SetTextForeground(colText
); 
 967     if ( attr 
&& attr
->HasFont() ) 
 969         dc
->SetFont(attr
->GetFont()); 
 977 void wxListLineData::DoDraw( wxDC 
*dc
, bool hilight
, bool paintBG 
) 
 981     m_owner
->CalcScrolledPosition( m_bound_all
.x
, m_bound_all
.y
, &dev_x
, &dev_y 
); 
 982     wxCoord dev_w 
= m_bound_all
.width
; 
 983     wxCoord dev_h 
= m_bound_all
.height
; 
 985     if (!m_owner
->IsExposed( dev_x
, dev_y
, dev_w
, dev_h 
)) 
 988     wxWindow 
*listctrl 
= m_owner
->GetParent(); 
 990     // default foreground colour 
 994         colText 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_HIGHLIGHTTEXT 
); 
 998         colText 
= listctrl
->GetForegroundColour(); 
1002     wxFont font 
= listctrl
->GetFont(); 
1004     // VZ: currently we set the colours/fonts only once, but like this (i.e. 
1005     //     using SetAttributes() inside the loop), it will be trivial to 
1006     //     customize the subitems (in report mode) too. 
1007     wxListItemData 
*item 
= (wxListItemData
*)m_items
.First()->Data(); 
1008     wxListItemAttr 
*attr 
= item
->GetAttributes(); 
1009     SetAttributes(dc
, attr
, colText
, font
, hilight
); 
1011     bool hasBgCol 
= attr 
&& attr
->HasBackgroundColour(); 
1012     if ( paintBG 
|| hasBgCol 
) 
1016             dc
->SetBrush( * m_hilightBrush 
); 
1021                 dc
->SetBrush(wxBrush(attr
->GetBackgroundColour(), wxSOLID
)); 
1023                 dc
->SetBrush( * wxWHITE_BRUSH 
); 
1026         dc
->SetPen( * wxTRANSPARENT_PEN 
); 
1027         dc
->DrawRectangle( m_bound_hilight
.x
, m_bound_hilight
.y
, 
1028                            m_bound_hilight
.width
, m_bound_hilight
.height 
); 
1031     if (m_mode 
== wxLC_REPORT
) 
1033         wxNode 
*node 
= m_items
.First(); 
1036             wxListItemData 
*item 
= (wxListItemData
*)node
->Data(); 
1037             int x 
= item
->GetX(); 
1038             if (item
->HasImage()) 
1041                 m_owner
->DrawImage( item
->GetImage(), dc
, x
, item
->GetY() ); 
1042                 m_owner
->GetImageSize( item
->GetImage(), x
, y 
); 
1043                 x 
+= item
->GetX() + 5; 
1045             dc
->SetClippingRegion( item
->GetX(), item
->GetY(), item
->GetWidth()-3, item
->GetHeight() ); 
1046             if (item
->HasText()) 
1048                 dc
->DrawText( item
->GetText(), x
, item
->GetY()+1 ); 
1050             dc
->DestroyClippingRegion(); 
1051             node 
= node
->Next(); 
1056         wxNode 
*node 
= m_items
.First(); 
1059             wxListItemData 
*item 
= (wxListItemData
*)node
->Data(); 
1060             if (item
->HasImage()) 
1062                 m_owner
->DrawImage( item
->GetImage(), dc
, m_bound_icon
.x
, m_bound_icon
.y 
); 
1064             if (item
->HasText()) 
1066                 dc
->DrawText( item
->GetText(), m_bound_label
.x
, m_bound_label
.y 
); 
1072 void wxListLineData::Hilight( bool on 
) 
1074     if (on 
== m_hilighted
) return; 
1077         m_owner
->SelectLine( this ); 
1079         m_owner
->DeselectLine( this ); 
1082 void wxListLineData::ReverseHilight( void ) 
1084     m_hilighted 
= !m_hilighted
; 
1086         m_owner
->SelectLine( this ); 
1088         m_owner
->DeselectLine( this ); 
1091 void wxListLineData::DrawRubberBand( wxDC 
*dc
, bool on 
) 
1095         dc
->SetPen( * wxBLACK_PEN 
); 
1096         dc
->SetBrush( * wxTRANSPARENT_BRUSH 
); 
1097         dc
->DrawRectangle( m_bound_hilight
.x
, m_bound_hilight
.y
, 
1098                            m_bound_hilight
.width
, m_bound_hilight
.height 
); 
1102 void wxListLineData::Draw( wxDC 
*dc 
) 
1104     DoDraw( dc
, m_hilighted
, m_hilighted 
); 
1107 bool wxListLineData::IsInRect( int x
, int y
, const wxRect 
&rect 
) 
1109     return ((x 
>= rect
.x
) && (x 
<= rect
.x
+rect
.width
) && 
1110             (y 
>= rect
.y
) && (y 
<= rect
.y
+rect
.height
)); 
1113 bool wxListLineData::IsHilighted( void ) 
1118 void wxListLineData::AssignRect( wxRect 
&dest
, int x
, int y
, int width
, int height 
) 
1123     dest
.height 
= height
; 
1126 void wxListLineData::AssignRect( wxRect 
&dest
, const wxRect 
&source 
) 
1130     dest
.width 
= source
.width
; 
1131     dest
.height 
= source
.height
; 
1134 //----------------------------------------------------------------------------- 
1135 //  wxListHeaderWindow 
1136 //----------------------------------------------------------------------------- 
1138 IMPLEMENT_DYNAMIC_CLASS(wxListHeaderWindow
,wxWindow
); 
1140 BEGIN_EVENT_TABLE(wxListHeaderWindow
,wxWindow
) 
1141     EVT_PAINT         (wxListHeaderWindow::OnPaint
) 
1142     EVT_MOUSE_EVENTS  (wxListHeaderWindow::OnMouse
) 
1143     EVT_SET_FOCUS     (wxListHeaderWindow::OnSetFocus
) 
1146 wxListHeaderWindow::wxListHeaderWindow( void ) 
1148     m_owner 
= (wxListMainWindow 
*) NULL
; 
1149     m_currentCursor 
= (wxCursor 
*) NULL
; 
1150     m_resizeCursor 
= (wxCursor 
*) NULL
; 
1151     m_isDragging 
= FALSE
; 
1154 wxListHeaderWindow::wxListHeaderWindow( wxWindow 
*win
, wxWindowID id
, wxListMainWindow 
*owner
, 
1155       const wxPoint 
&pos
, const wxSize 
&size
, 
1156       long style
, const wxString 
&name 
) : 
1157   wxWindow( win
, id
, pos
, size
, style
, name 
) 
1160 //  m_currentCursor = wxSTANDARD_CURSOR; 
1161     m_currentCursor 
= (wxCursor 
*) NULL
; 
1162     m_resizeCursor 
= new wxCursor( wxCURSOR_SIZEWE 
); 
1163     m_isDragging 
= FALSE
; 
1166     SetBackgroundColour( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
) ); 
1169 wxListHeaderWindow::~wxListHeaderWindow( void ) 
1171     delete m_resizeCursor
; 
1174 void wxListHeaderWindow::DoDrawRect( wxDC 
*dc
, int x
, int y
, int w
, int h 
) 
1176     const int m_corner 
= 1; 
1178     dc
->SetBrush( *wxTRANSPARENT_BRUSH 
); 
1180     dc
->SetPen( *wxBLACK_PEN 
); 
1181     dc
->DrawLine( x
+w
-m_corner
+1, y
, x
+w
, y
+h 
);  // right (outer) 
1182     dc
->DrawRectangle( x
, y
+h
, w
+1, 1 );          // bottom (outer) 
1184     wxPen 
pen( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNSHADOW 
), 1, wxSOLID 
); 
1187     dc
->DrawLine( x
+w
-m_corner
, y
, x
+w
-1, y
+h 
);  // right (inner) 
1188     dc
->DrawRectangle( x
+1, y
+h
-1, w
-2, 1 );      // bottom (inner) 
1190     dc
->SetPen( *wxWHITE_PEN 
); 
1191     dc
->DrawRectangle( x
, y
, w
-m_corner
+1, 1 );   // top (outer) 
1192     dc
->DrawRectangle( x
, y
, 1, h 
);              // left (outer) 
1193     dc
->DrawLine( x
, y
+h
-1, x
+1, y
+h
-1 ); 
1194     dc
->DrawLine( x
+w
-1, y
, x
+w
-1, y
+1 ); 
1197 // shift the DC origin to match the position of the main window horz 
1198 // scrollbar: this allows us to always use logical coords 
1199 void wxListHeaderWindow::AdjustDC(wxDC
& dc
) 
1201 #if wxUSE_GENERIC_LIST_EXTENSIONS 
1203     m_owner
->GetScrollPixelsPerUnit( &xpix
, NULL 
); 
1206     m_owner
->GetViewStart( &x
, NULL 
); 
1208     // account for the horz scrollbar offset 
1209     dc
.SetDeviceOrigin( -x 
* xpix
, 0 ); 
1210 #endif // wxUSE_GENERIC_LIST_EXTENSIONS 
1213 void wxListHeaderWindow::OnPaint( wxPaintEvent 
&WXUNUSED(event
) ) 
1215     wxPaintDC 
dc( this ); 
1221     dc
.SetFont( GetFont() ); 
1223     // width and height of the entire header window 
1225     GetClientSize( &w
, &h 
); 
1226 #if wxUSE_GENERIC_LIST_EXTENSIONS 
1227     m_owner
->CalcUnscrolledPosition(w
, 0, &w
, NULL
); 
1228 #endif // wxUSE_GENERIC_LIST_EXTENSIONS 
1230     dc
.SetBackgroundMode(wxTRANSPARENT
); 
1232     // do *not* use the listctrl colour for headers - one day we will have a 
1233     // function to set it separately 
1234     dc
.SetTextForeground( *wxBLACK 
); 
1236     int x 
= 1;          // left of the header rect 
1237     const int y 
= 1;    // top 
1238     int numColumns 
= m_owner
->GetColumnCount(); 
1240     for (int i 
= 0; i 
< numColumns
; i
++) 
1242         m_owner
->GetColumn( i
, item 
); 
1243         int wCol 
= item
.m_width
; 
1244         int cw 
= wCol 
- 2; // the width of the rect to draw 
1246         int xEnd 
= x 
+ wCol
; 
1248         // VZ: no, draw it normally - this is better now as we allow resizing 
1249         //     of the last column as well 
1251         // let the last column occupy all available space 
1252         if ( i 
== numColumns 
- 1 ) 
1256         dc
.SetPen( *wxWHITE_PEN 
); 
1258         DoDrawRect( &dc
, x
, y
, cw
, h
-2 ); 
1259         dc
.SetClippingRegion( x
, y
, cw
-5, h
-4 ); 
1260         dc
.DrawText( item
.m_text
, x
+4, y
+3 ); 
1261         dc
.DestroyClippingRegion(); 
1270 void wxListHeaderWindow::DrawCurrent() 
1272     int x1 
= m_currentX
; 
1274     ClientToScreen( &x1
, &y1 
); 
1276     int x2 
= m_currentX
-1; 
1278     m_owner
->GetClientSize( NULL
, &y2 
); 
1279     m_owner
->ClientToScreen( &x2
, &y2 
); 
1282     dc
.SetLogicalFunction( wxINVERT 
); 
1283     dc
.SetPen( wxPen( *wxBLACK
, 2, wxSOLID 
) ); 
1284     dc
.SetBrush( *wxTRANSPARENT_BRUSH 
); 
1288     dc
.DrawLine( x1
, y1
, x2
, y2 
); 
1290     dc
.SetLogicalFunction( wxCOPY 
); 
1292     dc
.SetPen( wxNullPen 
); 
1293     dc
.SetBrush( wxNullBrush 
); 
1296 void wxListHeaderWindow::OnMouse( wxMouseEvent 
&event 
) 
1298     // we want to work with logical coords 
1299 #if wxUSE_GENERIC_LIST_EXTENSIONS 
1301     m_owner
->CalcUnscrolledPosition(event
.GetX(), event
.GetY(), &x
, &y
); 
1302 #else // !wxUSE_GENERIC_LIST_EXTENSIONS 
1303     int x 
= event
.GetX(); 
1304     int y 
= event
.GetY(); 
1305 #endif // wxUSE_GENERIC_LIST_EXTENSIONS 
1309         // we don't draw the line beyond our window, but we allow dragging it 
1312         GetClientSize( &w
, NULL 
); 
1313 #if wxUSE_GENERIC_LIST_EXTENSIONS 
1314         m_owner
->CalcUnscrolledPosition(w
, 0, &w
, NULL
); 
1315 #endif // wxUSE_GENERIC_LIST_EXTENSIONS 
1318         // erase the line if it was drawn 
1319         if ( m_currentX 
< w 
) 
1322         if (event
.ButtonUp()) 
1325             m_isDragging 
= FALSE
; 
1327             m_owner
->SetColumnWidth( m_column
, m_currentX 
- m_minX 
); 
1334                 m_currentX 
= m_minX 
+ 7; 
1336             // draw in the new location 
1337             if ( m_currentX 
< w 
) 
1341     else // not dragging 
1344         bool hit_border 
= FALSE
; 
1346         // end of the current column 
1349         // find the column where this event occured 
1350         int countCol 
= m_owner
->GetColumnCount(); 
1351         for (int j 
= 0; j 
< countCol
; j
++) 
1353             xpos 
+= m_owner
->GetColumnWidth( j 
); 
1356             if ( (abs(x
-xpos
) < 3) && (y 
< 22) ) 
1358                 // near the column border 
1365                 // inside the column 
1372         if (event
.LeftDown()) 
1376                 m_isDragging 
= TRUE
; 
1383                 wxWindow 
*parent 
= GetParent(); 
1384                 wxListEvent 
le( wxEVT_COMMAND_LIST_COL_CLICK
, parent
->GetId() ); 
1385                 le
.SetEventObject( parent 
); 
1386                 le
.m_col 
= m_column
; 
1387                 parent
->GetEventHandler()->ProcessEvent( le 
); 
1390         else if (event
.Moving()) 
1395                 setCursor 
= m_currentCursor 
== wxSTANDARD_CURSOR
; 
1396                 m_currentCursor 
= m_resizeCursor
; 
1400                 setCursor 
= m_currentCursor 
!= wxSTANDARD_CURSOR
; 
1401                 m_currentCursor 
= wxSTANDARD_CURSOR
; 
1405                 SetCursor(*m_currentCursor
); 
1410 void wxListHeaderWindow::OnSetFocus( wxFocusEvent 
&WXUNUSED(event
) ) 
1412     m_owner
->SetFocus(); 
1415 //----------------------------------------------------------------------------- 
1416 // wxListRenameTimer (internal) 
1417 //----------------------------------------------------------------------------- 
1419 wxListRenameTimer::wxListRenameTimer( wxListMainWindow 
*owner 
) 
1424 void wxListRenameTimer::Notify() 
1426     m_owner
->OnRenameTimer(); 
1429 //----------------------------------------------------------------------------- 
1430 // wxListTextCtrl (internal) 
1431 //----------------------------------------------------------------------------- 
1433 IMPLEMENT_DYNAMIC_CLASS(wxListTextCtrl
,wxTextCtrl
); 
1435 BEGIN_EVENT_TABLE(wxListTextCtrl
,wxTextCtrl
) 
1436     EVT_CHAR           (wxListTextCtrl::OnChar
) 
1437     EVT_KILL_FOCUS     (wxListTextCtrl::OnKillFocus
) 
1440 wxListTextCtrl::wxListTextCtrl( wxWindow 
*parent
, 
1441                                 const wxWindowID id
, 
1444                                 wxListMainWindow 
*owner
, 
1445                                 const wxString 
&value
, 
1449                                 const wxValidator
& validator
, 
1450                                 const wxString 
&name 
) 
1451               : wxTextCtrl( parent
, id
, value
, pos
, size
, style
, validator
, name 
) 
1456     (*m_accept
) = FALSE
; 
1458     m_startValue 
= value
; 
1461 void wxListTextCtrl::OnChar( wxKeyEvent 
&event 
) 
1463     if (event
.m_keyCode 
== WXK_RETURN
) 
1466         (*m_res
) = GetValue(); 
1468         if (!wxPendingDelete
.Member(this)) 
1469             wxPendingDelete
.Append(this); 
1471         if ((*m_accept
) && ((*m_res
) != m_startValue
)) 
1472             m_owner
->OnRenameAccept(); 
1476     if (event
.m_keyCode 
== WXK_ESCAPE
) 
1478         (*m_accept
) = FALSE
; 
1481         if (!wxPendingDelete
.Member(this)) 
1482             wxPendingDelete
.Append(this); 
1490 void wxListTextCtrl::OnKillFocus( wxFocusEvent 
&WXUNUSED(event
) ) 
1492     if (!wxPendingDelete
.Member(this)) 
1493         wxPendingDelete
.Append(this); 
1495     if ((*m_accept
) && ((*m_res
) != m_startValue
)) 
1496         m_owner
->OnRenameAccept(); 
1499 //----------------------------------------------------------------------------- 
1501 //----------------------------------------------------------------------------- 
1503 IMPLEMENT_DYNAMIC_CLASS(wxListMainWindow
,wxScrolledWindow
); 
1505 BEGIN_EVENT_TABLE(wxListMainWindow
,wxScrolledWindow
) 
1506   EVT_PAINT          (wxListMainWindow::OnPaint
) 
1507   EVT_SIZE           (wxListMainWindow::OnSize
) 
1508   EVT_MOUSE_EVENTS   (wxListMainWindow::OnMouse
) 
1509   EVT_CHAR           (wxListMainWindow::OnChar
) 
1510   EVT_KEY_DOWN       (wxListMainWindow::OnKeyDown
) 
1511   EVT_SET_FOCUS      (wxListMainWindow::OnSetFocus
) 
1512   EVT_KILL_FOCUS     (wxListMainWindow::OnKillFocus
) 
1513   EVT_SCROLLWIN      (wxListMainWindow::OnScroll
) 
1516 wxListMainWindow::wxListMainWindow() 
1519     m_columns
.DeleteContents( TRUE 
); 
1520     m_current 
= (wxListLineData 
*) NULL
; 
1522     m_hilightBrush 
= (wxBrush 
*) NULL
; 
1526     m_small_image_list 
= (wxImageList 
*) NULL
; 
1527     m_normal_image_list 
= (wxImageList 
*) NULL
; 
1528     m_small_spacing 
= 30; 
1529     m_normal_spacing 
= 40; 
1532     m_lastOnSame 
= FALSE
; 
1533     m_renameTimer 
= new wxListRenameTimer( this ); 
1534     m_isCreated 
= FALSE
; 
1538     m_lineBeforeLastClicked 
= (wxListLineData 
*)NULL
; 
1541 wxListMainWindow::wxListMainWindow( wxWindow 
*parent
, wxWindowID id
, 
1542       const wxPoint 
&pos
, const wxSize 
&size
, 
1543       long style
, const wxString 
&name 
) : 
1544   wxScrolledWindow( parent
, id
, pos
, size
, style
|wxHSCROLL
|wxVSCROLL
, name 
) 
1547     m_columns
.DeleteContents( TRUE 
); 
1548     m_current 
= (wxListLineData 
*) NULL
; 
1551     m_hilightBrush 
= new wxBrush( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_HIGHLIGHT
), wxSOLID 
); 
1552     m_small_image_list 
= (wxImageList 
*) NULL
; 
1553     m_normal_image_list 
= (wxImageList 
*) NULL
; 
1554     m_small_spacing 
= 30; 
1555     m_normal_spacing 
= 40; 
1558     m_isCreated 
= FALSE
; 
1562     if (m_mode 
& wxLC_REPORT
) 
1564 #if wxUSE_GENERIC_LIST_EXTENSIONS 
1576     SetScrollbars( m_xScroll
, m_yScroll
, 0, 0, 0, 0 ); 
1579     m_lastOnSame 
= FALSE
; 
1580     m_renameTimer 
= new wxListRenameTimer( this ); 
1581     m_renameAccept 
= FALSE
; 
1583     SetBackgroundColour( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_LISTBOX 
) ); 
1586 wxListMainWindow::~wxListMainWindow() 
1590     if (m_hilightBrush
) delete m_hilightBrush
; 
1592     delete m_renameTimer
; 
1595 void wxListMainWindow::RefreshLine( wxListLineData 
*line 
) 
1597     if (m_dirty
) return; 
1605     line
->GetExtent( x
, y
, w
, h 
); 
1606     CalcScrolledPosition( x
, y
, &x
, &y 
); 
1607     wxRect 
rect( x
, y
, w
, h 
); 
1608     Refresh( TRUE
, &rect 
); 
1611 void wxListMainWindow::OnPaint( wxPaintEvent 
&WXUNUSED(event
) ) 
1613     // Note: a wxPaintDC must be constructed even if no drawing is 
1614     // done (a Windows requirement). 
1615     wxPaintDC 
dc( this ); 
1618     if (m_dirty
) return; 
1620     if (m_lines
.GetCount() == 0) return; 
1624     dc
.SetFont( GetFont() ); 
1626     if (m_mode 
& wxLC_REPORT
) 
1628         int lineSpacing 
= 0; 
1629         wxListLineData 
*line 
= &m_lines
[0]; 
1631         line
->GetSize( dummy
, lineSpacing 
); 
1634         int y_s 
= m_yScroll
*GetScrollPos( wxVERTICAL 
); 
1636         size_t i_to 
= y_s 
/ lineSpacing 
+ m_visibleLines
+2; 
1637         if (i_to 
>= m_lines
.GetCount()) i_to 
= m_lines
.GetCount(); 
1638         for (size_t i 
= y_s 
/ lineSpacing
; i 
< i_to
; i
++) 
1640             m_lines
[i
].Draw( &dc 
); 
1645         for (size_t i 
= 0; i 
< m_lines
.GetCount(); i
++) 
1646             m_lines
[i
].Draw( &dc 
); 
1649     if (m_current
) m_current
->DrawRubberBand( &dc
, m_hasFocus 
); 
1654 void wxListMainWindow::HilightAll( bool on 
) 
1656     for (size_t i 
= 0; i 
< m_lines
.GetCount(); i
++) 
1658         wxListLineData 
*line 
= &m_lines
[i
]; 
1659         if (line
->IsHilighted() != on
) 
1661             line
->Hilight( on 
); 
1662             RefreshLine( line 
); 
1667 void wxListMainWindow::SendNotify( wxListLineData 
*line
, wxEventType command 
) 
1669     wxListEvent 
le( command
, GetParent()->GetId() ); 
1670     le
.SetEventObject( GetParent() ); 
1671     le
.m_itemIndex 
= GetIndexOfLine( line 
); 
1672     line
->GetItem( 0, le
.m_item 
); 
1673     GetParent()->GetEventHandler()->ProcessEvent( le 
); 
1674 //    GetParent()->GetEventHandler()->AddPendingEvent( le ); 
1677 void wxListMainWindow::FocusLine( wxListLineData 
*WXUNUSED(line
) ) 
1679 //  SendNotify( line, wxEVT_COMMAND_LIST_ITEM_FOCUSSED ); 
1682 void wxListMainWindow::UnfocusLine( wxListLineData 
*WXUNUSED(line
) ) 
1684 //  SendNotify( line, wxEVT_COMMAND_LIST_ITEM_UNFOCUSSED ); 
1687 void wxListMainWindow::SelectLine( wxListLineData 
*line 
) 
1689     SendNotify( line
, wxEVT_COMMAND_LIST_ITEM_SELECTED 
); 
1692 void wxListMainWindow::DeselectLine( wxListLineData 
*line 
) 
1694     SendNotify( line
, wxEVT_COMMAND_LIST_ITEM_DESELECTED 
); 
1697 void wxListMainWindow::DeleteLine( wxListLineData 
*line 
) 
1699     SendNotify( line
, wxEVT_COMMAND_LIST_DELETE_ITEM 
); 
1704 void wxListMainWindow::EditLabel( long item 
) 
1706     wxCHECK_RET( ((size_t)item 
< m_lines
.GetCount()),  
1707                  wxT("wrong index in wxListCtrl::Edit()") ); 
1709     m_currentEdit 
= &m_lines
[(size_t)item
]; 
1711     wxListEvent 
le( wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT
, GetParent()->GetId() ); 
1712     le
.SetEventObject( GetParent() ); 
1713     le
.m_itemIndex 
= GetIndexOfLine( m_currentEdit 
); 
1714     m_currentEdit
->GetItem( 0, le
.m_item 
); 
1715     GetParent()->GetEventHandler()->ProcessEvent( le 
); 
1717     if (!le
.IsAllowed()) 
1720     // We have to call this here because the label in 
1721     // question might just have been added and no screen 
1722     // update taken place. 
1723     if (m_dirty
) wxYield(); 
1726     m_currentEdit
->GetText( 0, s 
); 
1731     m_currentEdit
->GetLabelExtent( x
, y
, w
, h 
); 
1733     wxClientDC 
dc(this); 
1735     x 
= dc
.LogicalToDeviceX( x 
); 
1736     y 
= dc
.LogicalToDeviceY( y 
); 
1738     wxListTextCtrl 
*text 
= new wxListTextCtrl( 
1739       this, -1, &m_renameAccept
, &m_renameRes
, this, s
, wxPoint(x
-4,y
-4), wxSize(w
+11,h
+8) ); 
1743 void wxListMainWindow::OnRenameTimer() 
1745     wxCHECK_RET( m_current
, wxT("invalid m_current") ); 
1747     Edit( m_lines
.Index( *m_current 
) ); 
1750 void wxListMainWindow::OnRenameAccept() 
1752     wxListEvent 
le( wxEVT_COMMAND_LIST_END_LABEL_EDIT
, GetParent()->GetId() ); 
1753     le
.SetEventObject( GetParent() ); 
1754     le
.m_itemIndex 
= GetIndexOfLine( m_currentEdit 
); 
1755     m_currentEdit
->GetItem( 0, le
.m_item 
); 
1756     le
.m_item
.m_text 
= m_renameRes
; 
1757     GetParent()->GetEventHandler()->ProcessEvent( le 
); 
1759     if (!le
.IsAllowed()) return; 
1762     info
.m_mask 
= wxLIST_MASK_TEXT
; 
1763     info
.m_itemId 
= le
.m_itemIndex
; 
1764     info
.m_text 
= m_renameRes
; 
1765     info
.SetTextColour(le
.m_item
.GetTextColour()); 
1769 void wxListMainWindow::OnMouse( wxMouseEvent 
&event 
) 
1771     if (GetParent()->GetEventHandler()->ProcessEvent( event
)) return; 
1773     if (!m_current
) return; 
1774     if (m_dirty
) return; 
1775     if ( !(event
.Dragging() || event
.ButtonDown() || event
.LeftUp() || event
.ButtonDClick()) ) return; 
1777     int x 
= event
.GetX(); 
1778     int y 
= event
.GetY(); 
1779     CalcUnscrolledPosition( x
, y
, &x
, &y 
); 
1781     /* Did we actually hit an item ? */ 
1783     wxListLineData 
*line 
= (wxListLineData 
*) NULL
; 
1784     for (size_t i 
= 0; i 
< m_lines
.GetCount(); i
++) 
1787         hitResult 
= line
->IsHit( x
, y 
); 
1788         if (hitResult
) break; 
1789         line 
= (wxListLineData 
*) NULL
; 
1792     if (event
.Dragging()) 
1794         if (m_dragCount 
== 0) 
1795             m_dragStart 
= wxPoint(x
,y
); 
1799         if (m_dragCount 
!= 3) return; 
1801         int command 
= wxEVT_COMMAND_LIST_BEGIN_DRAG
; 
1802         if (event
.RightIsDown()) command 
= wxEVT_COMMAND_LIST_BEGIN_RDRAG
; 
1804         wxListEvent 
le( command
, GetParent()->GetId() ); 
1805         le
.SetEventObject( GetParent() ); 
1806         le
.m_pointDrag 
= m_dragStart
; 
1807         GetParent()->GetEventHandler()->ProcessEvent( le 
); 
1818     bool forceClick 
= FALSE
; 
1819     if (event
.ButtonDClick()) 
1821         m_renameTimer
->Stop(); 
1822         m_lastOnSame 
= FALSE
; 
1824         if ( line 
== m_lineBeforeLastClicked 
) 
1828             SendNotify( line
, wxEVT_COMMAND_LIST_ITEM_ACTIVATED 
); 
1834             // the first click was on another item, so don't interpret this as 
1835             // a double click, but as a simple click instead 
1840     if (event
.LeftUp() && m_lastOnSame
) 
1843         if ((line 
== m_current
) && 
1844             (hitResult 
== wxLIST_HITTEST_ONITEMLABEL
) && 
1845             (m_mode 
& wxLC_EDIT_LABELS
)  ) 
1847             m_renameTimer
->Start( 100, TRUE 
); 
1849         m_lastOnSame 
= FALSE
; 
1853     if (event
.RightDown()) 
1855         SendNotify( line
, wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK 
); 
1859     if (event
.MiddleDown()) 
1861         SendNotify( line
, wxEVT_COMMAND_LIST_ITEM_MIDDLE_CLICK 
); 
1865     if ( event
.LeftDown() || forceClick 
) 
1867         m_lineBeforeLastClicked 
= m_lineLastClicked
; 
1868         m_lineLastClicked 
= line
; 
1871         wxListLineData 
*oldCurrent 
= m_current
; 
1872         if (m_mode 
& wxLC_SINGLE_SEL
) 
1875             HilightAll( FALSE 
); 
1876             m_current
->ReverseHilight(); 
1877             RefreshLine( m_current 
); 
1881             if (event
.ControlDown()) 
1884                 m_current
->ReverseHilight(); 
1885                 RefreshLine( m_current 
); 
1887             else if (event
.ShiftDown()) 
1893                 int numOfCurrent 
= -1; 
1894                 for (j 
= 0; j 
< m_lines
.GetCount(); j
++) 
1896                     wxListLineData 
*test_line 
= &m_lines
[j
]; 
1898                     if (test_line 
== oldCurrent
) break; 
1903                 for (j 
= 0; j 
< m_lines
.GetCount(); j
++) 
1905                     wxListLineData 
*test_line 
= &m_lines
[j
]; 
1907                     if (test_line 
== line
) break; 
1910                 if (numOfLine 
< numOfCurrent
) 
1913                     numOfLine 
= numOfCurrent
; 
1917                 for (int i 
= 0; i 
<= numOfLine
-numOfCurrent
; i
++) 
1919                     wxListLineData 
*test_line
= &m_lines
[numOfCurrent 
+ i
]; 
1920                     test_line
->Hilight(TRUE
); 
1921                     RefreshLine( test_line 
); 
1927                 HilightAll( FALSE 
); 
1928                 m_current
->ReverseHilight(); 
1929                 RefreshLine( m_current 
); 
1932         if (m_current 
!= oldCurrent
) 
1934             RefreshLine( oldCurrent 
); 
1935             UnfocusLine( oldCurrent 
); 
1936             FocusLine( m_current 
); 
1939         // forceClick is only set if the previous click was on another item 
1940         m_lastOnSame 
= !forceClick 
&& (m_current 
== oldCurrent
); 
1946 void wxListMainWindow::MoveToFocus() 
1948     if (!m_current
) return; 
1954     m_current
->GetExtent( item_x
, item_y
, item_w
, item_h 
); 
1958     GetClientSize( &client_w
, &client_h 
); 
1960     int view_x 
= m_xScroll
*GetScrollPos( wxHORIZONTAL 
); 
1961     int view_y 
= m_yScroll
*GetScrollPos( wxVERTICAL 
); 
1963     if (m_mode 
& wxLC_REPORT
) 
1965         if (item_y
-5 < view_y 
) 
1966             Scroll( -1, (item_y
-5)/m_yScroll 
); 
1967         if (item_y
+item_h
+5 > view_y
+client_h
) 
1968             Scroll( -1, (item_y
+item_h
-client_h
+15)/m_yScroll 
); 
1972         if (item_x
-view_x 
< 5) 
1973             Scroll( (item_x
-5)/m_xScroll
, -1 ); 
1974         if (item_x
+item_w
-5 > view_x
+client_w
) 
1975             Scroll( (item_x
+item_w
-client_w
+15)/m_xScroll
, -1 ); 
1979 void wxListMainWindow::OnArrowChar( wxListLineData 
*newCurrent
, bool shiftDown 
) 
1981     if ((m_mode 
& wxLC_SINGLE_SEL
) || (m_usedKeys 
== FALSE
)) m_current
->Hilight( FALSE 
); 
1982     wxListLineData 
*oldCurrent 
= m_current
; 
1983     m_current 
= newCurrent
; 
1984     if (shiftDown 
|| (m_mode 
& wxLC_SINGLE_SEL
)) m_current
->Hilight( TRUE 
); 
1985     RefreshLine( m_current 
); 
1986     RefreshLine( oldCurrent 
); 
1987     FocusLine( m_current 
); 
1988     UnfocusLine( oldCurrent 
); 
1992 void wxListMainWindow::OnKeyDown( wxKeyEvent 
&event 
) 
1994     wxWindow 
*parent 
= GetParent(); 
1996     /* we propagate the key event up */ 
1997     wxKeyEvent 
ke( wxEVT_KEY_DOWN 
); 
1998     ke
.m_shiftDown 
= event
.m_shiftDown
; 
1999     ke
.m_controlDown 
= event
.m_controlDown
; 
2000     ke
.m_altDown 
= event
.m_altDown
; 
2001     ke
.m_metaDown 
= event
.m_metaDown
; 
2002     ke
.m_keyCode 
= event
.m_keyCode
; 
2005     ke
.SetEventObject( parent 
); 
2006     if (parent
->GetEventHandler()->ProcessEvent( ke 
)) return; 
2011 void wxListMainWindow::OnChar( wxKeyEvent 
&event 
) 
2013     wxWindow 
*parent 
= GetParent(); 
2015     /* we send a list_key event up */ 
2018         wxListEvent 
le( wxEVT_COMMAND_LIST_KEY_DOWN
, GetParent()->GetId() ); 
2019         le
.m_itemIndex 
= GetIndexOfLine( m_current 
); 
2020         m_current
->GetItem( 0, le
.m_item 
); 
2021         le
.m_code 
= (int)event
.KeyCode(); 
2022         le
.SetEventObject( parent 
); 
2023         parent
->GetEventHandler()->ProcessEvent( le 
); 
2026     /* we propagate the char event up */ 
2027     wxKeyEvent 
ke( wxEVT_CHAR 
); 
2028     ke
.m_shiftDown 
= event
.m_shiftDown
; 
2029     ke
.m_controlDown 
= event
.m_controlDown
; 
2030     ke
.m_altDown 
= event
.m_altDown
; 
2031     ke
.m_metaDown 
= event
.m_metaDown
; 
2032     ke
.m_keyCode 
= event
.m_keyCode
; 
2035     ke
.SetEventObject( parent 
); 
2036     if (parent
->GetEventHandler()->ProcessEvent( ke 
)) return; 
2038     if (event
.KeyCode() == WXK_TAB
) 
2040         wxNavigationKeyEvent nevent
; 
2041         nevent
.SetWindowChange( event
.ControlDown() ); 
2042         nevent
.SetDirection( !event
.ShiftDown() ); 
2043         nevent
.SetEventObject( GetParent()->GetParent() ); 
2044         nevent
.SetCurrentFocus( m_parent 
); 
2045         if (GetParent()->GetParent()->GetEventHandler()->ProcessEvent( nevent 
)) return; 
2048     /* no item -> nothing to do */ 
2055     switch (event
.KeyCode()) 
2059             int index 
= m_lines
.Index(*m_current
); 
2060             if (index 
!= wxNOT_FOUND 
&& index 
> 0) 
2061                 OnArrowChar( &m_lines
[index
-1], event
.ShiftDown() ); 
2066             int index 
= m_lines
.Index(*m_current
); 
2067             if (index 
!= wxNOT_FOUND 
&& (size_t)index 
< m_lines
.GetCount()-1) 
2068                 OnArrowChar( &m_lines
[index
+1], event
.ShiftDown() ); 
2073             if (!m_lines
.IsEmpty()) 
2074                 OnArrowChar( &m_lines
.Last(), event
.ShiftDown() ); 
2079             if (!m_lines
.IsEmpty()) 
2080                 OnArrowChar( &m_lines
[0], event
.ShiftDown() ); 
2086             int index 
= m_lines
.Index(*m_current
); 
2087             if (m_mode 
& wxLC_REPORT
) 
2089                 steps 
= m_visibleLines
-1; 
2093                 steps 
= index 
% m_visibleLines
; 
2095             if (index 
!= wxNOT_FOUND
) 
2098                 if (index 
< 0) index 
= 0;           
2099                 OnArrowChar( &m_lines
[index
], event
.ShiftDown() ); 
2106             int index 
= m_lines
.Index(*m_current
); 
2107             if (m_mode 
& wxLC_REPORT
) 
2109                 steps 
= m_visibleLines
-1; 
2113                 steps 
= m_visibleLines
-(index 
% m_visibleLines
)-1; 
2116             if (index 
!= wxNOT_FOUND
) 
2119                 if ((size_t)index 
>= m_lines
.GetCount())  
2120                     index 
= m_lines
.GetCount()-1; 
2121                 OnArrowChar( &m_lines
[index
], event
.ShiftDown() ); 
2127             if (!(m_mode 
& wxLC_REPORT
)) 
2129                 int index 
= m_lines
.Index(*m_current
); 
2130                 if (index 
!= wxNOT_FOUND
) 
2132                     index 
-= m_visibleLines
; 
2133                     if (index 
< 0) index 
= 0; 
2134                     OnArrowChar( &m_lines
[index
], event
.ShiftDown() ); 
2141             if (!(m_mode 
& wxLC_REPORT
)) 
2143                 int index 
= m_lines
.Index(*m_current
); 
2144                 if (index 
!= wxNOT_FOUND
) 
2146                     index 
+= m_visibleLines
; 
2147                     if ((size_t)index 
>= m_lines
.GetCount())  
2148                         index 
= m_lines
.GetCount()-1; 
2149                     OnArrowChar( &m_lines
[index
], event
.ShiftDown() ); 
2156             if (m_mode 
& wxLC_SINGLE_SEL
) 
2158                 wxListEvent 
le( wxEVT_COMMAND_LIST_ITEM_ACTIVATED
, GetParent()->GetId() ); 
2159                 le
.SetEventObject( GetParent() ); 
2160                 le
.m_itemIndex 
= GetIndexOfLine( m_current 
); 
2161                 m_current
->GetItem( 0, le
.m_item 
); 
2162                 GetParent()->GetEventHandler()->ProcessEvent( le 
); 
2166                 m_current
->ReverseHilight(); 
2167                 RefreshLine( m_current 
); 
2173             if (!(m_mode 
& wxLC_SINGLE_SEL
)) 
2175                 wxListLineData 
*oldCurrent 
= m_current
; 
2176                 m_current
->ReverseHilight(); 
2177                 int index 
= m_lines
.Index( *m_current 
) + 1; 
2178                 if ( (size_t)index 
< m_lines
.GetCount() ) 
2179                     m_current 
= &m_lines
[index
]; 
2180                 RefreshLine( oldCurrent 
); 
2181                 RefreshLine( m_current 
); 
2182                 UnfocusLine( oldCurrent 
); 
2183                 FocusLine( m_current 
); 
2191             wxListEvent 
le( wxEVT_COMMAND_LIST_ITEM_ACTIVATED
, GetParent()->GetId() ); 
2192             le
.SetEventObject( GetParent() ); 
2193             le
.m_itemIndex 
= GetIndexOfLine( m_current 
); 
2194             m_current
->GetItem( 0, le
.m_item 
); 
2195             GetParent()->GetEventHandler()->ProcessEvent( le 
); 
2208 extern wxWindow 
*g_focusWindow
; 
2211 void wxListMainWindow::OnSetFocus( wxFocusEvent 
&WXUNUSED(event
) ) 
2214     RefreshLine( m_current 
); 
2216     if (!GetParent()) return; 
2219     g_focusWindow 
= GetParent(); 
2222     wxFocusEvent 
event( wxEVT_SET_FOCUS
, GetParent()->GetId() ); 
2223     event
.SetEventObject( GetParent() ); 
2224     GetParent()->GetEventHandler()->ProcessEvent( event 
); 
2227 void wxListMainWindow::OnKillFocus( wxFocusEvent 
&WXUNUSED(event
) ) 
2230     RefreshLine( m_current 
); 
2233 void wxListMainWindow::OnSize( wxSizeEvent 
&WXUNUSED(event
) ) 
2236   We don't even allow the wxScrolledWindow::AdjustScrollbars() call 
2242 void wxListMainWindow::DrawImage( int index
, wxDC 
*dc
, int x
, int y 
) 
2244     if ((m_mode 
& wxLC_ICON
) && (m_normal_image_list
)) 
2246         m_normal_image_list
->Draw( index
, *dc
, x
, y
, wxIMAGELIST_DRAW_TRANSPARENT 
); 
2249     if ((m_mode 
& wxLC_SMALL_ICON
) && (m_small_image_list
)) 
2251         m_small_image_list
->Draw( index
, *dc
, x
, y
, wxIMAGELIST_DRAW_TRANSPARENT 
); 
2253     if ((m_mode 
& wxLC_LIST
) && (m_small_image_list
)) 
2255         m_small_image_list
->Draw( index
, *dc
, x
, y
, wxIMAGELIST_DRAW_TRANSPARENT 
); 
2257     if ((m_mode 
& wxLC_REPORT
) && (m_small_image_list
)) 
2259         m_small_image_list
->Draw( index
, *dc
, x
, y
, wxIMAGELIST_DRAW_TRANSPARENT 
); 
2264 void wxListMainWindow::GetImageSize( int index
, int &width
, int &height 
) 
2266     if ((m_mode 
& wxLC_ICON
) && (m_normal_image_list
)) 
2268         m_normal_image_list
->GetSize( index
, width
, height 
); 
2271     if ((m_mode 
& wxLC_SMALL_ICON
) && (m_small_image_list
)) 
2273         m_small_image_list
->GetSize( index
, width
, height 
); 
2276     if ((m_mode 
& wxLC_LIST
) && (m_small_image_list
)) 
2278         m_small_image_list
->GetSize( index
, width
, height 
); 
2281     if ((m_mode 
& wxLC_REPORT
) && (m_small_image_list
)) 
2283         m_small_image_list
->GetSize( index
, width
, height 
); 
2290 int wxListMainWindow::GetTextLength( wxString 
&s 
) 
2292     wxClientDC 
dc( this ); 
2295     dc
.GetTextExtent( s
, &lw
, &lh 
); 
2299 int wxListMainWindow::GetIndexOfLine( const wxListLineData 
*line 
) 
2301     int i 
= m_lines
.Index(*line
); 
2302     if (i 
== wxNOT_FOUND
) return -1; 
2306 void wxListMainWindow::SetImageList( wxImageList 
*imageList
, int which 
) 
2310     // calc the spacing from the icon size 
2313     if ((imageList
) && (imageList
->GetImageCount()) ) 
2315         imageList
->GetSize(0, width
, height
); 
2318     if (which 
== wxIMAGE_LIST_NORMAL
) 
2320         m_normal_image_list 
= imageList
; 
2321         m_normal_spacing 
= width 
+ 8; 
2324     if (which 
== wxIMAGE_LIST_SMALL
) 
2326         m_small_image_list 
= imageList
; 
2327         m_small_spacing 
= width 
+ 14; 
2331 void wxListMainWindow::SetItemSpacing( int spacing
, bool isSmall 
) 
2336         m_small_spacing 
= spacing
; 
2340         m_normal_spacing 
= spacing
; 
2344 int wxListMainWindow::GetItemSpacing( bool isSmall 
) 
2346     return isSmall 
? m_small_spacing 
: m_normal_spacing
; 
2349 void wxListMainWindow::SetColumn( int col
, wxListItem 
&item 
) 
2352     wxNode 
*node 
= m_columns
.Nth( col 
); 
2355         if (item
.m_width 
== wxLIST_AUTOSIZE_USEHEADER
) item
.m_width 
= GetTextLength( item
.m_text 
)+7; 
2356         wxListHeaderData 
*column 
= (wxListHeaderData
*)node
->Data(); 
2357         column
->SetItem( item 
); 
2360     wxListHeaderWindow 
*headerWin 
= ((wxListCtrl
*) GetParent())->m_headerWin
; 
2362         headerWin
->m_dirty 
= TRUE
; 
2365 void wxListMainWindow::SetColumnWidth( int col
, int width 
) 
2367     wxCHECK_RET( m_mode 
& wxLC_REPORT
, 
2368                  _T("SetColumnWidth() can only be called in report mode.") ); 
2372     wxNode 
*node 
= (wxNode
*) NULL
; 
2374     if (width 
== wxLIST_AUTOSIZE_USEHEADER
) 
2376         // TODO do use the header 
2379     else if (width 
== wxLIST_AUTOSIZE
) 
2381         wxClientDC 
dc(this); 
2382         dc
.SetFont( GetFont() ); 
2385         for (size_t i 
= 0; i 
< m_lines
.GetCount(); i
++) 
2387             wxListLineData 
*line 
= &m_lines
[i
]; 
2388             wxNode 
*n 
= line
->m_items
.Nth( col 
); 
2391                 wxListItemData 
*item 
= (wxListItemData
*)n
->Data(); 
2392                 int current 
= 0, ix 
= 0, iy 
= 0; 
2393                 wxCoord lx 
= 0, ly 
= 0; 
2394                 if (item
->HasImage()) 
2396                     GetImageSize( item
->GetImage(), ix
, iy 
); 
2399                 if (item
->HasText()) 
2402                     item
->GetText( str 
); 
2403                     dc
.GetTextExtent( str
, &lx
, &ly 
); 
2406                 if (current 
> max
) max 
= current
; 
2412     node 
= m_columns
.Nth( col 
); 
2415         wxListHeaderData 
*column 
= (wxListHeaderData
*)node
->Data(); 
2416         column
->SetWidth( width 
); 
2419     for (size_t i 
= 0; i 
< m_lines
.GetCount(); i
++) 
2421         wxListLineData 
*line 
= &m_lines
[i
]; 
2422         wxNode 
*n 
= line
->m_items
.Nth( col 
); 
2425             wxListItemData 
*item 
= (wxListItemData
*)n
->Data(); 
2426             item
->SetSize( width
, -1 ); 
2430     wxListHeaderWindow 
*headerWin 
= ((wxListCtrl
*) GetParent())->m_headerWin
; 
2432         headerWin
->m_dirty 
= TRUE
; 
2435 void wxListMainWindow::GetColumn( int col
, wxListItem 
&item 
) 
2437     wxNode 
*node 
= m_columns
.Nth( col 
); 
2440         wxListHeaderData 
*column 
= (wxListHeaderData
*)node
->Data(); 
2441         column
->GetItem( item 
); 
2453 int wxListMainWindow::GetColumnWidth( int col 
) 
2455     wxNode 
*node 
= m_columns
.Nth( col 
); 
2458         wxListHeaderData 
*column 
= (wxListHeaderData
*)node
->Data(); 
2459         return column
->GetWidth(); 
2467 int wxListMainWindow::GetColumnCount() 
2469     return m_columns
.Number(); 
2472 int wxListMainWindow::GetCountPerPage() 
2474     return m_visibleLines
; 
2477 void wxListMainWindow::SetItem( wxListItem 
&item 
) 
2480     if (item
.m_itemId 
>= 0 && (size_t)item
.m_itemId 
< m_lines
.GetCount()) 
2482         wxListLineData 
*line 
= &m_lines
[(size_t)item
.m_itemId
]; 
2483         if (m_mode 
& wxLC_REPORT
) item
.m_width 
= GetColumnWidth( item
.m_col 
)-3; 
2484         line
->SetItem( item
.m_col
, item 
); 
2488 void wxListMainWindow::SetItemState( long item
, long state
, long stateMask 
) 
2490     // m_dirty = TRUE; no recalcs needed 
2492     wxListLineData 
*oldCurrent 
= m_current
; 
2494     if (stateMask 
& wxLIST_STATE_FOCUSED
) 
2496         if (item 
>= 0 && (size_t)item 
< m_lines
.GetCount()) 
2498             wxListLineData 
*line 
= &m_lines
[(size_t)item
]; 
2499             UnfocusLine( m_current 
); 
2501             FocusLine( m_current 
); 
2502             if ((m_mode 
& wxLC_SINGLE_SEL
) && oldCurrent
) oldCurrent
->Hilight( FALSE 
); 
2503             RefreshLine( m_current 
); 
2504             if (oldCurrent
) RefreshLine( oldCurrent 
); 
2508     if (stateMask 
& wxLIST_STATE_SELECTED
) 
2510         bool on 
= (state 
& wxLIST_STATE_SELECTED
) != 0; 
2511         if (!on 
&& (m_mode 
& wxLC_SINGLE_SEL
)) return; 
2513         if (item 
>= 0 && (size_t)item 
< m_lines
.GetCount()) 
2515             wxListLineData 
*line 
= &m_lines
[(size_t)item
]; 
2516             if (m_mode 
& wxLC_SINGLE_SEL
) 
2518                 UnfocusLine( m_current 
); 
2520                 FocusLine( m_current 
); 
2521                 if (oldCurrent
) oldCurrent
->Hilight( FALSE 
); 
2522                 RefreshLine( m_current 
); 
2523                 if (oldCurrent
) RefreshLine( oldCurrent 
); 
2525             bool on 
= (state 
& wxLIST_STATE_SELECTED
) != 0; 
2526             if (on 
!= line
->IsHilighted()) 
2528                 line
->Hilight( on 
); 
2529                 RefreshLine( line 
); 
2535 int wxListMainWindow::GetItemState( long item
, long stateMask 
) 
2537     int ret 
= wxLIST_STATE_DONTCARE
; 
2538     if (stateMask 
& wxLIST_STATE_FOCUSED
) 
2540         if (item 
>= 0 && (size_t)item 
< m_lines
.GetCount()) 
2542             wxListLineData 
*line 
= &m_lines
[(size_t)item
]; 
2543             if (line 
== m_current
) ret 
|= wxLIST_STATE_FOCUSED
; 
2546     if (stateMask 
& wxLIST_STATE_SELECTED
) 
2548         if (item 
>= 0 && (size_t)item 
< m_lines
.GetCount()) 
2550             wxListLineData 
*line 
= &m_lines
[(size_t)item
]; 
2551             if (line
->IsHilighted()) ret 
|= wxLIST_STATE_FOCUSED
; 
2557 void wxListMainWindow::GetItem( wxListItem 
&item 
) 
2559     if (item
.m_itemId 
>= 0 && (size_t)item
.m_itemId 
< m_lines
.GetCount()) 
2561         wxListLineData 
*line 
= &m_lines
[(size_t)item
.m_itemId
]; 
2562         line
->GetItem( item
.m_col
, item 
); 
2573 int wxListMainWindow::GetItemCount() 
2575     return m_lines
.GetCount(); 
2578 void wxListMainWindow::GetItemRect( long index
, wxRect 
&rect 
) 
2580     if (index 
>= 0 && (size_t)index 
< m_lines
.GetCount()) 
2582         m_lines
[(size_t)index
].GetRect( rect 
); 
2593 bool wxListMainWindow::GetItemPosition(long item
, wxPoint
& pos
) 
2595     if (item 
>= 0 && (size_t)item 
< m_lines
.GetCount()) 
2598         m_lines
[(size_t)item
].GetRect( rect 
); 
2610 int wxListMainWindow::GetSelectedItemCount() 
2613     for (size_t i 
= 0; i 
< m_lines
.GetCount(); i
++) 
2615         if (m_lines
[i
].IsHilighted()) ret
++; 
2620 void wxListMainWindow::SetMode( long mode 
) 
2627     if (m_mode 
& wxLC_REPORT
) 
2629 #if wxUSE_GENERIC_LIST_EXTENSIONS 
2643 long wxListMainWindow::GetMode() const 
2648 void wxListMainWindow::CalculatePositions() 
2650     if (m_lines
.IsEmpty()) return; 
2652     wxClientDC 
dc( this ); 
2653     dc
.SetFont( GetFont() ); 
2655     int iconSpacing 
= 0; 
2656     if (m_mode 
& wxLC_ICON
) iconSpacing 
= m_normal_spacing
; 
2657     if (m_mode 
& wxLC_SMALL_ICON
) iconSpacing 
= m_small_spacing
; 
2659     // we take the first line (which also can be an icon or 
2660     // an a text item in wxLC_ICON and wxLC_LIST modes) to 
2661     // measure the size of the line 
2665     int lineSpacing 
= 0; 
2667     wxListLineData 
*line 
= &m_lines
[0]; 
2668     line
->CalculateSize( &dc
, iconSpacing 
); 
2670     line
->GetSize( dummy
, lineSpacing 
); 
2673     int clientWidth 
= 0; 
2674     int clientHeight 
= 0; 
2676     if (m_mode 
& wxLC_REPORT
) 
2680         int entireHeight 
= m_lines
.GetCount() * lineSpacing 
+ 2; 
2681         int scroll_pos 
= GetScrollPos( wxVERTICAL 
); 
2682 #if wxUSE_GENERIC_LIST_EXTENSIONS 
2683         int x_scroll_pos 
= GetScrollPos( wxHORIZONTAL 
); 
2685         SetScrollbars( m_xScroll
, m_yScroll
, 0, (entireHeight
+15) / m_yScroll
, 0, scroll_pos
, TRUE 
); 
2687         GetClientSize( &clientWidth
, &clientHeight 
); 
2689         int entireWidth 
= 0 ; 
2690         for (size_t j 
= 0; j 
< m_lines
.GetCount(); j
++) 
2692             wxListLineData 
*line 
= &m_lines
[j
]; 
2693             line
->CalculateSize( &dc
, iconSpacing 
); 
2694             line
->SetPosition( &dc
, x
, y
, clientWidth 
); 
2696             for (int i 
= 0; i 
< GetColumnCount(); i
++) 
2698                 line
->SetColumnPosition( i
, col_x 
); 
2699                 col_x 
+= GetColumnWidth( i 
); 
2701             entireWidth 
= wxMax( entireWidth 
, col_x 
) ; 
2702 #if wxUSE_GENERIC_LIST_EXTENSIONS 
2703             line
->SetPosition( &dc
, x
, y
, col_x 
); 
2705             y 
+= lineSpacing
;  // one pixel blank line between items 
2707                 m_visibleLines 
= clientHeight 
/ lineSpacing
; 
2708 #if wxUSE_GENERIC_LIST_EXTENSIONS 
2709                 SetScrollbars( m_xScroll
, m_yScroll
, entireWidth 
/ m_xScroll 
, (entireHeight
+15) / m_yScroll
, x_scroll_pos  
, scroll_pos
, TRUE 
); 
2714         // at first we try without any scrollbar. if the items don't 
2715         // fit into the window, we recalculate after subtracting an 
2716         // approximated 15 pt for the horizontal scrollbar 
2718         GetSize( &clientWidth
, &clientHeight 
); 
2719         clientHeight 
-= 4;  // sunken frame 
2721         int entireWidth 
= 0; 
2723         for (int tries 
= 0; tries 
< 2; tries
++) 
2730             int m_currentVisibleLines 
= 0; 
2731             for (size_t i 
= 0; i 
< m_lines
.GetCount(); i
++) 
2733                 m_currentVisibleLines
++; 
2734                 wxListLineData 
*line 
= &m_lines
[i
]; 
2735                 line
->CalculateSize( &dc
, iconSpacing 
); 
2736                 line
->SetPosition( &dc
, x
, y
, clientWidth 
); 
2737                 line
->GetSize( lineWidth
, lineHeight 
); 
2738                 if (lineWidth 
> maxWidth
) maxWidth 
= lineWidth
; 
2740                 if (m_currentVisibleLines 
> m_visibleLines
) 
2741                     m_visibleLines 
= m_currentVisibleLines
; 
2742                 if (y
+lineSpacing
-6 >= clientHeight
) // -6 for earlier "line breaking" 
2744                     m_currentVisibleLines 
= 0; 
2747                     entireWidth 
+= maxWidth
+6; 
2750                 if (i 
== m_lines
.GetCount()-1) entireWidth 
+= maxWidth
; 
2751                 if ((tries 
== 0) && (entireWidth 
> clientWidth
)) 
2753                     clientHeight 
-= 15; // scrollbar height 
2755                     m_currentVisibleLines 
= 0; 
2758                 if (i 
== m_lines
.GetCount()-1) tries 
= 1;  // everything fits, no second try required 
2762         int scroll_pos 
= GetScrollPos( wxHORIZONTAL 
); 
2763         SetScrollbars( m_xScroll
, m_yScroll
, (entireWidth
+15) / m_xScroll
, 0, scroll_pos
, 0, TRUE 
); 
2767 void wxListMainWindow::RealizeChanges() 
2771         if (!m_lines
.IsEmpty()) 
2772             m_current 
= &m_lines
[0]; 
2776         FocusLine( m_current 
); 
2777         // TODO: MSW doesn't automatically hilight the 
2779         // if (m_mode & wxLC_SINGLE_SEL) m_current->Hilight( TRUE ); 
2783 long wxListMainWindow::GetNextItem( long item
, 
2784                                     int WXUNUSED(geometry
), 
2788          max 
= GetItemCount(); 
2789     wxCHECK_MSG( (ret 
== -1) || (ret 
< max
), -1, 
2790                  _T("invalid listctrl index in GetNextItem()") ); 
2792     // notice that we start with the next item (or the first one if item == -1) 
2793     // and this is intentional to allow writing a simple loop to iterate over 
2794     // all selected items 
2798         // this is not an error because the index was ok initially, just no 
2803     for (size_t i 
= (size_t)ret
; i 
< m_lines
.GetCount(); i
++) 
2805         wxListLineData 
*line 
= &m_lines
[i
]; 
2806         if ((state 
& wxLIST_STATE_FOCUSED
) && (line 
== m_current
)) 
2808         if ((state 
& wxLIST_STATE_SELECTED
) && (line
->IsHilighted())) 
2818 void wxListMainWindow::DeleteItem( long index 
) 
2821     if (index 
>= 0 && (size_t)index 
< m_lines
.GetCount()) 
2823         wxListLineData 
*line 
= &m_lines
[(size_t)index
]; 
2824         if (m_current 
== line
) m_current 
= (wxListLineData 
*) NULL
; 
2826         m_lines
.RemoveAt( (size_t)index 
); 
2830 void wxListMainWindow::DeleteColumn( int col 
) 
2832     wxCHECK_RET( col 
< (int)m_columns
.GetCount(), 
2833                wxT("attempting to delete inexistent column in wxListView") ); 
2836     wxNode 
*node 
= m_columns
.Nth( col 
); 
2837     if (node
) m_columns
.DeleteNode( node 
); 
2840 void wxListMainWindow::DeleteAllItems() 
2843     m_current 
= (wxListLineData 
*) NULL
; 
2845     // to make the deletion of all items faster, we don't send the 
2846     // notifications in this case: this is compatible with wxMSW and 
2847     // documented in DeleteAllItems() description 
2849     wxListEvent 
event( wxEVT_COMMAND_LIST_DELETE_ALL_ITEMS
, GetParent()->GetId() ); 
2850     event
.SetEventObject( GetParent() ); 
2851     GetParent()->GetEventHandler()->ProcessEvent( event 
); 
2856 void wxListMainWindow::DeleteEverything() 
2863 void wxListMainWindow::EnsureVisible( long index 
) 
2865     // We have to call this here because the label in 
2866     // question might just have been added and no screen 
2867     // update taken place. 
2868     if (m_dirty
) wxYield(); 
2870     wxListLineData 
*oldCurrent 
= m_current
; 
2871     m_current 
= (wxListLineData 
*) NULL
; 
2872     if (index 
>= 0 && (size_t)index 
< m_lines
.GetCount()) 
2873         m_current 
= &m_lines
[(size_t)index
]; 
2874     if (m_current
) MoveToFocus(); 
2875     m_current 
= oldCurrent
; 
2878 long wxListMainWindow::FindItem(long start
, const wxString
& str
, bool WXUNUSED(partial
) ) 
2882     if (pos 
< 0) pos 
= 0; 
2883     for (size_t i 
= pos
; i 
< m_lines
.GetCount(); i
++) 
2885         wxListLineData 
*line 
= &m_lines
[i
]; 
2887         line
->GetText( 0, s 
); 
2888         if (s 
== tmp
) return pos
; 
2894 long wxListMainWindow::FindItem(long start
, long data
) 
2897     if (pos 
< 0) pos 
= 0; 
2898     for (size_t i 
= pos
; i 
< m_lines
.GetCount(); i
++) 
2900         wxListLineData 
*line 
= &m_lines
[i
]; 
2902         line
->GetItem( 0, item 
); 
2903         if (item
.m_data 
== data
) return pos
; 
2909 long wxListMainWindow::HitTest( int x
, int y
, int &flags 
) 
2911     CalcUnscrolledPosition( x
, y
, &x
, &y 
); 
2914     for (size_t i 
= 0; i 
< m_lines
.GetCount(); i
++) 
2916         wxListLineData 
*line 
= &m_lines
[i
]; 
2917         long ret 
= line
->IsHit( x
, y 
); 
2928 void wxListMainWindow::InsertItem( wxListItem 
&item 
) 
2932     if (m_mode 
& wxLC_REPORT
) mode 
= wxLC_REPORT
; 
2933     else if (m_mode 
& wxLC_LIST
) mode 
= wxLC_LIST
; 
2934     else if (m_mode 
& wxLC_ICON
) mode 
= wxLC_ICON
; 
2935     else if (m_mode 
& wxLC_SMALL_ICON
) mode 
= wxLC_ICON
;  // no typo 
2937     wxListLineData 
*line 
= new wxListLineData( this, mode
, m_hilightBrush 
); 
2939     if (m_mode 
& wxLC_REPORT
) 
2941         line
->InitItems( GetColumnCount() ); 
2942         item
.m_width 
= GetColumnWidth( 0 )-3; 
2946         line
->InitItems( 1 ); 
2949     line
->SetItem( 0, item 
); 
2950     if ((item
.m_itemId 
>= 0) && ((size_t)item
.m_itemId 
< m_lines
.GetCount())) 
2952         m_lines
.Insert( line
, (size_t)item
.m_itemId 
); 
2956         m_lines
.Add( line 
); 
2960 void wxListMainWindow::InsertColumn( long col
, wxListItem 
&item 
) 
2963     if (m_mode 
& wxLC_REPORT
) 
2965         if (item
.m_width 
== wxLIST_AUTOSIZE_USEHEADER
) item
.m_width 
= GetTextLength( item
.m_text 
); 
2966         wxListHeaderData 
*column 
= new wxListHeaderData( item 
); 
2967         if ((col 
>= 0) && (col 
< (int)m_columns
.GetCount())) 
2969             wxNode 
*node 
= m_columns
.Nth( (size_t)col 
); 
2971                  m_columns
.Insert( node
, column 
); 
2975             m_columns
.Append( column 
); 
2980 wxListCtrlCompare list_ctrl_compare_func_2
; 
2981 long              list_ctrl_compare_data
; 
2983 int LINKAGEMODE 
list_ctrl_compare_func_1( wxListLineData 
**arg1
, wxListLineData 
**arg2 
) 
2985     wxListLineData 
*line1 
= *arg1
; 
2986     wxListLineData 
*line2 
= *arg2
; 
2988     line1
->GetItem( 0, item 
); 
2989     long data1 
= item
.m_data
; 
2990     line2
->GetItem( 0, item 
); 
2991     long data2 
= item
.m_data
; 
2992     return list_ctrl_compare_func_2( data1
, data2
, list_ctrl_compare_data 
); 
2995 void wxListMainWindow::SortItems( wxListCtrlCompare fn
, long data 
) 
2997     list_ctrl_compare_func_2 
= fn
; 
2998     list_ctrl_compare_data 
= data
; 
2999     m_lines
.Sort( list_ctrl_compare_func_1 
); 
3003 void wxListMainWindow::OnScroll(wxScrollWinEvent
& event
) 
3005         wxScrolledWindow::OnScroll( event 
) ; 
3006 #if wxUSE_GENERIC_LIST_EXTENSIONS 
3008     if (event
.GetOrientation() == wxHORIZONTAL 
&& ( m_mode 
& wxLC_REPORT 
)) 
3010             wxListCtrl
* lc 
= wxDynamicCast( GetParent() , wxListCtrl 
) ; 
3013                     lc
->m_headerWin
->Refresh() ; 
3015                         lc
->m_headerWin
->MacUpdateImmediately() ; 
3022 // ------------------------------------------------------------------------------------- 
3024 // ------------------------------------------------------------------------------------- 
3026 IMPLEMENT_DYNAMIC_CLASS(wxListItem
, wxObject
) 
3028 wxListItem::wxListItem() 
3037     m_format 
= wxLIST_FORMAT_CENTRE
; 
3043 void wxListItem::Clear() 
3052     m_format 
= wxLIST_FORMAT_CENTRE
; 
3054     m_text 
= wxEmptyString
; 
3056     if (m_attr
) delete m_attr
; 
3060 void wxListItem::ClearAttributes() 
3062     if (m_attr
) delete m_attr
; 
3066 // ------------------------------------------------------------------------------------- 
3068 // ------------------------------------------------------------------------------------- 
3070 IMPLEMENT_DYNAMIC_CLASS(wxListEvent
, wxNotifyEvent
) 
3072 wxListEvent::wxListEvent( wxEventType commandType
, int id 
): 
3073   wxNotifyEvent( commandType
, id 
) 
3079     m_cancelled 
= FALSE
; 
3084 void wxListEvent::CopyObject(wxObject
& object_dest
) const 
3086     wxListEvent 
*obj 
= (wxListEvent 
*)&object_dest
; 
3088     wxNotifyEvent::CopyObject(object_dest
); 
3090     obj
->m_code 
= m_code
; 
3091     obj
->m_itemIndex 
= m_itemIndex
; 
3092     obj
->m_oldItemIndex 
= m_oldItemIndex
; 
3094     obj
->m_cancelled 
= m_cancelled
; 
3095     obj
->m_pointDrag 
= m_pointDrag
; 
3096     obj
->m_item
.m_mask 
= m_item
.m_mask
; 
3097     obj
->m_item
.m_itemId 
= m_item
.m_itemId
; 
3098     obj
->m_item
.m_col 
= m_item
.m_col
; 
3099     obj
->m_item
.m_state 
= m_item
.m_state
; 
3100     obj
->m_item
.m_stateMask 
= m_item
.m_stateMask
; 
3101     obj
->m_item
.m_text 
= m_item
.m_text
; 
3102     obj
->m_item
.m_image 
= m_item
.m_image
; 
3103     obj
->m_item
.m_data 
= m_item
.m_data
; 
3104     obj
->m_item
.m_format 
= m_item
.m_format
; 
3105     obj
->m_item
.m_width 
= m_item
.m_width
; 
3107     if ( m_item
.HasAttributes() ) 
3109         obj
->m_item
.SetTextColour(m_item
.GetTextColour()); 
3113 // ------------------------------------------------------------------------------------- 
3115 // ------------------------------------------------------------------------------------- 
3117 IMPLEMENT_DYNAMIC_CLASS(wxListCtrl
, wxControl
) 
3119 BEGIN_EVENT_TABLE(wxListCtrl
,wxControl
) 
3120   EVT_SIZE          (wxListCtrl::OnSize
) 
3121   EVT_IDLE          (wxListCtrl::OnIdle
) 
3124 wxListCtrl::wxListCtrl() 
3126     m_imageListNormal 
= (wxImageList 
*) NULL
; 
3127     m_imageListSmall 
= (wxImageList 
*) NULL
; 
3128     m_imageListState 
= (wxImageList 
*) NULL
; 
3129     m_mainWin 
= (wxListMainWindow
*) NULL
; 
3130     m_headerWin 
= (wxListHeaderWindow
*) NULL
; 
3133 wxListCtrl::~wxListCtrl() 
3137 bool wxListCtrl::Create(wxWindow 
*parent
, 
3142                         const wxValidator 
&validator
, 
3143                         const wxString 
&name
) 
3145     m_imageListNormal 
= (wxImageList 
*) NULL
; 
3146     m_imageListSmall 
= (wxImageList 
*) NULL
; 
3147     m_imageListState 
= (wxImageList 
*) NULL
; 
3148     m_mainWin 
= (wxListMainWindow
*) NULL
; 
3149     m_headerWin 
= (wxListHeaderWindow
*) NULL
; 
3151     if ( !(style 
& (wxLC_REPORT 
| wxLC_LIST 
| wxLC_ICON
)) ) 
3153         style 
= style 
| wxLC_LIST
; 
3156     bool ret 
= wxControl::Create( parent
, id
, pos
, size
, style
, validator
, name 
); 
3159     if (style 
& wxSUNKEN_BORDER
) 
3160         style 
-= wxSUNKEN_BORDER
; 
3162     m_mainWin 
= new wxListMainWindow( this, -1, wxPoint(0,0), size
, style 
); 
3164     if (HasFlag(wxLC_REPORT
)) 
3166         m_headerWin 
= new wxListHeaderWindow( this, -1, m_mainWin
, wxPoint(0,0), wxSize(size
.x
,23), wxTAB_TRAVERSAL 
); 
3167         if (HasFlag(wxLC_NO_HEADER
)) 
3168             m_headerWin
->Show( FALSE 
); 
3172         m_headerWin 
= (wxListHeaderWindow 
*) NULL
; 
3178 void wxListCtrl::OnSize( wxSizeEvent 
&WXUNUSED(event
) ) 
3180     /* handled in OnIdle */ 
3182     if (m_mainWin
) m_mainWin
->m_dirty 
= TRUE
; 
3185 void wxListCtrl::SetSingleStyle( long style
, bool add 
) 
3187     long flag 
= GetWindowStyle(); 
3191         if (style 
& wxLC_MASK_TYPE
)  flag 
= flag 
& ~wxLC_MASK_TYPE
; 
3192         if (style 
& wxLC_MASK_ALIGN
) flag 
= flag 
& ~wxLC_MASK_ALIGN
; 
3193         if (style 
& wxLC_MASK_SORT
) flag 
= flag 
& ~wxLC_MASK_SORT
; 
3202         if (flag 
& style
) flag 
-= style
; 
3205     SetWindowStyleFlag( flag 
); 
3208 void wxListCtrl::SetWindowStyleFlag( long flag 
) 
3212         m_mainWin
->DeleteEverything(); 
3216         GetClientSize( &width
, &height 
); 
3218         m_mainWin
->SetMode( flag 
); 
3220         if (flag 
& wxLC_REPORT
) 
3222             if (!HasFlag(wxLC_REPORT
)) 
3226                     m_headerWin 
= new wxListHeaderWindow( this, -1, m_mainWin
, 
3227                       wxPoint(0,0), wxSize(width
,23), wxTAB_TRAVERSAL 
); 
3228                     if (HasFlag(wxLC_NO_HEADER
)) 
3229                         m_headerWin
->Show( FALSE 
); 
3233                     if (flag 
& wxLC_NO_HEADER
) 
3234                         m_headerWin
->Show( FALSE 
); 
3236                         m_headerWin
->Show( TRUE 
); 
3242             if (HasFlag(wxLC_REPORT
) && !(HasFlag(wxLC_NO_HEADER
))) 
3244                 m_headerWin
->Show( FALSE 
); 
3249     wxWindow::SetWindowStyleFlag( flag 
); 
3252 bool wxListCtrl::GetColumn(int col
, wxListItem 
&item
) const 
3254     m_mainWin
->GetColumn( col
, item 
); 
3258 bool wxListCtrl::SetColumn( int col
, wxListItem
& item 
) 
3260     m_mainWin
->SetColumn( col
, item 
); 
3264 int wxListCtrl::GetColumnWidth( int col 
) const 
3266     return m_mainWin
->GetColumnWidth( col 
); 
3269 bool wxListCtrl::SetColumnWidth( int col
, int width 
) 
3271     m_mainWin
->SetColumnWidth( col
, width 
); 
3275 int wxListCtrl::GetCountPerPage() const 
3277   return m_mainWin
->GetCountPerPage();  // different from Windows ? 
3280 bool wxListCtrl::GetItem( wxListItem 
&info 
) const 
3282     m_mainWin
->GetItem( info 
); 
3286 bool wxListCtrl::SetItem( wxListItem 
&info 
) 
3288     m_mainWin
->SetItem( info 
); 
3292 long wxListCtrl::SetItem( long index
, int col
, const wxString
& label
, int imageId 
) 
3295     info
.m_text 
= label
; 
3296     info
.m_mask 
= wxLIST_MASK_TEXT
; 
3297     info
.m_itemId 
= index
; 
3301         info
.m_image 
= imageId
; 
3302         info
.m_mask 
|= wxLIST_MASK_IMAGE
; 
3304     m_mainWin
->SetItem(info
); 
3308 int wxListCtrl::GetItemState( long item
, long stateMask 
) const 
3310     return m_mainWin
->GetItemState( item
, stateMask 
); 
3313 bool wxListCtrl::SetItemState( long item
, long state
, long stateMask 
) 
3315     m_mainWin
->SetItemState( item
, state
, stateMask 
); 
3319 bool wxListCtrl::SetItemImage( long item
, int image
, int WXUNUSED(selImage
) ) 
3322     info
.m_image 
= image
; 
3323     info
.m_mask 
= wxLIST_MASK_IMAGE
; 
3324     info
.m_itemId 
= item
; 
3325     m_mainWin
->SetItem( info 
); 
3329 wxString 
wxListCtrl::GetItemText( long item 
) const 
3332     info
.m_itemId 
= item
; 
3333     m_mainWin
->GetItem( info 
); 
3337 void wxListCtrl::SetItemText( long item
, const wxString 
&str 
) 
3340     info
.m_mask 
= wxLIST_MASK_TEXT
; 
3341     info
.m_itemId 
= item
; 
3343     m_mainWin
->SetItem( info 
); 
3346 long wxListCtrl::GetItemData( long item 
) const 
3349     info
.m_itemId 
= item
; 
3350     m_mainWin
->GetItem( info 
); 
3354 bool wxListCtrl::SetItemData( long item
, long data 
) 
3357     info
.m_mask 
= wxLIST_MASK_DATA
; 
3358     info
.m_itemId 
= item
; 
3360     m_mainWin
->SetItem( info 
); 
3364 bool wxListCtrl::GetItemRect( long item
, wxRect 
&rect
,  int WXUNUSED(code
) ) const 
3366     m_mainWin
->GetItemRect( item
, rect 
); 
3370 bool wxListCtrl::GetItemPosition( long item
, wxPoint
& pos 
) const 
3372     m_mainWin
->GetItemPosition( item
, pos 
); 
3376 bool wxListCtrl::SetItemPosition( long WXUNUSED(item
), const wxPoint
& WXUNUSED(pos
) ) 
3381 int wxListCtrl::GetItemCount() const 
3383     return m_mainWin
->GetItemCount(); 
3386 int wxListCtrl::GetColumnCount() const 
3388     return m_mainWin
->GetColumnCount(); 
3391 void wxListCtrl::SetItemSpacing( int spacing
, bool isSmall 
) 
3393     m_mainWin
->SetItemSpacing( spacing
, isSmall 
); 
3396 int wxListCtrl::GetItemSpacing( bool isSmall 
) const 
3398     return m_mainWin
->GetItemSpacing( isSmall 
); 
3401 int wxListCtrl::GetSelectedItemCount() const 
3403     return m_mainWin
->GetSelectedItemCount(); 
3406 wxColour 
wxListCtrl::GetTextColour() const 
3408     return GetForegroundColour(); 
3411 void wxListCtrl::SetTextColour(const wxColour
& col
) 
3413     SetForegroundColour(col
); 
3416 long wxListCtrl::GetTopItem() const 
3421 long wxListCtrl::GetNextItem( long item
, int geom
, int state 
) const 
3423     return m_mainWin
->GetNextItem( item
, geom
, state 
); 
3426 wxImageList 
*wxListCtrl::GetImageList(int which
) const 
3428     if (which 
== wxIMAGE_LIST_NORMAL
) 
3430         return m_imageListNormal
; 
3432     else if (which 
== wxIMAGE_LIST_SMALL
) 
3434         return m_imageListSmall
; 
3436     else if (which 
== wxIMAGE_LIST_STATE
) 
3438         return m_imageListState
; 
3440     return (wxImageList 
*) NULL
; 
3443 void wxListCtrl::SetImageList( wxImageList 
*imageList
, int which 
) 
3445     m_mainWin
->SetImageList( imageList
, which 
); 
3448 bool wxListCtrl::Arrange( int WXUNUSED(flag
) ) 
3453 bool wxListCtrl::DeleteItem( long item 
) 
3455     m_mainWin
->DeleteItem( item 
); 
3459 bool wxListCtrl::DeleteAllItems() 
3461     m_mainWin
->DeleteAllItems(); 
3465 bool wxListCtrl::DeleteAllColumns() 
3467     for ( size_t n 
= 0; n 
< m_mainWin
->m_columns
.GetCount(); n
++ ) 
3473 void wxListCtrl::ClearAll() 
3475     m_mainWin
->DeleteEverything(); 
3478 bool wxListCtrl::DeleteColumn( int col 
) 
3480     m_mainWin
->DeleteColumn( col 
); 
3484 void wxListCtrl::Edit( long item 
) 
3486     m_mainWin
->Edit( item 
); 
3489 bool wxListCtrl::EnsureVisible( long item 
) 
3491     m_mainWin
->EnsureVisible( item 
); 
3495 long wxListCtrl::FindItem( long start
, const wxString
& str
,  bool partial 
) 
3497     return m_mainWin
->FindItem( start
, str
, partial 
); 
3500 long wxListCtrl::FindItem( long start
, long data 
) 
3502     return m_mainWin
->FindItem( start
, data 
); 
3505 long wxListCtrl::FindItem( long WXUNUSED(start
), const wxPoint
& WXUNUSED(pt
), 
3506                            int WXUNUSED(direction
)) 
3511 long wxListCtrl::HitTest( const wxPoint 
&point
, int &flags 
) 
3513     return m_mainWin
->HitTest( (int)point
.x
, (int)point
.y
, flags 
); 
3516 long wxListCtrl::InsertItem( wxListItem
& info 
) 
3518     m_mainWin
->InsertItem( info 
); 
3519     return info
.m_itemId
; 
3522 long wxListCtrl::InsertItem( long index
, const wxString 
&label 
) 
3525     info
.m_text 
= label
; 
3526     info
.m_mask 
= wxLIST_MASK_TEXT
; 
3527     info
.m_itemId 
= index
; 
3528     return InsertItem( info 
); 
3531 long wxListCtrl::InsertItem( long index
, int imageIndex 
) 
3534     info
.m_mask 
= wxLIST_MASK_IMAGE
; 
3535     info
.m_image 
= imageIndex
; 
3536     info
.m_itemId 
= index
; 
3537     return InsertItem( info 
); 
3540 long wxListCtrl::InsertItem( long index
, const wxString 
&label
, int imageIndex 
) 
3543     info
.m_text 
= label
; 
3544     info
.m_image 
= imageIndex
; 
3545     info
.m_mask 
= wxLIST_MASK_TEXT 
| wxLIST_MASK_IMAGE
; 
3546     info
.m_itemId 
= index
; 
3547     return InsertItem( info 
); 
3550 long wxListCtrl::InsertColumn( long col
, wxListItem 
&item 
) 
3552     wxASSERT( m_headerWin 
); 
3553     m_mainWin
->InsertColumn( col
, item 
); 
3554     m_headerWin
->Refresh(); 
3559 long wxListCtrl::InsertColumn( long col
, const wxString 
&heading
, 
3560                                int format
, int width 
) 
3563     item
.m_mask 
= wxLIST_MASK_TEXT 
| wxLIST_MASK_FORMAT
; 
3564     item
.m_text 
= heading
; 
3567         item
.m_mask 
|= wxLIST_MASK_WIDTH
; 
3568         item
.m_width 
= width
; 
3570     item
.m_format 
= format
; 
3572     return InsertColumn( col
, item 
); 
3575 bool wxListCtrl::ScrollList( int WXUNUSED(dx
), int WXUNUSED(dy
) ) 
3581 // fn is a function which takes 3 long arguments: item1, item2, data. 
3582 // item1 is the long data associated with a first item (NOT the index). 
3583 // item2 is the long data associated with a second item (NOT the index). 
3584 // data is the same value as passed to SortItems. 
3585 // The return value is a negative number if the first item should precede the second 
3586 // item, a positive number of the second item should precede the first, 
3587 // or zero if the two items are equivalent. 
3588 // data is arbitrary data to be passed to the sort function. 
3590 bool wxListCtrl::SortItems( wxListCtrlCompare fn
, long data 
) 
3592     m_mainWin
->SortItems( fn
, data 
); 
3596 void wxListCtrl::OnIdle( wxIdleEvent 
&WXUNUSED(event
) ) 
3598     if (!m_mainWin
->m_dirty
) return; 
3602     GetClientSize( &cw
, &ch 
); 
3609     if (HasFlag(wxLC_REPORT
) && !HasFlag(wxLC_NO_HEADER
)) 
3611         m_headerWin
->GetPosition( &x
, &y 
); 
3612         m_headerWin
->GetSize( &w
, &h 
); 
3613         if ((x 
!= 0) || (y 
!= 0) || (w 
!= cw
) || (h 
!= 23)) 
3614             m_headerWin
->SetSize( 0, 0, cw
, 23 ); 
3616         m_mainWin
->GetPosition( &x
, &y 
); 
3617         m_mainWin
->GetSize( &w
, &h 
); 
3618         if ((x 
!= 0) || (y 
!= 24) || (w 
!= cw
) || (h 
!= ch
-24)) 
3619             m_mainWin
->SetSize( 0, 24, cw
, ch
-24 ); 
3623         m_mainWin
->GetPosition( &x
, &y 
); 
3624         m_mainWin
->GetSize( &w
, &h 
); 
3625         if ((x 
!= 0) || (y 
!= 24) || (w 
!= cw
) || (h 
!= ch
)) 
3626             m_mainWin
->SetSize( 0, 0, cw
, ch 
); 
3629     m_mainWin
->CalculatePositions(); 
3630     m_mainWin
->RealizeChanges(); 
3631     m_mainWin
->m_dirty 
= FALSE
; 
3632     m_mainWin
->Refresh(); 
3634     if ( m_headerWin 
&& m_headerWin
->m_dirty 
) 
3636         m_headerWin
->m_dirty 
= FALSE
; 
3637         m_headerWin
->Refresh(); 
3641 bool wxListCtrl::SetBackgroundColour( const wxColour 
&colour 
) 
3645         m_mainWin
->SetBackgroundColour( colour 
); 
3646         m_mainWin
->m_dirty 
= TRUE
; 
3652 bool wxListCtrl::SetForegroundColour( const wxColour 
&colour 
) 
3654     if ( !wxWindow::SetForegroundColour( colour 
) ) 
3659         m_mainWin
->SetForegroundColour( colour 
); 
3660         m_mainWin
->m_dirty 
= TRUE
; 
3665         m_headerWin
->SetForegroundColour( colour 
); 
3671 bool wxListCtrl::SetFont( const wxFont 
&font 
) 
3673     if ( !wxWindow::SetFont( font 
) ) 
3678         m_mainWin
->SetFont( font 
); 
3679         m_mainWin
->m_dirty 
= TRUE
; 
3684         m_headerWin
->SetFont( font 
); 
3690 #if wxUSE_DRAG_AND_DROP 
3692 void wxListCtrl::SetDropTarget( wxDropTarget 
*dropTarget 
) 
3694     m_mainWin
->SetDropTarget( dropTarget 
); 
3697 wxDropTarget 
*wxListCtrl::GetDropTarget() const 
3699     return m_mainWin
->GetDropTarget(); 
3702 #endif // wxUSE_DRAG_AND_DROP 
3704 bool wxListCtrl::SetCursor( const wxCursor 
&cursor 
) 
3706     return m_mainWin 
? m_mainWin
->wxWindow::SetCursor(cursor
) : FALSE
; 
3709 wxColour 
wxListCtrl::GetBackgroundColour() const 
3711     return m_mainWin 
? m_mainWin
->GetBackgroundColour() : wxColour(); 
3714 wxColour 
wxListCtrl::GetForegroundColour() const 
3716     return m_mainWin 
? m_mainWin
->GetForegroundColour() : wxColour(); 
3719 bool wxListCtrl::DoPopupMenu( wxMenu 
*menu
, int x
, int y 
) 
3721     return m_mainWin
->PopupMenu( menu
, x
, y 
); 
3724 void wxListCtrl::SetFocus() 
3726     /* The test in window.cpp fails as we are a composite 
3727        window, so it checks against "this", but not m_mainWin. */ 
3728     if ( FindFocus() != this ) 
3729         m_mainWin
->SetFocus();