1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  11 #pragma implementation "listctrl.h" 
  14 // For compilers that support precompilation, includes "wx.h". 
  15 #include "wx/wxprec.h" 
  21 #include "wx/dcscreen.h" 
  23 #include "wx/listctrl.h" 
  24 #include "wx/generic/imaglist.h" 
  26 #ifndef wxUSE_GENERIC_LIST_EXTENSIONS 
  27 #define wxUSE_GENERIC_LIST_EXTENSIONS 0 
  30 //----------------------------------------------------------------------------- 
  32 //----------------------------------------------------------------------------- 
  34 IMPLEMENT_DYNAMIC_CLASS(wxListItemData
,wxObject
); 
  36 wxListItemData::wxListItemData() 
  47 wxListItemData::wxListItemData( const wxListItem 
&info 
) 
  56 void wxListItemData::SetItem( const wxListItem 
&info 
) 
  58     if (info
.m_mask 
& wxLIST_MASK_TEXT
) m_text 
= info
.m_text
; 
  59     if (info
.m_mask 
& wxLIST_MASK_IMAGE
) m_image 
= info
.m_image
; 
  60     if (info
.m_mask 
& wxLIST_MASK_DATA
) m_data 
= info
.m_data
; 
  62     if ( info
.HasAttributes() ) 
  65             *m_attr 
= *info
.GetAttributes(); 
  67             m_attr 
= new wxListItemAttr(*info
.GetAttributes()); 
  72     m_width 
= info
.m_width
; 
  76 void wxListItemData::SetText( const wxString 
&s 
) 
  81 void wxListItemData::SetImage( int image 
) 
  86 void wxListItemData::SetData( long data 
) 
  91 void wxListItemData::SetPosition( int x
, int y 
) 
  97 void wxListItemData::SetSize( int width
, int height 
) 
  99     if (width 
!= -1) m_width 
= width
; 
 100     if (height 
!= -1) m_height 
= height
; 
 103 bool wxListItemData::HasImage() const 
 105     return (m_image 
>= 0); 
 108 bool wxListItemData::HasText() const 
 110     return (!m_text
.IsNull()); 
 113 bool wxListItemData::IsHit( int x
, int y 
) const 
 115     return ((x 
>= m_xpos
) && (x 
<= m_xpos
+m_width
) && (y 
>= m_ypos
) && (y 
<= m_ypos
+m_height
)); 
 118 void wxListItemData::GetText( wxString 
&s 
) 
 123 int wxListItemData::GetX() const 
 128 int wxListItemData::GetY() const 
 133 int wxListItemData::GetWidth() const 
 138 int wxListItemData::GetHeight() const 
 143 int wxListItemData::GetImage() const 
 148 void wxListItemData::GetItem( wxListItem 
&info 
) const 
 150     info
.m_text 
= m_text
; 
 151     info
.m_image 
= m_image
; 
 152     info
.m_data 
= m_data
; 
 156         if ( m_attr
->HasTextColour() ) 
 157             info
.SetTextColour(m_attr
->GetTextColour()); 
 158         if ( m_attr
->HasBackgroundColour() ) 
 159             info
.SetBackgroundColour(m_attr
->GetBackgroundColour()); 
 160         if ( m_attr
->HasFont() ) 
 161             info
.SetFont(m_attr
->GetFont()); 
 165 //----------------------------------------------------------------------------- 
 167 //----------------------------------------------------------------------------- 
 169 IMPLEMENT_DYNAMIC_CLASS(wxListHeaderData
,wxObject
); 
 171 wxListHeaderData::wxListHeaderData() 
 182 wxListHeaderData::wxListHeaderData( const wxListItem 
&item 
) 
 190 void wxListHeaderData::SetItem( const wxListItem 
&item 
) 
 192     m_mask 
= item
.m_mask
; 
 193     m_text 
= item
.m_text
; 
 194     m_image 
= item
.m_image
; 
 195     m_format 
= item
.m_format
; 
 196     m_width 
= item
.m_width
; 
 197     if (m_width 
< 0) m_width 
= 80; 
 198     if (m_width 
< 6) m_width 
= 6; 
 201 void wxListHeaderData::SetPosition( int x
, int y 
) 
 207 void wxListHeaderData::SetHeight( int h 
) 
 212 void wxListHeaderData::SetWidth( int w 
) 
 215     if (m_width 
< 0) m_width 
= 80; 
 216     if (m_width 
< 6) m_width 
= 6; 
 219 void wxListHeaderData::SetFormat( int format 
) 
 224 bool wxListHeaderData::HasImage() const 
 226     return (m_image 
!= 0); 
 229 bool wxListHeaderData::HasText() const 
 231     return (m_text
.Length() > 0); 
 234 bool wxListHeaderData::IsHit( int x
, int y 
) const 
 236     return ((x 
>= m_xpos
) && (x 
<= m_xpos
+m_width
) && (y 
>= m_ypos
) && (y 
<= m_ypos
+m_height
)); 
 239 void wxListHeaderData::GetItem( wxListItem 
&item 
) 
 241     item
.m_mask 
= m_mask
; 
 242     item
.m_text 
= m_text
; 
 243     item
.m_image 
= m_image
; 
 244     item
.m_format 
= m_format
; 
 245     item
.m_width 
= m_width
; 
 248 void wxListHeaderData::GetText( wxString 
&s 
) 
 253 int wxListHeaderData::GetImage() const 
 258 int wxListHeaderData::GetWidth() const 
 263 int wxListHeaderData::GetFormat() const 
 268 //----------------------------------------------------------------------------- 
 270 //----------------------------------------------------------------------------- 
 272 IMPLEMENT_DYNAMIC_CLASS(wxListLineData
,wxObject
); 
 274 wxListLineData::wxListLineData( wxListMainWindow 
*owner
, int mode
, wxBrush 
*hilightBrush 
) 
 279     m_hilightBrush 
= hilightBrush
; 
 280     m_items
.DeleteContents( TRUE 
); 
 284 void wxListLineData::CalculateSize( wxDC 
*dc
, int spacing 
) 
 291             m_bound_all
.width 
= m_spacing
; 
 292             m_bound_all
.height 
= m_spacing
+13; 
 293             wxNode 
*node 
= m_items
.First(); 
 296                 wxListItemData 
*item 
= (wxListItemData
*)node
->Data(); 
 297                 wxString s 
= item
->GetText(); 
 299                 dc
->GetTextExtent( s
, &lw
, &lh 
); 
 300                 if (lw 
> m_spacing
) m_bound_all
.width 
= lw
; 
 306             wxNode 
*node 
= m_items
.First(); 
 309                 wxListItemData 
*item 
= (wxListItemData
*)node
->Data(); 
 310                 wxString s 
= item
->GetText(); 
 312                 dc
->GetTextExtent( s
, &lw
, &lh 
); 
 313                 m_bound_all
.width 
= lw
; 
 314                 m_bound_all
.height 
= lh
; 
 315                 if (item
->HasImage()) 
 319                     m_owner
->GetImageSize( item
->GetImage(), w
, h 
); 
 320                     m_bound_all
.width 
+= 4 + w
; 
 321                     if (h 
> m_bound_all
.height
) m_bound_all
.height 
= h
; 
 328             m_bound_all
.width 
= 0; 
 329             m_bound_all
.height 
= 0; 
 330             wxNode 
*node 
= m_items
.First(); 
 333                 wxListItemData 
*item 
= (wxListItemData
*)node
->Data(); 
 336                 if (s
.IsNull()) s 
= "H"; 
 338                 dc
->GetTextExtent( s
, &lw
, &lh 
); 
 339                 item
->SetSize( item
->GetWidth(), lh 
); 
 340                 m_bound_all
.width 
+= lw
; 
 341                 m_bound_all
.height 
= lh
; 
 349 void wxListLineData::SetPosition( wxDC 
*dc
, int x
, int y
, int window_width 
) 
 357             AssignRect( m_bound_icon
, 0, 0, 0, 0 ); 
 358             AssignRect( m_bound_label
, 0, 0, 0, 0 ); 
 359             AssignRect( m_bound_hilight
, m_bound_all 
); 
 360             wxNode 
*node 
= m_items
.First(); 
 363                 wxListItemData 
*item 
= (wxListItemData
*)node
->Data(); 
 364                 if (item
->HasImage()) 
 366                     wxListItemData 
*item 
= (wxListItemData
*)node
->Data(); 
 369                     m_owner
->GetImageSize( item
->GetImage(), w
, h 
); 
 370                     m_bound_icon
.x 
= m_bound_all
.x 
+ (m_spacing
/2) - (w
/2); 
 371                     m_bound_icon
.y 
= m_bound_all
.y 
+ m_spacing 
- h 
- 5; 
 372                     m_bound_icon
.width 
= w
; 
 373                     m_bound_icon
.height 
= h
; 
 374                     if (!item
->HasText()) 
 376                         AssignRect( m_bound_hilight
, m_bound_icon 
); 
 377                         m_bound_hilight
.x 
-= 5; 
 378                         m_bound_hilight
.y 
-= 5; 
 379                         m_bound_hilight
.width 
+= 9; 
 380                         m_bound_hilight
.height 
+= 9; 
 388                     dc
->GetTextExtent( s
, &lw
, &lh 
); 
 389                     if (m_bound_all
.width 
> m_spacing
) 
 390                         m_bound_label
.x 
= m_bound_all
.x
; 
 392                         m_bound_label
.x 
= m_bound_all
.x 
+  (m_spacing
/2) - lw
/2; 
 393                     m_bound_label
.y 
= m_bound_all
.y 
+ m_bound_all
.height 
- lh
; 
 394                     m_bound_label
.width 
= lw
; 
 395                     m_bound_label
.height 
= lh
; 
 396                     AssignRect( m_bound_hilight
, m_bound_label 
); 
 397                     m_bound_hilight
.x 
-= 2; 
 398                     m_bound_hilight
.y 
-= 2; 
 399                     m_bound_hilight
.width 
+= 4; 
 400                     m_bound_hilight
.height 
+= 4; 
 407             AssignRect( m_bound_label
, m_bound_all 
); 
 410             m_bound_all
.width 
+= 4; 
 411             m_bound_all
.height 
+= 3; 
 412             AssignRect( m_bound_hilight
, m_bound_all 
); 
 413             AssignRect( m_bound_icon
, 0, 0, 0, 0 ); 
 414             wxNode 
*node 
= m_items
.First(); 
 417                 wxListItemData 
*item 
= (wxListItemData
*)node
->Data(); 
 418                 if (item
->HasImage()) 
 420                     m_bound_icon
.x 
= m_bound_all
.x 
+ 2; 
 421                     m_bound_icon
.y 
= m_bound_all
.y 
+ 2; 
 424                     m_owner
->GetImageSize( item
->GetImage(), w
, h 
); 
 425                     m_bound_icon
.width 
= w
; 
 426                     m_bound_icon
.height 
= h
; 
 427                     m_bound_label
.x 
+= 4 + w
; 
 428                     m_bound_label
.width 
-= 4 + w
; 
 436             dc
->GetTextExtent( "H", &lw
, &lh 
); 
 439             m_bound_all
.height 
= lh
+3; 
 440             m_bound_all
.width 
= window_width
; 
 441             AssignRect( m_bound_hilight
, m_bound_all 
); 
 442             AssignRect( m_bound_label
, m_bound_all 
); 
 443             AssignRect( m_bound_icon
, 0, 0, 0, 0 ); 
 444             wxNode 
*node 
= m_items
.First(); 
 447                 wxListItemData 
*item 
= (wxListItemData
*)node
->Data(); 
 450                 if (s
.IsEmpty()) s 
= wxT("H"); 
 452                 dc
->GetTextExtent( s
, &lw
, &lh 
); 
 453                 m_bound_label
.width 
= lw
; 
 454                 m_bound_label
.height 
= lh
; 
 455                 if (item
->HasImage()) 
 457                     m_bound_icon
.x 
= m_bound_all
.x 
+ 2; 
 458                     m_bound_icon
.y 
= m_bound_all
.y 
+ 2; 
 461                     m_owner
->GetImageSize( item
->GetImage(), w
, h 
); 
 462                     m_bound_icon
.width 
= w
; 
 463                     m_bound_icon
.height 
= h
; 
 464                     m_bound_label
.x 
+= 4 + w
; 
 472 void wxListLineData::SetColumnPosition( int index
, int x 
) 
 475     wxNode 
*node 
= m_items
.Nth( i 
); 
 478         wxListItemData 
*item 
= (wxListItemData
*)node
->Data(); 
 479         item
->SetPosition( x
, m_bound_all
.y
+1 ); 
 483 void wxListLineData::GetSize( int &width
, int &height 
) 
 485     width 
= m_bound_all
.width
; 
 486     height 
= m_bound_all
.height
; 
 489 void wxListLineData::GetExtent( int &x
, int &y
, int &width
, int &height 
) 
 493     width 
= m_bound_all
.width
; 
 494     height 
= m_bound_all
.height
; 
 497 void wxListLineData::GetLabelExtent( int &x
, int &y
, int &width
, int &height 
) 
 501     width 
= m_bound_label
.width
; 
 502     height 
= m_bound_label
.height
; 
 505 void wxListLineData::GetRect( wxRect 
&rect 
) 
 507     AssignRect( rect
, m_bound_all 
); 
 510 long wxListLineData::IsHit( int x
, int y 
) 
 512     wxNode 
*node 
= m_items
.First(); 
 515         wxListItemData 
*item 
= (wxListItemData
*)node
->Data(); 
 516         if (item
->HasImage() && IsInRect( x
, y
, m_bound_icon 
)) return wxLIST_HITTEST_ONITEMICON
; 
 517         if (item
->HasText() && IsInRect( x
, y
, m_bound_label 
)) return wxLIST_HITTEST_ONITEMLABEL
; 
 518 //      if (!(item->HasImage() || item->HasText())) return 0; 
 520     // if there is no icon or text = empty 
 521     if (IsInRect( x
, y
, m_bound_all 
)) return wxLIST_HITTEST_ONITEMICON
; 
 525 void wxListLineData::InitItems( int num 
) 
 527     for (int i 
= 0; i 
< num
; i
++) m_items
.Append( new wxListItemData() ); 
 530 void wxListLineData::SetItem( int index
, const wxListItem 
&info 
) 
 532     wxNode 
*node 
= m_items
.Nth( index 
); 
 535        wxListItemData 
*item 
= (wxListItemData
*)node
->Data(); 
 536        item
->SetItem( info 
); 
 540 void wxListLineData::GetItem( int index
, wxListItem 
&info 
) 
 543     wxNode 
*node 
= m_items
.Nth( i 
); 
 546         wxListItemData 
*item 
= (wxListItemData
*)node
->Data(); 
 547         item
->GetItem( info 
); 
 551 void wxListLineData::GetText( int index
, wxString 
&s 
) 
 554     wxNode 
*node 
= m_items
.Nth( i 
); 
 558         wxListItemData 
*item 
= (wxListItemData
*)node
->Data(); 
 563 void wxListLineData::SetText( int index
, const wxString s 
) 
 566     wxNode 
*node 
= m_items
.Nth( i 
); 
 569         wxListItemData 
*item 
= (wxListItemData
*)node
->Data(); 
 574 int wxListLineData::GetImage( int index 
) 
 577     wxNode 
*node 
= m_items
.Nth( i 
); 
 580         wxListItemData 
*item 
= (wxListItemData
*)node
->Data(); 
 581         return item
->GetImage(); 
 586 void wxListLineData::SetAttributes(wxDC 
*dc
, 
 587                                    const wxListItemAttr 
*attr
, 
 588                                    const wxColour
& colText
, 
 591     if ( attr 
&& attr
->HasTextColour() ) 
 593         dc
->SetTextForeground(attr
->GetTextColour()); 
 597         dc
->SetTextForeground(colText
); 
 600     if ( attr 
&& attr
->HasFont() ) 
 602         dc
->SetFont(attr
->GetFont()); 
 610 void wxListLineData::DoDraw( wxDC 
*dc
, bool hilight
, bool paintBG 
) 
 612     long dev_x 
= dc
->LogicalToDeviceX( m_bound_all
.x
-2 ); 
 613     long dev_y 
= dc
->LogicalToDeviceY( m_bound_all
.y
-2 ); 
 614     long dev_w 
= dc
->LogicalToDeviceXRel( m_bound_all
.width
+4 ); 
 615     long dev_h 
= dc
->LogicalToDeviceYRel( m_bound_all
.height
+4 ); 
 617     if (!m_owner
->IsExposed( dev_x
, dev_y
, dev_w
, dev_h 
)) 
 622     wxWindow 
*listctrl 
= m_owner
->GetParent(); 
 624     // default foreground colour 
 628         colText 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_HIGHLIGHTTEXT 
); 
 632         colText 
= listctrl
->GetForegroundColour(); 
 636     wxFont font 
= listctrl
->GetFont(); 
 638     // VZ: currently we set the colours/fonts only once, but like this (i.e. 
 639     //     using SetAttributes() inside the loop), it will be trivial to 
 640     //     customize the subitems (in report mode) too. 
 641     wxListItemData 
*item 
= (wxListItemData
*)m_items
.First()->Data(); 
 642     wxListItemAttr 
*attr 
= item
->GetAttributes(); 
 643     SetAttributes(dc
, attr
, colText
, font
); 
 645     bool hasBgCol 
= attr 
&& attr
->HasBackgroundColour(); 
 646     if ( paintBG 
|| hasBgCol 
) 
 650             dc
->SetBrush( * m_hilightBrush 
); 
 655                 dc
->SetBrush(wxBrush(attr
->GetBackgroundColour(), wxSOLID
)); 
 657                 dc
->SetBrush( * wxWHITE_BRUSH 
); 
 660         dc
->SetPen( * wxTRANSPARENT_PEN 
); 
 661         dc
->DrawRectangle( m_bound_hilight
.x
, m_bound_hilight
.y
, 
 662                            m_bound_hilight
.width
, m_bound_hilight
.height 
); 
 665     if (m_mode 
== wxLC_REPORT
) 
 667         wxNode 
*node 
= m_items
.First(); 
 670             wxListItemData 
*item 
= (wxListItemData
*)node
->Data(); 
 671             dc
->SetClippingRegion( item
->GetX(), item
->GetY(), item
->GetWidth()-3, item
->GetHeight() ); 
 672             int x 
= item
->GetX(); 
 673             if (item
->HasImage()) 
 676                 m_owner
->DrawImage( item
->GetImage(), dc
, x
, item
->GetY() ); 
 677                 m_owner
->GetImageSize( item
->GetImage(), x
, y 
); 
 678                 x 
+= item
->GetX() + 5; 
 682                 dc
->DrawText( item
->GetText(), x
, item
->GetY() ); 
 684             dc
->DestroyClippingRegion(); 
 690         wxNode 
*node 
= m_items
.First(); 
 693             wxListItemData 
*item 
= (wxListItemData
*)node
->Data(); 
 694             if (item
->HasImage()) 
 696                 m_owner
->DrawImage( item
->GetImage(), dc
, m_bound_icon
.x
, m_bound_icon
.y 
); 
 700                 dc
->DrawText( item
->GetText(), m_bound_label
.x
, m_bound_label
.y 
); 
 706 void wxListLineData::Hilight( bool on 
) 
 708     if (on 
== m_hilighted
) return; 
 710         m_owner
->SelectLine( this ); 
 712         m_owner
->DeselectLine( this ); 
 716 void wxListLineData::ReverseHilight( void ) 
 718     m_hilighted 
= !m_hilighted
; 
 720         m_owner
->SelectLine( this ); 
 722         m_owner
->DeselectLine( this ); 
 725 void wxListLineData::DrawRubberBand( wxDC 
*dc
, bool on 
) 
 729         dc
->SetPen( * wxBLACK_PEN 
); 
 730         dc
->SetBrush( * wxTRANSPARENT_BRUSH 
); 
 731         dc
->DrawRectangle( m_bound_hilight
.x
, m_bound_hilight
.y
, 
 732                            m_bound_hilight
.width
, m_bound_hilight
.height 
); 
 736 void wxListLineData::Draw( wxDC 
*dc 
) 
 738     DoDraw( dc
, m_hilighted
, m_hilighted 
); 
 741 bool wxListLineData::IsInRect( int x
, int y
, const wxRect 
&rect 
) 
 743     return ((x 
>= rect
.x
) && (x 
<= rect
.x
+rect
.width
) && 
 744             (y 
>= rect
.y
) && (y 
<= rect
.y
+rect
.height
)); 
 747 bool wxListLineData::IsHilighted( void ) 
 752 void wxListLineData::AssignRect( wxRect 
&dest
, int x
, int y
, int width
, int height 
) 
 757     dest
.height 
= height
; 
 760 void wxListLineData::AssignRect( wxRect 
&dest
, const wxRect 
&source 
) 
 764     dest
.width 
= source
.width
; 
 765     dest
.height 
= source
.height
; 
 768 //----------------------------------------------------------------------------- 
 769 //  wxListHeaderWindow 
 770 //----------------------------------------------------------------------------- 
 772 IMPLEMENT_DYNAMIC_CLASS(wxListHeaderWindow
,wxWindow
); 
 774 BEGIN_EVENT_TABLE(wxListHeaderWindow
,wxWindow
) 
 775     EVT_PAINT         (wxListHeaderWindow::OnPaint
) 
 776     EVT_MOUSE_EVENTS  (wxListHeaderWindow::OnMouse
) 
 777     EVT_SET_FOCUS     (wxListHeaderWindow::OnSetFocus
) 
 780 wxListHeaderWindow::wxListHeaderWindow( void ) 
 782     m_owner 
= (wxListMainWindow 
*) NULL
; 
 783     m_currentCursor 
= (wxCursor 
*) NULL
; 
 784     m_resizeCursor 
= (wxCursor 
*) NULL
; 
 785     m_isDragging 
= FALSE
; 
 788 wxListHeaderWindow::wxListHeaderWindow( wxWindow 
*win
, wxWindowID id
, wxListMainWindow 
*owner
, 
 789       const wxPoint 
&pos
, const wxSize 
&size
, 
 790       long style
, const wxString 
&name 
) : 
 791   wxWindow( win
, id
, pos
, size
, style
, name 
) 
 794 //  m_currentCursor = wxSTANDARD_CURSOR; 
 795     m_currentCursor 
= (wxCursor 
*) NULL
; 
 796     m_resizeCursor 
= new wxCursor( wxCURSOR_SIZEWE 
); 
 797     m_isDragging 
= FALSE
; 
 798     SetBackgroundColour( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
) ); 
 801 wxListHeaderWindow::~wxListHeaderWindow( void ) 
 803     delete m_resizeCursor
; 
 806 void wxListHeaderWindow::DoDrawRect( wxDC 
*dc
, int x
, int y
, int w
, int h 
) 
 808     const int m_corner 
= 1; 
 810     dc
->SetBrush( *wxTRANSPARENT_BRUSH 
); 
 812     dc
->SetPen( *wxBLACK_PEN 
); 
 813     dc
->DrawLine( x
+w
-m_corner
+1, y
, x
+w
, y
+h 
);  // right (outer) 
 814     dc
->DrawRectangle( x
, y
+h
, w
+1, 1 );          // bottom (outer) 
 816     wxPen 
pen( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNSHADOW 
), 1, wxSOLID 
); 
 819     dc
->DrawLine( x
+w
-m_corner
, y
, x
+w
-1, y
+h 
);  // right (inner) 
 820     dc
->DrawRectangle( x
+1, y
+h
-1, w
-2, 1 );      // bottom (inner) 
 822     dc
->SetPen( *wxWHITE_PEN 
); 
 823     dc
->DrawRectangle( x
, y
, w
-m_corner
+1, 1 );   // top (outer) 
 824     dc
->DrawRectangle( x
, y
, 1, h 
);              // left (outer) 
 825     dc
->DrawLine( x
, y
+h
-1, x
+1, y
+h
-1 ); 
 826     dc
->DrawLine( x
+w
-1, y
, x
+w
-1, y
+1 ); 
 829 void wxListHeaderWindow::OnPaint( wxPaintEvent 
&WXUNUSED(event
) ) 
 831     wxPaintDC 
dc( this ); 
 833 #if wxUSE_GENERIC_LIST_EXTENSIONS 
 834         if ( m_owner
->GetMode() & wxLC_REPORT 
) 
 839                 m_owner
->GetScrollPixelsPerUnit( &xpix 
, &ypix 
) ; 
 840                 m_owner
->ViewStart( &x
, &y 
) ; 
 841             dc
.SetDeviceOrigin( -x 
* xpix
, 0 ); 
 846     dc
.SetFont( GetFont() ); 
 852     GetClientSize( &w
, &h 
); 
 854     dc
.SetBackgroundMode(wxTRANSPARENT
); 
 855     dc
.SetTextForeground( *wxBLACK 
); 
 857     // do *not* use the listctrl colour for headers - one day we will have a 
 858     // function to set it separately 
 862     int numColumns 
= m_owner
->GetColumnCount(); 
 864     for (int i 
= 0; i 
< numColumns
; i
++) 
 866         m_owner
->GetColumn( i
, item 
); 
 867         int cw 
= item
.m_width
-2; 
 868 #if wxUSE_GENERIC_LIST_EXTENSIONS 
 869         if ((i
+1 == numColumns
) || ( dc
.LogicalToDeviceX(x
+item
.m_width
) > w
-5)) 
 870                 cw 
= dc
.DeviceToLogicalX(w
)-x
-1; 
 872         if ((i
+1 == numColumns
) || (x
+item
.m_width 
> w
-5)) cw 
= w
-x
-1; 
 874         dc
.SetPen( *wxWHITE_PEN 
); 
 876         DoDrawRect( &dc
, x
, y
, cw
, h
-2 ); 
 877         dc
.SetClippingRegion( x
, y
, cw
-5, h
-4 ); 
 878         dc
.DrawText( item
.m_text
, x
+4, y
+3 ); 
 879         dc
.DestroyClippingRegion(); 
 881 #if wxUSE_GENERIC_LIST_EXTENSIONS 
 882         if (dc
.LogicalToDeviceX(x
) > w
+5) break; 
 890 void wxListHeaderWindow::DrawCurrent() 
 894     int x2 
= m_currentX
-1; 
 897     m_owner
->GetClientSize( &dummy
, &y2 
); 
 898     ClientToScreen( &x1
, &y1 
); 
 899     m_owner
->ClientToScreen( &x2
, &y2 
); 
 902     dc
.SetLogicalFunction( wxINVERT 
); 
 903     dc
.SetPen( wxPen( *wxBLACK
, 2, wxSOLID 
) ); 
 904     dc
.SetBrush( *wxTRANSPARENT_BRUSH 
); 
 906     dc
.DrawLine( x1
, y1
, x2
, y2 
); 
 908     dc
.SetLogicalFunction( wxCOPY 
); 
 910     dc
.SetPen( wxNullPen 
); 
 911     dc
.SetBrush( wxNullBrush 
); 
 914 void wxListHeaderWindow::OnMouse( wxMouseEvent 
&event 
) 
 916     int x 
= event
.GetX(); 
 917     int y 
= event
.GetY(); 
 921         if (event
.ButtonUp()) 
 924             m_isDragging 
= FALSE
; 
 925             m_owner
->SetColumnWidth( m_column
, m_currentX
-m_minX 
); 
 931             GetClientSize( &size_x
, & dummy 
); 
 935                 m_currentX 
= m_minX
+7; 
 936             if (m_currentX 
> size_x
-7) m_currentX 
= size_x
-7; 
 943     bool hit_border 
= FALSE
; 
 945     for (int j 
= 0; j 
< m_owner
->GetColumnCount()-1; j
++) 
 947         xpos 
+= m_owner
->GetColumnWidth( j 
); 
 949         if ((abs(x
-xpos
) < 3) && (y 
< 22)) 
 961     if (event
.LeftDown()) 
 973             wxListEvent 
le( wxEVT_COMMAND_LIST_COL_CLICK
, GetParent()->GetId() ); 
 974             le
.SetEventObject( GetParent() ); 
 976             GetParent()->GetEventHandler()->ProcessEvent( le 
); 
 985             if (m_currentCursor 
== wxSTANDARD_CURSOR
) SetCursor( * m_resizeCursor 
); 
 986             m_currentCursor 
= m_resizeCursor
; 
 990             if (m_currentCursor 
!= wxSTANDARD_CURSOR
) SetCursor( * wxSTANDARD_CURSOR 
); 
 991             m_currentCursor 
= wxSTANDARD_CURSOR
; 
 996 void wxListHeaderWindow::OnSetFocus( wxFocusEvent 
&WXUNUSED(event
) ) 
1001 //----------------------------------------------------------------------------- 
1002 // wxListRenameTimer (internal) 
1003 //----------------------------------------------------------------------------- 
1005 wxListRenameTimer::wxListRenameTimer( wxListMainWindow 
*owner 
) 
1010 void wxListRenameTimer::Notify() 
1012     m_owner
->OnRenameTimer(); 
1015 //----------------------------------------------------------------------------- 
1016 // wxListTextCtrl (internal) 
1017 //----------------------------------------------------------------------------- 
1019 IMPLEMENT_DYNAMIC_CLASS(wxListTextCtrl
,wxTextCtrl
); 
1021 BEGIN_EVENT_TABLE(wxListTextCtrl
,wxTextCtrl
) 
1022     EVT_CHAR           (wxListTextCtrl::OnChar
) 
1023     EVT_KILL_FOCUS     (wxListTextCtrl::OnKillFocus
) 
1026 wxListTextCtrl::wxListTextCtrl( wxWindow 
*parent
, const wxWindowID id
, 
1027     bool *accept
, wxString 
*res
, wxListMainWindow 
*owner
, 
1028     const wxString 
&value
, const wxPoint 
&pos
, const wxSize 
&size
, 
1029 #if wxUSE_VALIDATORS 
1030     int style
, const wxValidator
& validator
, const wxString 
&name 
) : 
1032   wxTextCtrl( parent
, id
, value
, pos
, size
, style
, validator
, name 
) 
1037     (*m_accept
) = FALSE
; 
1039     m_startValue 
= value
; 
1042 void wxListTextCtrl::OnChar( wxKeyEvent 
&event 
) 
1044     if (event
.m_keyCode 
== WXK_RETURN
) 
1047         (*m_res
) = GetValue(); 
1048         m_owner
->SetFocus(); 
1051     if (event
.m_keyCode 
== WXK_ESCAPE
) 
1053         (*m_accept
) = FALSE
; 
1055         m_owner
->SetFocus(); 
1061 void wxListTextCtrl::OnKillFocus( wxFocusEvent 
&WXUNUSED(event
) ) 
1063     if (wxPendingDelete
.Member(this)) return; 
1065     wxPendingDelete
.Append(this); 
1067     if ((*m_accept
) && ((*m_res
) != m_startValue
)) 
1068         m_owner
->OnRenameAccept(); 
1071 //----------------------------------------------------------------------------- 
1073 //----------------------------------------------------------------------------- 
1075 IMPLEMENT_DYNAMIC_CLASS(wxListMainWindow
,wxScrolledWindow
); 
1077 BEGIN_EVENT_TABLE(wxListMainWindow
,wxScrolledWindow
) 
1078   EVT_PAINT          (wxListMainWindow::OnPaint
) 
1079   EVT_SIZE           (wxListMainWindow::OnSize
) 
1080   EVT_MOUSE_EVENTS   (wxListMainWindow::OnMouse
) 
1081   EVT_CHAR           (wxListMainWindow::OnChar
) 
1082   EVT_KEY_DOWN       (wxListMainWindow::OnKeyDown
) 
1083   EVT_SET_FOCUS      (wxListMainWindow::OnSetFocus
) 
1084   EVT_KILL_FOCUS     (wxListMainWindow::OnKillFocus
) 
1085   EVT_SCROLLWIN                 (wxListMainWindow::OnScroll
) 
1088 wxListMainWindow::wxListMainWindow() 
1091     m_lines
.DeleteContents( TRUE 
); 
1092     m_columns
.DeleteContents( TRUE 
); 
1093     m_current 
= (wxListLineData 
*) NULL
; 
1095     m_hilightBrush 
= (wxBrush 
*) NULL
; 
1099     m_small_image_list 
= (wxImageList 
*) NULL
; 
1100     m_normal_image_list 
= (wxImageList 
*) NULL
; 
1101     m_small_spacing 
= 30; 
1102     m_normal_spacing 
= 40; 
1105     m_lastOnSame 
= FALSE
; 
1106     m_renameTimer 
= new wxListRenameTimer( this ); 
1107     m_isCreated 
= FALSE
; 
1111 wxListMainWindow::wxListMainWindow( wxWindow 
*parent
, wxWindowID id
, 
1112       const wxPoint 
&pos
, const wxSize 
&size
, 
1113       long style
, const wxString 
&name 
) : 
1114   wxScrolledWindow( parent
, id
, pos
, size
, style
|wxHSCROLL
|wxVSCROLL
, name 
) 
1117     m_lines
.DeleteContents( TRUE 
); 
1118     m_columns
.DeleteContents( TRUE 
); 
1119     m_current 
= (wxListLineData 
*) NULL
; 
1122     m_hilightBrush 
= new wxBrush( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_HIGHLIGHT
), wxSOLID 
); 
1123     m_small_image_list 
= (wxImageList 
*) NULL
; 
1124     m_normal_image_list 
= (wxImageList 
*) NULL
; 
1125     m_small_spacing 
= 30; 
1126     m_normal_spacing 
= 40; 
1129     m_isCreated 
= FALSE
; 
1133     if (m_mode 
& wxLC_REPORT
) 
1135 #if wxUSE_GENERIC_LIST_EXTENSIONS 
1147     SetScrollbars( m_xScroll
, m_yScroll
, 0, 0, 0, 0 ); 
1150     m_lastOnSame 
= FALSE
; 
1151     m_renameTimer 
= new wxListRenameTimer( this ); 
1152     m_renameAccept 
= FALSE
; 
1154     SetBackgroundColour( *wxWHITE 
); 
1157 wxListMainWindow::~wxListMainWindow() 
1159     if (m_hilightBrush
) delete m_hilightBrush
; 
1161     delete m_renameTimer
; 
1164 void wxListMainWindow::RefreshLine( wxListLineData 
*line 
) 
1172         wxClientDC 
dc(this); 
1174         line
->GetExtent( x
, y
, w
, h 
); 
1176           dc
.LogicalToDeviceX(x
-3), 
1177           dc
.LogicalToDeviceY(y
-3), 
1178           dc
.LogicalToDeviceXRel(w
+6), 
1179           dc
.LogicalToDeviceXRel(h
+6) ); 
1180         Refresh( TRUE
, &rect 
); 
1184 void wxListMainWindow::OnPaint( wxPaintEvent 
&WXUNUSED(event
) ) 
1186     // Note: a wxPaintDC must be constructed even if no drawing is 
1187     // done (a Windows requirement). 
1188     wxPaintDC 
dc( this ); 
1191     if (m_dirty
) return; 
1193     if (m_lines
.GetCount() == 0) return; 
1197     dc
.SetFont( GetFont() ); 
1199     if (m_mode 
& wxLC_REPORT
) 
1201         int lineSpacing 
= 0; 
1202         wxListLineData 
*line 
= (wxListLineData
*)m_lines
.First()->Data(); 
1204         line
->GetSize( dummy
, lineSpacing 
); 
1207         int y_s 
= m_yScroll
*GetScrollPos( wxVERTICAL 
); 
1209         wxNode 
*node 
= m_lines
.Nth( y_s 
/ lineSpacing 
); 
1210         for (int i 
= 0; i 
< m_visibleLines
+2; i
++) 
1214             line 
= (wxListLineData
*)node
->Data(); 
1216             node 
= node
->Next(); 
1221         wxNode 
*node 
= m_lines
.First(); 
1224             wxListLineData 
*line 
= (wxListLineData
*)node
->Data(); 
1226             node 
= node
->Next(); 
1230     if (m_current
) m_current
->DrawRubberBand( &dc
, m_hasFocus 
); 
1235 void wxListMainWindow::HilightAll( bool on 
) 
1237     wxNode 
*node 
= m_lines
.First(); 
1240         wxListLineData 
*line 
= (wxListLineData 
*)node
->Data(); 
1241         if (line
->IsHilighted() != on
) 
1243             line
->Hilight( on 
); 
1244             RefreshLine( line 
); 
1246         node 
= node
->Next(); 
1250 void wxListMainWindow::SendNotify( wxListLineData 
*line
, wxEventType command 
) 
1252     wxListEvent 
le( command
, GetParent()->GetId() ); 
1253     le
.SetEventObject( GetParent() ); 
1254     le
.m_itemIndex 
= GetIndexOfLine( line 
); 
1255     line
->GetItem( 0, le
.m_item 
); 
1256 //    GetParent()->GetEventHandler()->ProcessEvent( le ); 
1257     GetParent()->GetEventHandler()->AddPendingEvent( le 
); 
1260 void wxListMainWindow::FocusLine( wxListLineData 
*WXUNUSED(line
) ) 
1262 //  SendNotify( line, wxEVT_COMMAND_LIST_ITEM_FOCUSSED ); 
1265 void wxListMainWindow::UnfocusLine( wxListLineData 
*WXUNUSED(line
) ) 
1267 //  SendNotify( line, wxEVT_COMMAND_LIST_ITEM_UNFOCUSSED ); 
1270 void wxListMainWindow::SelectLine( wxListLineData 
*line 
) 
1272     SendNotify( line
, wxEVT_COMMAND_LIST_ITEM_SELECTED 
); 
1275 void wxListMainWindow::DeselectLine( wxListLineData 
*line 
) 
1277     SendNotify( line
, wxEVT_COMMAND_LIST_ITEM_DESELECTED 
); 
1280 void wxListMainWindow::DeleteLine( wxListLineData 
*line 
) 
1282     SendNotify( line
, wxEVT_COMMAND_LIST_DELETE_ITEM 
); 
1287 void wxListMainWindow::EditLabel( long item 
) 
1289     wxNode 
*node 
= m_lines
.Nth( item 
); 
1290     wxCHECK_RET( node
, wxT("wrong index in wxListCtrl::Edit()") ); 
1292     m_currentEdit 
= (wxListLineData
*) node
->Data(); 
1294     wxListEvent 
le( wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT
, GetParent()->GetId() ); 
1295     le
.SetEventObject( GetParent() ); 
1296     le
.m_itemIndex 
= GetIndexOfLine( m_currentEdit 
); 
1297     m_currentEdit
->GetItem( 0, le
.m_item 
); 
1298     GetParent()->GetEventHandler()->ProcessEvent( le 
); 
1300     if (!le
.IsAllowed()) 
1303     // We have to call this here because the label in 
1304     // question might just have been added and no screen 
1305     // update taken place. 
1306     if (m_dirty
) wxYield(); 
1309     m_currentEdit
->GetText( 0, s 
); 
1314     m_currentEdit
->GetLabelExtent( x
, y
, w
, h 
); 
1316     wxClientDC 
dc(this); 
1318     x 
= dc
.LogicalToDeviceX( x 
); 
1319     y 
= dc
.LogicalToDeviceY( y 
); 
1321     wxListTextCtrl 
*text 
= new wxListTextCtrl( 
1322       this, -1, &m_renameAccept
, &m_renameRes
, this, s
, wxPoint(x
-4,y
-4), wxSize(w
+11,h
+8) ); 
1326 void wxListMainWindow::OnRenameTimer() 
1328     wxCHECK_RET( m_current
, wxT("invalid m_current") ); 
1330     Edit( m_lines
.IndexOf( m_current 
) ); 
1333 void wxListMainWindow::OnRenameAccept() 
1335     wxListEvent 
le( wxEVT_COMMAND_LIST_END_LABEL_EDIT
, GetParent()->GetId() ); 
1336     le
.SetEventObject( GetParent() ); 
1337     le
.m_itemIndex 
= GetIndexOfLine( m_currentEdit 
); 
1338     m_currentEdit
->GetItem( 0, le
.m_item 
); 
1339     le
.m_item
.m_text 
= m_renameRes
; 
1340     GetParent()->GetEventHandler()->ProcessEvent( le 
); 
1342     if (!le
.IsAllowed()) return; 
1345     info
.m_mask 
= wxLIST_MASK_TEXT
; 
1346     info
.m_itemId 
= le
.m_itemIndex
; 
1347     info
.m_text 
= m_renameRes
; 
1348     info
.SetTextColour(le
.m_item
.GetTextColour()); 
1352 void wxListMainWindow::OnMouse( wxMouseEvent 
&event 
) 
1354     if (GetParent()->GetEventHandler()->ProcessEvent( event
)) return; 
1356     if (!m_current
) return; 
1357     if (m_dirty
) return; 
1358     if ( !(event
.Dragging() || event
.ButtonDown() || event
.LeftUp() || event
.ButtonDClick()) ) return; 
1360     wxClientDC 
dc(this); 
1362     long x 
= dc
.DeviceToLogicalX( (long)event
.GetX() ); 
1363     long y 
= dc
.DeviceToLogicalY( (long)event
.GetY() ); 
1365     /* Did we actually hit an item ? */ 
1367     wxNode 
*node 
= m_lines
.First(); 
1368     wxListLineData 
*line 
= (wxListLineData 
*) NULL
; 
1371         line 
= (wxListLineData
*)node
->Data(); 
1372         hitResult 
= line
->IsHit( x
, y 
); 
1373         if (hitResult
) break; 
1374         line 
= (wxListLineData 
*) NULL
; 
1375         node 
= node
->Next(); 
1378     if (event
.Dragging()) 
1380         if (m_dragCount 
== 0) 
1381             m_dragStart 
= wxPoint(x
,y
); 
1385         if (m_dragCount 
!= 3) return; 
1387         int command 
= wxEVT_COMMAND_LIST_BEGIN_DRAG
; 
1388         if (event
.RightIsDown()) command 
= wxEVT_COMMAND_LIST_BEGIN_RDRAG
; 
1390         wxListEvent 
le( command
, GetParent()->GetId() ); 
1391         le
.SetEventObject( GetParent() ); 
1392         le
.m_pointDrag 
= m_dragStart
; 
1393         GetParent()->GetEventHandler()->ProcessEvent( le 
); 
1404     if (event
.ButtonDClick()) 
1407         m_lastOnSame 
= FALSE
; 
1408         m_renameTimer
->Stop(); 
1410         SendNotify( line
, wxEVT_COMMAND_LIST_ITEM_ACTIVATED 
); 
1415     if (event
.LeftUp() && m_lastOnSame
) 
1418         if ((line 
== m_current
) && 
1419             (hitResult 
== wxLIST_HITTEST_ONITEMLABEL
) && 
1420             (m_mode 
& wxLC_EDIT_LABELS
)  ) 
1422             m_renameTimer
->Start( 100, TRUE 
); 
1424         m_lastOnSame 
= FALSE
; 
1428     if (event
.RightDown()) 
1430         SendNotify( line
, wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK 
); 
1434     if (event
.MiddleDown()) 
1436         SendNotify( line
, wxEVT_COMMAND_LIST_ITEM_MIDDLE_CLICK 
); 
1440     if (event
.LeftDown()) 
1443         wxListLineData 
*oldCurrent 
= m_current
; 
1444         if (m_mode 
& wxLC_SINGLE_SEL
) 
1447             HilightAll( FALSE 
); 
1448             m_current
->ReverseHilight(); 
1449             RefreshLine( m_current 
); 
1453             if (event
.ShiftDown()) 
1456                 m_current
->ReverseHilight(); 
1457                 RefreshLine( m_current 
); 
1459             else if (event
.ControlDown()) 
1463                 int numOfCurrent 
= -1; 
1464                 node 
= m_lines
.First(); 
1467                     wxListLineData 
*test_line 
= (wxListLineData
*)node
->Data(); 
1469                     if (test_line 
== oldCurrent
) break; 
1470                     node 
= node
->Next(); 
1474                 node 
= m_lines
.First(); 
1477                     wxListLineData 
*test_line 
= (wxListLineData
*)node
->Data(); 
1479                     if (test_line 
== line
) break; 
1480                     node 
= node
->Next(); 
1483                 if (numOfLine 
< numOfCurrent
) 
1486                     numOfLine 
= numOfCurrent
; 
1490                 wxNode 
*node 
= m_lines
.Nth( numOfCurrent 
); 
1491                 for (int i 
= 0; i 
<= numOfLine
-numOfCurrent
; i
++) 
1493                     wxListLineData 
*test_line
= (wxListLineData
*)node
->Data(); 
1494                     test_line
->Hilight(TRUE
); 
1495                     RefreshLine( test_line 
); 
1496                     node 
= node
->Next(); 
1502                 HilightAll( FALSE 
); 
1503                 m_current
->ReverseHilight(); 
1504                 RefreshLine( m_current 
); 
1507         if (m_current 
!= oldCurrent
) 
1509             RefreshLine( oldCurrent 
); 
1510             UnfocusLine( oldCurrent 
); 
1511             FocusLine( m_current 
); 
1513         m_lastOnSame 
= (m_current 
== oldCurrent
); 
1518 void wxListMainWindow::MoveToFocus() 
1520     if (!m_current
) return; 
1526     m_current
->GetExtent( x
, y
, w
, h 
); 
1530     GetClientSize( &w_p
, &h_p 
); 
1532     if (m_mode 
& wxLC_REPORT
) 
1534         int y_s 
= m_yScroll
*GetScrollPos( wxVERTICAL 
); 
1535         if ((y 
> y_s
) && (y
+h 
< y_s
+h_p
)) return; 
1536         if (y
-y_s 
< 5) { Scroll( -1, (y
-5-h_p
/2)/m_yScroll 
); } 
1537         if (y
+h
+5 > y_s
+h_p
) { Scroll( -1, (y
+h
-h_p
/2+h
+15)/m_yScroll
); } 
1541         int x_s 
= m_xScroll
*GetScrollPos( wxHORIZONTAL 
); 
1542         if ((x 
> x_s
) && (x
+w 
< x_s
+w_p
)) return; 
1543         if (x
-x_s 
< 5) { Scroll( (x
-5)/m_xScroll
, -1 ); } 
1544         if (x
+w
-5 > x_s
+w_p
) { Scroll( (x
+w
-w_p
+15)/m_xScroll
, -1 ); } 
1548 void wxListMainWindow::OnArrowChar( wxListLineData 
*newCurrent
, bool shiftDown 
) 
1550     if ((m_mode 
& wxLC_SINGLE_SEL
) || (m_usedKeys 
== FALSE
)) m_current
->Hilight( FALSE 
); 
1551     wxListLineData 
*oldCurrent 
= m_current
; 
1552     m_current 
= newCurrent
; 
1554     if (shiftDown 
|| (m_mode 
& wxLC_SINGLE_SEL
)) m_current
->Hilight( TRUE 
); 
1555     RefreshLine( m_current 
); 
1556     RefreshLine( oldCurrent 
); 
1557     FocusLine( m_current 
); 
1558     UnfocusLine( oldCurrent 
); 
1561 void wxListMainWindow::OnKeyDown( wxKeyEvent 
&event 
) 
1563     wxWindow 
*parent 
= GetParent(); 
1565     /* we propagate the key event up */ 
1566     wxKeyEvent 
ke( wxEVT_KEY_DOWN 
); 
1567     ke
.m_shiftDown 
= event
.m_shiftDown
; 
1568     ke
.m_controlDown 
= event
.m_controlDown
; 
1569     ke
.m_altDown 
= event
.m_altDown
; 
1570     ke
.m_metaDown 
= event
.m_metaDown
; 
1571     ke
.m_keyCode 
= event
.m_keyCode
; 
1574     ke
.SetEventObject( parent 
); 
1575     if (parent
->GetEventHandler()->ProcessEvent( ke 
)) return; 
1580 void wxListMainWindow::OnChar( wxKeyEvent 
&event 
) 
1582     wxWindow 
*parent 
= GetParent(); 
1584     /* we send a list_key event up */ 
1585     wxListEvent 
le( wxEVT_COMMAND_LIST_KEY_DOWN
, GetParent()->GetId() ); 
1586     le
.m_code 
= event
.KeyCode(); 
1587     le
.SetEventObject( parent 
); 
1588     parent
->GetEventHandler()->ProcessEvent( le 
); 
1590     /* we propagate the char event up */ 
1591     wxKeyEvent 
ke( wxEVT_CHAR 
); 
1592     ke
.m_shiftDown 
= event
.m_shiftDown
; 
1593     ke
.m_controlDown 
= event
.m_controlDown
; 
1594     ke
.m_altDown 
= event
.m_altDown
; 
1595     ke
.m_metaDown 
= event
.m_metaDown
; 
1596     ke
.m_keyCode 
= event
.m_keyCode
; 
1599     ke
.SetEventObject( parent 
); 
1600     if (parent
->GetEventHandler()->ProcessEvent( ke 
)) return; 
1602     if (event
.KeyCode() == WXK_TAB
) 
1604         wxNavigationKeyEvent nevent
; 
1605         nevent
.SetDirection( !event
.ShiftDown() ); 
1606         nevent
.SetCurrentFocus( m_parent 
); 
1607         if (m_parent
->GetEventHandler()->ProcessEvent( nevent 
)) return; 
1610     /* no item -> nothing to do */ 
1617     switch (event
.KeyCode()) 
1621             wxNode 
*node 
= m_lines
.Member( m_current 
)->Previous(); 
1622             if (node
) OnArrowChar( (wxListLineData
*)node
->Data(), event
.ShiftDown() ); 
1627             wxNode 
*node 
= m_lines
.Member( m_current 
)->Next(); 
1628             if (node
) OnArrowChar( (wxListLineData
*)node
->Data(), event
.ShiftDown() ); 
1633             wxNode 
*node 
= m_lines
.Last(); 
1634             OnArrowChar( (wxListLineData
*)node
->Data(), event
.ShiftDown() ); 
1639             wxNode 
*node 
= m_lines
.First(); 
1640             OnArrowChar( (wxListLineData
*)node
->Data(), event
.ShiftDown() ); 
1646             if (m_mode 
& wxLC_REPORT
) 
1648                 steps 
= m_visibleLines
-1; 
1653                 wxNode 
*node 
= m_lines
.First(); 
1654                 for (;;) { if (m_current 
== (wxListLineData
*)node
->Data()) break; pos
++; node 
= node
->Next(); } 
1655                 steps 
= pos 
% m_visibleLines
; 
1657             wxNode 
*node 
= m_lines
.Member( m_current 
); 
1658             for (int i 
= 0; i 
< steps
; i
++) if (node
->Previous()) node 
= node
->Previous(); 
1659             if (node
) OnArrowChar( (wxListLineData
*)node
->Data(), event
.ShiftDown() ); 
1665             if (m_mode 
& wxLC_REPORT
) 
1667                 steps 
= m_visibleLines
-1; 
1671                 int pos 
= 0; wxNode 
*node 
= m_lines
.First(); 
1672                 for (;;) { if (m_current 
== (wxListLineData
*)node
->Data()) break; pos
++; node 
= node
->Next(); } 
1673                 steps 
= m_visibleLines
-(pos 
% m_visibleLines
)-1; 
1675             wxNode 
*node 
= m_lines
.Member( m_current 
); 
1676             for (int i 
= 0; i 
< steps
; i
++) if (node
->Next()) node 
= node
->Next(); 
1677             if (node
) OnArrowChar( (wxListLineData
*)node
->Data(), event
.ShiftDown() ); 
1682             if (!(m_mode 
& wxLC_REPORT
)) 
1684                 wxNode 
*node 
= m_lines
.Member( m_current 
); 
1685                 for (int i 
= 0; i 
<m_visibleLines
; i
++) if (node
->Previous()) node 
= node
->Previous(); 
1686                 if (node
) OnArrowChar( (wxListLineData
*)node
->Data(), event
.ShiftDown() ); 
1692             if (!(m_mode 
& wxLC_REPORT
)) 
1694                 wxNode 
*node 
= m_lines
.Member( m_current 
); 
1695                 for (int i 
= 0; i 
<m_visibleLines
; i
++) if (node
->Next()) node 
= node
->Next(); 
1696                 if (node
) OnArrowChar( (wxListLineData
*)node
->Data(), event
.ShiftDown() ); 
1702             m_current
->ReverseHilight(); 
1703             RefreshLine( m_current 
); 
1708             if (!(m_mode 
& wxLC_SINGLE_SEL
)) 
1710                 wxListLineData 
*oldCurrent 
= m_current
; 
1711                 m_current
->ReverseHilight(); 
1712                 wxNode 
*node 
= m_lines
.Member( m_current 
)->Next(); 
1713                 if (node
) m_current 
= (wxListLineData
*)node
->Data(); 
1715                 RefreshLine( oldCurrent 
); 
1716                 RefreshLine( m_current 
); 
1717                 UnfocusLine( oldCurrent 
); 
1718                 FocusLine( m_current 
); 
1725             wxListEvent 
le( wxEVT_COMMAND_LIST_ITEM_ACTIVATED
, GetParent()->GetId() ); 
1726             le
.SetEventObject( GetParent() ); 
1727             le
.m_itemIndex 
= GetIndexOfLine( m_current 
); 
1728             m_current
->GetItem( 0, le
.m_item 
); 
1729             GetParent()->GetEventHandler()->ProcessEvent( le 
); 
1742 extern wxWindow 
*g_focusWindow
; 
1745 void wxListMainWindow::OnSetFocus( wxFocusEvent 
&WXUNUSED(event
) ) 
1748     RefreshLine( m_current 
); 
1750     if (!GetParent()) return; 
1753     g_focusWindow 
= GetParent(); 
1756     wxFocusEvent 
event( wxEVT_SET_FOCUS
, GetParent()->GetId() ); 
1757     event
.SetEventObject( GetParent() ); 
1758     GetParent()->GetEventHandler()->ProcessEvent( event 
); 
1761 void wxListMainWindow::OnKillFocus( wxFocusEvent 
&WXUNUSED(event
) ) 
1764     RefreshLine( m_current 
); 
1767 void wxListMainWindow::OnSize( wxSizeEvent 
&WXUNUSED(event
) ) 
1770   We don't even allow the wxScrolledWindow::AdjustScrollbars() call 
1775 void wxListMainWindow::DrawImage( int index
, wxDC 
*dc
, int x
, int y 
) 
1777     if ((m_mode 
& wxLC_ICON
) && (m_normal_image_list
)) 
1779         m_normal_image_list
->Draw( index
, *dc
, x
, y
, wxIMAGELIST_DRAW_TRANSPARENT 
); 
1782     if ((m_mode 
& wxLC_SMALL_ICON
) && (m_small_image_list
)) 
1784         m_small_image_list
->Draw( index
, *dc
, x
, y
, wxIMAGELIST_DRAW_TRANSPARENT 
); 
1786     if ((m_mode 
& wxLC_LIST
) && (m_small_image_list
)) 
1788         m_small_image_list
->Draw( index
, *dc
, x
, y
, wxIMAGELIST_DRAW_TRANSPARENT 
); 
1790     if ((m_mode 
& wxLC_REPORT
) && (m_small_image_list
)) 
1792         m_small_image_list
->Draw( index
, *dc
, x
, y
, wxIMAGELIST_DRAW_TRANSPARENT 
); 
1797 void wxListMainWindow::GetImageSize( int index
, int &width
, int &height 
) 
1799     if ((m_mode 
& wxLC_ICON
) && (m_normal_image_list
)) 
1801         m_normal_image_list
->GetSize( index
, width
, height 
); 
1804     if ((m_mode 
& wxLC_SMALL_ICON
) && (m_small_image_list
)) 
1806         m_small_image_list
->GetSize( index
, width
, height 
); 
1809     if ((m_mode 
& wxLC_LIST
) && (m_small_image_list
)) 
1811         m_small_image_list
->GetSize( index
, width
, height 
); 
1814     if ((m_mode 
& wxLC_REPORT
) && (m_small_image_list
)) 
1816         m_small_image_list
->GetSize( index
, width
, height 
); 
1823 int wxListMainWindow::GetTextLength( wxString 
&s 
) 
1825     wxClientDC 
dc( this ); 
1828     dc
.GetTextExtent( s
, &lw
, &lh 
); 
1832 int wxListMainWindow::GetIndexOfLine( const wxListLineData 
*line 
) 
1835     wxNode 
*node 
= m_lines
.First(); 
1838         if (line 
== (wxListLineData
*)node
->Data()) return i
; 
1840         node 
= node
->Next(); 
1845 void wxListMainWindow::SetImageList( wxImageList 
*imageList
, int which 
) 
1848     if (which 
== wxIMAGE_LIST_NORMAL
) m_normal_image_list 
= imageList
; 
1849     if (which 
== wxIMAGE_LIST_SMALL
) m_small_image_list 
= imageList
; 
1852 void wxListMainWindow::SetItemSpacing( int spacing
, bool isSmall 
) 
1857         m_small_spacing 
= spacing
; 
1861         m_normal_spacing 
= spacing
; 
1865 int wxListMainWindow::GetItemSpacing( bool isSmall 
) 
1867     if (isSmall
) return m_small_spacing
; else return m_normal_spacing
; 
1870 void wxListMainWindow::SetColumn( int col
, wxListItem 
&item 
) 
1873     wxNode 
*node 
= m_columns
.Nth( col 
); 
1876         if (item
.m_width 
== wxLIST_AUTOSIZE_USEHEADER
) item
.m_width 
= GetTextLength( item
.m_text 
)+7; 
1877         wxListHeaderData 
*column 
= (wxListHeaderData
*)node
->Data(); 
1878         column
->SetItem( item 
); 
1880     wxListCtrl 
*lc 
= (wxListCtrl
*) GetParent(); 
1881     if (lc
->m_headerWin
) lc
->m_headerWin
->Refresh(); 
1884 void wxListMainWindow::SetColumnWidth( int col
, int width 
) 
1886     if (!(m_mode 
& wxLC_REPORT
)) return; 
1890     wxNode 
*node 
= (wxNode
*) NULL
; 
1892     if (width 
== wxLIST_AUTOSIZE_USEHEADER
) width 
= 80; 
1893     if (width 
== wxLIST_AUTOSIZE
) 
1895         wxClientDC 
dc(this); 
1896         dc
.SetFont( GetFont() ); 
1898         node 
= m_lines
.First(); 
1901             wxListLineData 
*line 
= (wxListLineData
*)node
->Data(); 
1902             wxNode 
*n 
= line
->m_items
.Nth( col 
); 
1905                 wxListItemData 
*item 
= (wxListItemData
*)n
->Data(); 
1906                 int current 
= 0, ix 
= 0, iy 
= 0; 
1907                 long lx 
= 0, ly 
= 0; 
1908                 if (item
->HasImage()) 
1910                     GetImageSize( item
->GetImage(), ix
, iy 
); 
1913                 if (item
->HasText()) 
1916                     item
->GetText( str 
); 
1917                     dc
.GetTextExtent( str
, &lx
, &ly 
); 
1920                 if (current 
> max
) max 
= current
; 
1922             node 
= node
->Next(); 
1927     node 
= m_columns
.Nth( col 
); 
1930         wxListHeaderData 
*column 
= (wxListHeaderData
*)node
->Data(); 
1931         column
->SetWidth( width 
); 
1934     node 
= m_lines
.First(); 
1937         wxListLineData 
*line 
= (wxListLineData
*)node
->Data(); 
1938         wxNode 
*n 
= line
->m_items
.Nth( col 
); 
1941             wxListItemData 
*item 
= (wxListItemData
*)n
->Data(); 
1942             item
->SetSize( width
, -1 ); 
1944         node 
= node
->Next(); 
1947     wxListCtrl 
*lc 
= (wxListCtrl
*) GetParent(); 
1948     if (lc
->m_headerWin
) lc
->m_headerWin
->Refresh(); 
1951 void wxListMainWindow::GetColumn( int col
, wxListItem 
&item 
) 
1953     wxNode 
*node 
= m_columns
.Nth( col 
); 
1956         wxListHeaderData 
*column 
= (wxListHeaderData
*)node
->Data(); 
1957         column
->GetItem( item 
); 
1969 int wxListMainWindow::GetColumnWidth( int col 
) 
1971     wxNode 
*node 
= m_columns
.Nth( col 
); 
1974         wxListHeaderData 
*column 
= (wxListHeaderData
*)node
->Data(); 
1975         return column
->GetWidth(); 
1983 int wxListMainWindow::GetColumnCount() 
1985     return m_columns
.Number(); 
1988 int wxListMainWindow::GetCountPerPage() 
1990     return m_visibleLines
; 
1993 void wxListMainWindow::SetItem( wxListItem 
&item 
) 
1996     wxNode 
*node 
= m_lines
.Nth( item
.m_itemId 
); 
1999         wxListLineData 
*line 
= (wxListLineData
*)node
->Data(); 
2000         if (m_mode 
& wxLC_REPORT
) item
.m_width 
= GetColumnWidth( item
.m_col 
)-3; 
2001         line
->SetItem( item
.m_col
, item 
); 
2005 void wxListMainWindow::SetItemState( long item
, long state
, long stateMask 
) 
2007     // m_dirty = TRUE; no recalcs needed 
2009     wxListLineData 
*oldCurrent 
= m_current
; 
2011     if (stateMask 
& wxLIST_STATE_FOCUSED
) 
2013         wxNode 
*node 
= m_lines
.Nth( item 
); 
2016             wxListLineData 
*line 
= (wxListLineData
*)node
->Data(); 
2017             UnfocusLine( m_current 
); 
2019             FocusLine( m_current 
); 
2020             RefreshLine( m_current 
); 
2021             if (oldCurrent
) RefreshLine( oldCurrent 
); 
2025     if (stateMask 
& wxLIST_STATE_SELECTED
) 
2027         bool on 
= state 
& wxLIST_STATE_SELECTED
; 
2028         if (!on 
&& (m_mode 
& wxLC_SINGLE_SEL
)) return; 
2030         wxNode 
*node 
= m_lines
.Nth( item 
); 
2033             wxListLineData 
*line 
= (wxListLineData
*)node
->Data(); 
2034             if (m_mode 
& wxLC_SINGLE_SEL
) 
2036                 UnfocusLine( m_current 
); 
2038                 FocusLine( m_current 
); 
2039                 if (oldCurrent
) oldCurrent
->Hilight( FALSE 
); 
2040                 RefreshLine( m_current 
); 
2041                 if (oldCurrent
) RefreshLine( oldCurrent 
); 
2043             bool on 
= state 
& wxLIST_STATE_SELECTED
; 
2044             if (on 
!= line
->IsHilighted()) 
2046                 line
->Hilight( on 
); 
2047                 RefreshLine( line 
); 
2053 int wxListMainWindow::GetItemState( long item
, long stateMask 
) 
2055     int ret 
= wxLIST_STATE_DONTCARE
; 
2056     if (stateMask 
& wxLIST_STATE_FOCUSED
) 
2058         wxNode 
*node 
= m_lines
.Nth( item 
); 
2061             wxListLineData 
*line 
= (wxListLineData
*)node
->Data(); 
2062             if (line 
== m_current
) ret 
|= wxLIST_STATE_FOCUSED
; 
2065     if (stateMask 
& wxLIST_STATE_SELECTED
) 
2067         wxNode 
*node 
= m_lines
.Nth( item 
); 
2070             wxListLineData 
*line 
= (wxListLineData
*)node
->Data(); 
2071             if (line
->IsHilighted()) ret 
|= wxLIST_STATE_FOCUSED
; 
2077 void wxListMainWindow::GetItem( wxListItem 
&item 
) 
2079     wxNode 
*node 
= m_lines
.Nth( item
.m_itemId 
); 
2082         wxListLineData 
*line 
= (wxListLineData
*)node
->Data(); 
2083         line
->GetItem( item
.m_col
, item 
); 
2094 int wxListMainWindow::GetItemCount() 
2096     return m_lines
.Number(); 
2099 void wxListMainWindow::GetItemRect( long index
, wxRect 
&rect 
) 
2101     wxNode 
*node 
= m_lines
.Nth( index 
); 
2104         wxListLineData 
*line 
= (wxListLineData
*)node
->Data(); 
2105         line
->GetRect( rect 
); 
2116 bool wxListMainWindow::GetItemPosition(long item
, wxPoint
& pos
) 
2118     wxNode 
*node 
= m_lines
.Nth( item 
); 
2122         wxListLineData 
*line 
= (wxListLineData
*)node
->Data(); 
2123         line
->GetRect( rect 
); 
2135 int wxListMainWindow::GetSelectedItemCount() 
2138     wxNode 
*node 
= m_lines
.First(); 
2141         wxListLineData 
*line 
= (wxListLineData
*)node
->Data(); 
2142         if (line
->IsHilighted()) ret
++; 
2143         node 
= node
->Next(); 
2148 void wxListMainWindow::SetMode( long mode 
) 
2155     if (m_mode 
& wxLC_REPORT
) 
2157 #if wxUSE_GENERIC_LIST_EXTENSIONS 
2171 long wxListMainWindow::GetMode() const 
2176 void wxListMainWindow::CalculatePositions() 
2178     if (!m_lines
.First()) return; 
2180     wxClientDC 
dc( this ); 
2181     dc
.SetFont( GetFont() ); 
2183     int iconSpacing 
= 0; 
2184     if (m_mode 
& wxLC_ICON
) iconSpacing 
= m_normal_spacing
; 
2185     if (m_mode 
& wxLC_SMALL_ICON
) iconSpacing 
= m_small_spacing
; 
2187     // we take the first line (which also can be an icon or 
2188     // an a text item in wxLC_ICON and wxLC_LIST modes) to 
2189     // measure the size of the line 
2193     int lineSpacing 
= 0; 
2195     wxListLineData 
*line 
= (wxListLineData
*)m_lines
.First()->Data(); 
2196     line
->CalculateSize( &dc
, iconSpacing 
); 
2198     line
->GetSize( dummy
, lineSpacing 
); 
2201     int clientWidth 
= 0; 
2202     int clientHeight 
= 0; 
2204     if (m_mode 
& wxLC_REPORT
) 
2208         int entireHeight 
= m_lines
.Number() * lineSpacing 
+ 2; 
2209         int scroll_pos 
= GetScrollPos( wxVERTICAL 
); 
2210 #if wxUSE_GENERIC_LIST_EXTENSIONS 
2211         int x_scroll_pos 
= GetScrollPos( wxHORIZONTAL 
); 
2213         SetScrollbars( m_xScroll
, m_yScroll
, 0, (entireHeight
+15) / m_yScroll
, 0, scroll_pos
, TRUE 
); 
2215         GetClientSize( &clientWidth
, &clientHeight 
); 
2217         wxNode
* node 
= m_lines
.First(); 
2218         int entireWidth 
= 0 ; 
2221             wxListLineData 
*line 
= (wxListLineData
*)node
->Data(); 
2222             line
->CalculateSize( &dc
, iconSpacing 
); 
2223             line
->SetPosition( &dc
, x
, y
, clientWidth 
); 
2225             for (int i 
= 0; i 
< GetColumnCount(); i
++) 
2227                 line
->SetColumnPosition( i
, col_x 
); 
2228                 col_x 
+= GetColumnWidth( i 
); 
2230             entireWidth 
= wxMax( entireWidth 
, col_x 
) ; 
2231 #if wxUSE_GENERIC_LIST_EXTENSIONS 
2232             line
->SetPosition( &dc
, x
, y
, col_x 
); 
2234             y 
+= lineSpacing
;  // one pixel blank line between items 
2235             node 
= node
->Next(); 
2237                 m_visibleLines 
= clientHeight 
/ lineSpacing
; 
2238 #if wxUSE_GENERIC_LIST_EXTENSIONS 
2239                 SetScrollbars( m_xScroll
, m_yScroll
, entireWidth 
/ m_xScroll 
, (entireHeight
+15) / m_yScroll
, x_scroll_pos  
, scroll_pos
, TRUE 
); 
2244         // at first we try without any scrollbar. if the items don't 
2245         // fit into the window, we recalculate after subtracting an 
2246         // approximated 15 pt for the horizontal scrollbar 
2248         GetSize( &clientWidth
, &clientHeight 
); 
2249         clientHeight 
-= 4;  // sunken frame 
2251         int entireWidth 
= 0; 
2253         for (int tries 
= 0; tries 
< 2; tries
++) 
2256             int x 
= 5;  // painting is done at x-2 
2257             int y 
= 5;  // painting is done at y-2 
2260             int m_currentVisibleLines 
= 0; 
2261             wxNode 
*node 
= m_lines
.First(); 
2264                 m_currentVisibleLines
++; 
2265                 wxListLineData 
*line 
= (wxListLineData
*)node
->Data(); 
2266                 line
->CalculateSize( &dc
, iconSpacing 
); 
2267                 line
->SetPosition( &dc
, x
, y
, clientWidth 
); 
2268                 line
->GetSize( lineWidth
, lineHeight 
); 
2269                 if (lineWidth 
> maxWidth
) maxWidth 
= lineWidth
; 
2271                 if (m_currentVisibleLines 
> m_visibleLines
) 
2272                     m_visibleLines 
= m_currentVisibleLines
; 
2273                 if (y
+lineSpacing
-6 >= clientHeight
) // -6 for earlier "line breaking" 
2275                     m_currentVisibleLines 
= 0; 
2278                     entireWidth 
+= maxWidth
+6; 
2281                 node 
= node
->Next(); 
2282                 if (!node
) entireWidth 
+= maxWidth
; 
2283                 if ((tries 
== 0) && (entireWidth 
> clientWidth
)) 
2285                     clientHeight 
-= 15; // scrollbar height 
2287                     m_currentVisibleLines 
= 0; 
2290                 if (!node
) tries 
= 1;  // everything fits, no second try required 
2294         int scroll_pos 
= GetScrollPos( wxHORIZONTAL 
); 
2295         SetScrollbars( m_xScroll
, m_yScroll
, (entireWidth
+15) / m_xScroll
, 0, scroll_pos
, 0, TRUE 
); 
2299 void wxListMainWindow::RealizeChanges( void ) 
2303         wxNode 
*node 
= m_lines
.First(); 
2304         if (node
) m_current 
= (wxListLineData
*)node
->Data(); 
2308         FocusLine( m_current 
); 
2309         if (m_mode 
& wxLC_SINGLE_SEL
) m_current
->Hilight( TRUE 
); 
2313 long wxListMainWindow::GetNextItem( long item
, int WXUNUSED(geometry
), int state 
) 
2316     if (item 
> 0) ret 
= item
; 
2317     if(ret 
>= GetItemCount()) return -1; 
2318     wxNode 
*node 
= m_lines
.Nth( ret 
); 
2321         wxListLineData 
*line 
= (wxListLineData
*)node
->Data(); 
2322         if ((state 
& wxLIST_STATE_FOCUSED
) && (line 
== m_current
)) return ret
; 
2323         if ((state 
& wxLIST_STATE_SELECTED
) && (line
->IsHilighted())) return ret
; 
2324         if (!state
) return ret
; 
2326         node 
= node
->Next(); 
2331 void wxListMainWindow::DeleteItem( long index 
) 
2334     wxNode 
*node 
= m_lines
.Nth( index 
); 
2337         wxListLineData 
*line 
= (wxListLineData
*)node
->Data(); 
2338         if (m_current 
== line
) m_current 
= (wxListLineData 
*) NULL
; 
2340         m_lines
.DeleteNode( node 
); 
2344 void wxListMainWindow::DeleteColumn( int col 
) 
2346     wxCHECK_RET( col 
< (int)m_columns
.GetCount(), 
2347                wxT("attempting to delete inexistent column in wxListView") ); 
2350     wxNode 
*node 
= m_columns
.Nth( col 
); 
2351     if (node
) m_columns
.DeleteNode( node 
); 
2354 void wxListMainWindow::DeleteAllItems( void ) 
2357     m_current 
= (wxListLineData 
*) NULL
; 
2359     // to make the deletion of all items faster, we don't send the 
2360     // notifications in this case: this is compatible with wxMSW and 
2361     // documented in DeleteAllItems() description 
2363     wxNode 
*node 
= m_lines
.First(); 
2366         wxListLineData 
*line 
= (wxListLineData
*)node
->Data(); 
2370         node 
= node
->Next(); 
2377 void wxListMainWindow::DeleteEverything( void ) 
2380     m_current 
= (wxListLineData 
*) NULL
; 
2381     wxNode 
*node 
= m_lines
.First(); 
2384         wxListLineData 
*line 
= (wxListLineData
*)node
->Data(); 
2386         node 
= node
->Next(); 
2389     m_current 
= (wxListLineData 
*) NULL
; 
2393 void wxListMainWindow::EnsureVisible( long index 
) 
2395     // We have to call this here because the label in 
2396     // question might just have been added and no screen 
2397     // update taken place. 
2398     if (m_dirty
) wxYield(); 
2400     wxListLineData 
*oldCurrent 
= m_current
; 
2401     m_current 
= (wxListLineData 
*) NULL
; 
2403     wxNode 
*node 
= m_lines
.Nth( i 
); 
2404     if (node
) m_current 
= (wxListLineData
*)node
->Data(); 
2405     if (m_current
) MoveToFocus(); 
2406     m_current 
= oldCurrent
; 
2409 long wxListMainWindow::FindItem(long start
, const wxString
& str
, bool WXUNUSED(partial
) ) 
2413     if (pos 
< 0) pos 
= 0; 
2414     wxNode 
*node 
= m_lines
.Nth( pos 
); 
2417         wxListLineData 
*line 
= (wxListLineData
*)node
->Data(); 
2419         line
->GetText( 0, s 
); 
2420         if (s 
== tmp
) return pos
; 
2421         node 
= node
->Next(); 
2427 long wxListMainWindow::FindItem(long start
, long data
) 
2430     if (pos 
< 0) pos 
= 0; 
2431     wxNode 
*node 
= m_lines
.Nth( pos 
); 
2434         wxListLineData 
*line 
= (wxListLineData
*)node
->Data(); 
2436         line
->GetItem( 0, item 
); 
2437         if (item
.m_data 
== data
) return pos
; 
2438         node 
= node
->Next(); 
2444 long wxListMainWindow::HitTest( int x
, int y
, int &flags 
) 
2446     wxNode 
*node 
= m_lines
.First(); 
2450         wxListLineData 
*line 
= (wxListLineData
*)node
->Data(); 
2451         long ret 
= line
->IsHit( x
, y 
); 
2457         node 
= node
->Next(); 
2463 void wxListMainWindow::InsertItem( wxListItem 
&item 
) 
2467     if (m_mode 
& wxLC_REPORT
) mode 
= wxLC_REPORT
; 
2468     else if (m_mode 
& wxLC_LIST
) mode 
= wxLC_LIST
; 
2469     else if (m_mode 
& wxLC_ICON
) mode 
= wxLC_ICON
; 
2470     else if (m_mode 
& wxLC_SMALL_ICON
) mode 
= wxLC_ICON
;  // no typo 
2472     wxListLineData 
*line 
= new wxListLineData( this, mode
, m_hilightBrush 
); 
2474     if (m_mode 
& wxLC_REPORT
) 
2476         line
->InitItems( GetColumnCount() ); 
2477         item
.m_width 
= GetColumnWidth( 0 )-3; 
2481         line
->InitItems( 1 ); 
2484     line
->SetItem( 0, item 
); 
2485     if ((item
.m_itemId 
>= 0) && (item
.m_itemId 
< (int)m_lines
.GetCount())) 
2487         wxNode 
*node 
= m_lines
.Nth( item
.m_itemId 
); 
2488         if (node
) m_lines
.Insert( node
, line 
); 
2492         m_lines
.Append( line 
); 
2496 void wxListMainWindow::InsertColumn( long col
, wxListItem 
&item 
) 
2499     if (m_mode 
& wxLC_REPORT
) 
2501         if (item
.m_width 
== wxLIST_AUTOSIZE_USEHEADER
) item
.m_width 
= GetTextLength( item
.m_text 
); 
2502         wxListHeaderData 
*column 
= new wxListHeaderData( item 
); 
2503         if ((col 
>= 0) && (col 
< (int)m_columns
.GetCount())) 
2505             wxNode 
*node 
= m_columns
.Nth( col 
); 
2507                  m_columns
.Insert( node
, column 
); 
2511             m_columns
.Append( column 
); 
2516 wxListCtrlCompare list_ctrl_compare_func_2
; 
2517 long              list_ctrl_compare_data
; 
2519 int LINKAGEMODE 
list_ctrl_compare_func_1( const void *arg1
, const void *arg2 
) 
2521     wxListLineData 
*line1 
= *((wxListLineData
**)arg1
); 
2522     wxListLineData 
*line2 
= *((wxListLineData
**)arg2
); 
2524     line1
->GetItem( 0, item 
); 
2525     long data1 
= item
.m_data
; 
2526     line2
->GetItem( 0, item 
); 
2527     long data2 
= item
.m_data
; 
2528     return list_ctrl_compare_func_2( data1
, data2
, list_ctrl_compare_data 
); 
2531 void wxListMainWindow::SortItems( wxListCtrlCompare fn
, long data 
) 
2533     list_ctrl_compare_func_2 
= fn
; 
2534     list_ctrl_compare_data 
= data
; 
2535     m_lines
.Sort( list_ctrl_compare_func_1 
); 
2538 void wxListMainWindow::OnScroll(wxScrollWinEvent
& event
) 
2540         wxScrolledWindow::OnScroll( event 
) ; 
2541 #if wxUSE_GENERIC_LIST_EXTENSIONS 
2543     if (event
.GetOrientation() == wxHORIZONTAL 
&& ( m_mode 
& wxLC_REPORT 
)) 
2545             wxListCtrl
* lc 
= wxDynamicCast( GetParent() , wxListCtrl 
) ; 
2548                     lc
->m_headerWin
->Refresh() ; 
2550                         lc
->m_headerWin
->MacUpdateImmediately() ; 
2557 // ------------------------------------------------------------------------------------- 
2559 // ------------------------------------------------------------------------------------- 
2561 IMPLEMENT_DYNAMIC_CLASS(wxListItem
, wxObject
) 
2563 wxListItem::wxListItem() 
2572     m_format 
= wxLIST_FORMAT_CENTRE
; 
2578 // ------------------------------------------------------------------------------------- 
2580 // ------------------------------------------------------------------------------------- 
2582 IMPLEMENT_DYNAMIC_CLASS(wxListEvent
, wxNotifyEvent
) 
2584 wxListEvent::wxListEvent( wxEventType commandType
, int id 
): 
2585   wxNotifyEvent( commandType
, id 
) 
2591     m_cancelled 
= FALSE
; 
2596 void wxListEvent::CopyObject(wxObject
& object_dest
) const 
2598     wxListEvent 
*obj 
= (wxListEvent 
*)&object_dest
; 
2600     wxNotifyEvent::CopyObject(object_dest
); 
2602     obj
->m_code 
= m_code
; 
2603     obj
->m_itemIndex 
= m_itemIndex
; 
2604     obj
->m_oldItemIndex 
= m_oldItemIndex
; 
2606     obj
->m_cancelled 
= m_cancelled
; 
2607     obj
->m_pointDrag 
= m_pointDrag
; 
2608     obj
->m_item
.m_mask 
= m_item
.m_mask
; 
2609     obj
->m_item
.m_itemId 
= m_item
.m_itemId
; 
2610     obj
->m_item
.m_col 
= m_item
.m_col
; 
2611     obj
->m_item
.m_state 
= m_item
.m_state
; 
2612     obj
->m_item
.m_stateMask 
= m_item
.m_stateMask
; 
2613     obj
->m_item
.m_text 
= m_item
.m_text
; 
2614     obj
->m_item
.m_image 
= m_item
.m_image
; 
2615     obj
->m_item
.m_data 
= m_item
.m_data
; 
2616     obj
->m_item
.m_format 
= m_item
.m_format
; 
2617     obj
->m_item
.m_width 
= m_item
.m_width
; 
2619     if ( m_item
.HasAttributes() ) 
2621         obj
->m_item
.SetTextColour(m_item
.GetTextColour()); 
2625 // ------------------------------------------------------------------------------------- 
2627 // ------------------------------------------------------------------------------------- 
2629 IMPLEMENT_DYNAMIC_CLASS(wxListCtrl
, wxControl
) 
2631 BEGIN_EVENT_TABLE(wxListCtrl
,wxControl
) 
2632   EVT_SIZE          (wxListCtrl::OnSize
) 
2633   EVT_IDLE          (wxListCtrl::OnIdle
) 
2636 wxListCtrl::wxListCtrl() 
2638     m_imageListNormal 
= (wxImageList 
*) NULL
; 
2639     m_imageListSmall 
= (wxImageList 
*) NULL
; 
2640     m_imageListState 
= (wxImageList 
*) NULL
; 
2641     m_mainWin 
= (wxListMainWindow
*) NULL
; 
2642     m_headerWin 
= (wxListHeaderWindow
*) NULL
; 
2645 wxListCtrl::~wxListCtrl() 
2649 bool wxListCtrl::Create( wxWindow 
*parent
, wxWindowID id
, 
2650       const wxPoint 
&pos
, const wxSize 
&size
, 
2651 #if wxUSE_VALIDATORS 
2652       long style
, const wxValidator 
&validator
, 
2654       const wxString 
&name 
) 
2656     m_imageListNormal 
= (wxImageList 
*) NULL
; 
2657     m_imageListSmall 
= (wxImageList 
*) NULL
; 
2658     m_imageListState 
= (wxImageList 
*) NULL
; 
2659     m_mainWin 
= (wxListMainWindow
*) NULL
; 
2660     m_headerWin 
= (wxListHeaderWindow
*) NULL
; 
2665 #pragma message disable codcauunr 
2666    // VMS reports on this part the warning: 
2667    // statement either is unreachable or causes unreachable code 
2669    if ((s 
& wxLC_REPORT 
== 0) && 
2670         (s 
& wxLC_LIST 
== 0) && 
2671         (s 
& wxLC_ICON 
== 0)) 
2676 #pragma message enable codcauunr 
2679     bool ret 
= wxControl::Create( parent
, id
, pos
, size
, s
, name 
); 
2681 #if wxUSE_VALIDATORS 
2682     SetValidator( validator 
); 
2685     if (s 
& wxSUNKEN_BORDER
) s 
-= wxSUNKEN_BORDER
; 
2687     m_mainWin 
= new wxListMainWindow( this, -1, wxPoint(0,0), size
, s 
); 
2689     if (HasFlag(wxLC_REPORT
)) 
2690         m_headerWin 
= new wxListHeaderWindow( this, -1, m_mainWin
, wxPoint(0,0), wxSize(size
.x
,23), wxTAB_TRAVERSAL 
); 
2692         m_headerWin 
= (wxListHeaderWindow 
*) NULL
; 
2694     SetBackgroundColour( *wxWHITE 
); 
2699 void wxListCtrl::OnSize( wxSizeEvent 
&WXUNUSED(event
) ) 
2701     /* handled in OnIdle */ 
2703     if (m_mainWin
) m_mainWin
->m_dirty 
= TRUE
; 
2706 void wxListCtrl::SetSingleStyle( long style
, bool add 
) 
2708     long flag 
= GetWindowStyle(); 
2712         if (style 
& wxLC_MASK_TYPE
)  flag 
= flag 
& ~wxLC_MASK_TYPE
; 
2713         if (style 
& wxLC_MASK_ALIGN
) flag 
= flag 
& ~wxLC_MASK_ALIGN
; 
2714         if (style 
& wxLC_MASK_SORT
) flag 
= flag 
& ~wxLC_MASK_SORT
; 
2723         if (flag 
& style
) flag 
-= style
; 
2726     SetWindowStyleFlag( flag 
); 
2729 void wxListCtrl::SetWindowStyleFlag( long flag 
) 
2733         m_mainWin
->DeleteEverything(); 
2737         GetClientSize( &width
, &height 
); 
2739         m_mainWin
->SetMode( flag 
); 
2741         if (flag 
& wxLC_REPORT
) 
2743             if (!HasFlag(wxLC_REPORT
)) 
2747                     m_headerWin 
= new wxListHeaderWindow( this, -1, m_mainWin
, 
2748                       wxPoint(0,0), wxSize(width
,23), wxTAB_TRAVERSAL 
); 
2749                     if (HasFlag(wxLC_NO_HEADER
)) 
2750                         m_headerWin
->Show( FALSE 
); 
2754                     if (flag 
& wxLC_NO_HEADER
) 
2755                         m_headerWin
->Show( FALSE 
); 
2757                         m_headerWin
->Show( TRUE 
); 
2763             if (HasFlag(wxLC_REPORT
) && !(HasFlag(wxLC_NO_HEADER
))) 
2765                 m_headerWin
->Show( FALSE 
); 
2770     wxWindow::SetWindowStyleFlag( flag 
); 
2773 bool wxListCtrl::GetColumn(int col
, wxListItem 
&item
) const 
2775     m_mainWin
->GetColumn( col
, item 
); 
2779 bool wxListCtrl::SetColumn( int col
, wxListItem
& item 
) 
2781     m_mainWin
->SetColumn( col
, item 
); 
2785 int wxListCtrl::GetColumnWidth( int col 
) const 
2787     return m_mainWin
->GetColumnWidth( col 
); 
2790 bool wxListCtrl::SetColumnWidth( int col
, int width 
) 
2792     m_mainWin
->SetColumnWidth( col
, width 
); 
2796 int wxListCtrl::GetCountPerPage() const 
2798   return m_mainWin
->GetCountPerPage();  // different from Windows ? 
2801 bool wxListCtrl::GetItem( wxListItem 
&info 
) const 
2803     m_mainWin
->GetItem( info 
); 
2807 bool wxListCtrl::SetItem( wxListItem 
&info 
) 
2809     m_mainWin
->SetItem( info 
); 
2813 long wxListCtrl::SetItem( long index
, int col
, const wxString
& label
, int imageId 
) 
2816     info
.m_text 
= label
; 
2817     info
.m_mask 
= wxLIST_MASK_TEXT
; 
2818     info
.m_itemId 
= index
; 
2822         info
.m_image 
= imageId
; 
2823         info
.m_mask 
|= wxLIST_MASK_IMAGE
; 
2825     m_mainWin
->SetItem(info
); 
2829 int wxListCtrl::GetItemState( long item
, long stateMask 
) const 
2831     return m_mainWin
->GetItemState( item
, stateMask 
); 
2834 bool wxListCtrl::SetItemState( long item
, long state
, long stateMask 
) 
2836     m_mainWin
->SetItemState( item
, state
, stateMask 
); 
2840 bool wxListCtrl::SetItemImage( long item
, int image
, int WXUNUSED(selImage
) ) 
2843     info
.m_image 
= image
; 
2844     info
.m_mask 
= wxLIST_MASK_IMAGE
; 
2845     info
.m_itemId 
= item
; 
2846     m_mainWin
->SetItem( info 
); 
2850 wxString 
wxListCtrl::GetItemText( long item 
) const 
2853     info
.m_itemId 
= item
; 
2854     m_mainWin
->GetItem( info 
); 
2858 void wxListCtrl::SetItemText( long item
, const wxString 
&str 
) 
2861     info
.m_mask 
= wxLIST_MASK_TEXT
; 
2862     info
.m_itemId 
= item
; 
2864     m_mainWin
->SetItem( info 
); 
2867 long wxListCtrl::GetItemData( long item 
) const 
2870     info
.m_itemId 
= item
; 
2871     m_mainWin
->GetItem( info 
); 
2875 bool wxListCtrl::SetItemData( long item
, long data 
) 
2878     info
.m_mask 
= wxLIST_MASK_DATA
; 
2879     info
.m_itemId 
= item
; 
2881     m_mainWin
->SetItem( info 
); 
2885 bool wxListCtrl::GetItemRect( long item
, wxRect 
&rect
,  int WXUNUSED(code
) ) const 
2887     m_mainWin
->GetItemRect( item
, rect 
); 
2891 bool wxListCtrl::GetItemPosition( long item
, wxPoint
& pos 
) const 
2893     m_mainWin
->GetItemPosition( item
, pos 
); 
2897 bool wxListCtrl::SetItemPosition( long WXUNUSED(item
), const wxPoint
& WXUNUSED(pos
) ) 
2902 int wxListCtrl::GetItemCount() const 
2904     return m_mainWin
->GetItemCount(); 
2907 int wxListCtrl::GetColumnCount() const 
2909     return m_mainWin
->GetColumnCount(); 
2912 void wxListCtrl::SetItemSpacing( int spacing
, bool isSmall 
) 
2914     m_mainWin
->SetItemSpacing( spacing
, isSmall 
); 
2917 int wxListCtrl::GetItemSpacing( bool isSmall 
) const 
2919     return m_mainWin
->GetItemSpacing( isSmall 
); 
2922 int wxListCtrl::GetSelectedItemCount() const 
2924     return m_mainWin
->GetSelectedItemCount(); 
2927 wxColour 
wxListCtrl::GetTextColour() const 
2929     return GetForegroundColour(); 
2932 void wxListCtrl::SetTextColour(const wxColour
& col
) 
2934     SetForegroundColour(col
); 
2937 long wxListCtrl::GetTopItem() const 
2942 long wxListCtrl::GetNextItem( long item
, int geom
, int state 
) const 
2944     return m_mainWin
->GetNextItem( item
, geom
, state 
); 
2947 wxImageList 
*wxListCtrl::GetImageList(int which
) const 
2949     if (which 
== wxIMAGE_LIST_NORMAL
) 
2951         return m_imageListNormal
; 
2953     else if (which 
== wxIMAGE_LIST_SMALL
) 
2955         return m_imageListSmall
; 
2957     else if (which 
== wxIMAGE_LIST_STATE
) 
2959         return m_imageListState
; 
2961     return (wxImageList 
*) NULL
; 
2964 void wxListCtrl::SetImageList( wxImageList 
*imageList
, int which 
) 
2966     m_mainWin
->SetImageList( imageList
, which 
); 
2969 bool wxListCtrl::Arrange( int WXUNUSED(flag
) ) 
2974 bool wxListCtrl::DeleteItem( long item 
) 
2976     m_mainWin
->DeleteItem( item 
); 
2980 bool wxListCtrl::DeleteAllItems() 
2982     m_mainWin
->DeleteAllItems(); 
2986 bool wxListCtrl::DeleteAllColumns() 
2988     for ( size_t n 
= 0; n 
< m_mainWin
->m_columns
.GetCount(); n
++ ) 
2994 void wxListCtrl::ClearAll() 
2996     m_mainWin
->DeleteEverything(); 
2999 bool wxListCtrl::DeleteColumn( int col 
) 
3001     m_mainWin
->DeleteColumn( col 
); 
3005 void wxListCtrl::Edit( long item 
) 
3007     m_mainWin
->Edit( item 
); 
3010 bool wxListCtrl::EnsureVisible( long item 
) 
3012     m_mainWin
->EnsureVisible( item 
); 
3016 long wxListCtrl::FindItem( long start
, const wxString
& str
,  bool partial 
) 
3018     return m_mainWin
->FindItem( start
, str
, partial 
); 
3021 long wxListCtrl::FindItem( long start
, long data 
) 
3023     return m_mainWin
->FindItem( start
, data 
); 
3026 long wxListCtrl::FindItem( long WXUNUSED(start
), const wxPoint
& WXUNUSED(pt
), 
3027                            int WXUNUSED(direction
)) 
3032 long wxListCtrl::HitTest( const wxPoint 
&point
, int &flags 
) 
3034     return m_mainWin
->HitTest( (int)point
.x
, (int)point
.y
, flags 
); 
3037 long wxListCtrl::InsertItem( wxListItem
& info 
) 
3039     m_mainWin
->InsertItem( info 
); 
3040     return info
.m_itemId
; 
3043 long wxListCtrl::InsertItem( long index
, const wxString 
&label 
) 
3046     info
.m_text 
= label
; 
3047     info
.m_mask 
= wxLIST_MASK_TEXT
; 
3048     info
.m_itemId 
= index
; 
3049     return InsertItem( info 
); 
3052 long wxListCtrl::InsertItem( long index
, int imageIndex 
) 
3055     info
.m_mask 
= wxLIST_MASK_IMAGE
; 
3056     info
.m_image 
= imageIndex
; 
3057     info
.m_itemId 
= index
; 
3058     return InsertItem( info 
); 
3061 long wxListCtrl::InsertItem( long index
, const wxString 
&label
, int imageIndex 
) 
3064     info
.m_text 
= label
; 
3065     info
.m_image 
= imageIndex
; 
3066     info
.m_mask 
= wxLIST_MASK_TEXT 
| wxLIST_MASK_IMAGE
; 
3067     info
.m_itemId 
= index
; 
3068     return InsertItem( info 
); 
3071 long wxListCtrl::InsertColumn( long col
, wxListItem 
&item 
) 
3073     m_mainWin
->InsertColumn( col
, item 
); 
3077 long wxListCtrl::InsertColumn( long col
, const wxString 
&heading
, 
3078                                int format
, int width 
) 
3081     item
.m_mask 
= wxLIST_MASK_TEXT 
| wxLIST_MASK_FORMAT
; 
3082     item
.m_text 
= heading
; 
3085         item
.m_mask 
|= wxLIST_MASK_WIDTH
; 
3086         item
.m_width 
= width
; 
3088     item
.m_format 
= format
; 
3090     return InsertColumn( col
, item 
); 
3093 bool wxListCtrl::ScrollList( int WXUNUSED(dx
), int WXUNUSED(dy
) ) 
3099 // fn is a function which takes 3 long arguments: item1, item2, data. 
3100 // item1 is the long data associated with a first item (NOT the index). 
3101 // item2 is the long data associated with a second item (NOT the index). 
3102 // data is the same value as passed to SortItems. 
3103 // The return value is a negative number if the first item should precede the second 
3104 // item, a positive number of the second item should precede the first, 
3105 // or zero if the two items are equivalent. 
3106 // data is arbitrary data to be passed to the sort function. 
3108 bool wxListCtrl::SortItems( wxListCtrlCompare fn
, long data 
) 
3110     m_mainWin
->SortItems( fn
, data 
); 
3114 void wxListCtrl::OnIdle( wxIdleEvent 
&WXUNUSED(event
) ) 
3116     if (!m_mainWin
->m_dirty
) return; 
3120     GetClientSize( &cw
, &ch 
); 
3127     if (HasFlag(wxLC_REPORT
) && !HasFlag(wxLC_NO_HEADER
)) 
3129         m_headerWin
->GetPosition( &x
, &y 
); 
3130         m_headerWin
->GetSize( &w
, &h 
); 
3131         if ((x 
!= 0) || (y 
!= 0) || (w 
!= cw
) || (h 
!= 23)) 
3132             m_headerWin
->SetSize( 0, 0, cw
, 23 ); 
3134         m_mainWin
->GetPosition( &x
, &y 
); 
3135         m_mainWin
->GetSize( &w
, &h 
); 
3136         if ((x 
!= 0) || (y 
!= 24) || (w 
!= cw
) || (h 
!= ch
-24)) 
3137             m_mainWin
->SetSize( 0, 24, cw
, ch
-24 ); 
3141         m_mainWin
->GetPosition( &x
, &y 
); 
3142         m_mainWin
->GetSize( &w
, &h 
); 
3143         if ((x 
!= 0) || (y 
!= 24) || (w 
!= cw
) || (h 
!= ch
)) 
3144             m_mainWin
->SetSize( 0, 0, cw
, ch 
); 
3147     m_mainWin
->CalculatePositions(); 
3148     m_mainWin
->RealizeChanges(); 
3149     m_mainWin
->m_dirty 
= FALSE
; 
3150     m_mainWin
->Refresh(); 
3153 bool wxListCtrl::SetBackgroundColour( const wxColour 
&colour 
) 
3155     if ( !wxWindow::SetBackgroundColour( colour 
) ) 
3160         m_mainWin
->SetBackgroundColour( colour 
); 
3161         m_mainWin
->m_dirty 
= TRUE
; 
3166 //        m_headerWin->SetBackgroundColour( colour ); 
3172 bool wxListCtrl::SetForegroundColour( const wxColour 
&colour 
) 
3174     if ( !wxWindow::SetForegroundColour( colour 
) ) 
3179         m_mainWin
->SetForegroundColour( colour 
); 
3180         m_mainWin
->m_dirty 
= TRUE
; 
3185         m_headerWin
->SetForegroundColour( colour 
); 
3191 bool wxListCtrl::SetFont( const wxFont 
&font 
) 
3193     if ( !wxWindow::SetFont( font 
) ) 
3198         m_mainWin
->SetFont( font 
); 
3199         m_mainWin
->m_dirty 
= TRUE
; 
3204         m_headerWin
->SetFont( font 
);