]> git.saurik.com Git - wxWidgets.git/blame - src/generic/listctrl.cpp
deTABified
[wxWidgets.git] / src / generic / listctrl.cpp
CommitLineData
c801d85f
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: listctrl.cpp
3// Purpose:
4// Author: Robert Roebling
0208334d
RR
5// Id: $Id$
6// Copyright: (c) 1998 Robert Roebling
bd8289c1 7// Licence: wxWindows licence
c801d85f
KB
8/////////////////////////////////////////////////////////////////////////////
9
10#ifdef __GNUG__
510fc784
RR
11 #pragma implementation "listctrl.h"
12 #pragma implementation "listctrlbase.h"
c801d85f
KB
13#endif
14
1e6d9499
JS
15// For compilers that support precompilation, includes "wx.h".
16#include "wx/wxprec.h"
17
18#ifdef __BORLANDC__
19#pragma hdrstop
20#endif
21
0208334d
RR
22#include "wx/dcscreen.h"
23#include "wx/app.h"
02527779 24#include "wx/listctrl.h"
f60d0f94 25#include "wx/generic/imaglist.h"
c801d85f 26
7c74e7fe
SC
27#ifndef wxUSE_GENERIC_LIST_EXTENSIONS
28#define wxUSE_GENERIC_LIST_EXTENSIONS 0
29#endif
30
c801d85f
KB
31//-----------------------------------------------------------------------------
32// wxListItemData
33//-----------------------------------------------------------------------------
34
35IMPLEMENT_DYNAMIC_CLASS(wxListItemData,wxObject);
36
fd9811b1 37wxListItemData::wxListItemData()
c801d85f 38{
92976ab6
RR
39 m_image = -1;
40 m_data = 0;
41 m_xpos = 0;
42 m_ypos = 0;
43 m_width = 0;
44 m_height = 0;
0530737d 45 m_attr = NULL;
e1e955e1 46}
c801d85f
KB
47
48wxListItemData::wxListItemData( const wxListItem &info )
49{
92976ab6
RR
50 m_image = -1;
51 m_data = 0;
0530737d
VZ
52 m_attr = NULL;
53
92976ab6 54 SetItem( info );
e1e955e1 55}
c801d85f
KB
56
57void wxListItemData::SetItem( const wxListItem &info )
58{
92976ab6
RR
59 if (info.m_mask & wxLIST_MASK_TEXT) m_text = info.m_text;
60 if (info.m_mask & wxLIST_MASK_IMAGE) m_image = info.m_image;
61 if (info.m_mask & wxLIST_MASK_DATA) m_data = info.m_data;
0530737d
VZ
62
63 if ( info.HasAttributes() )
64 {
65 if ( m_attr )
66 *m_attr = *info.GetAttributes();
67 else
68 m_attr = new wxListItemAttr(*info.GetAttributes());
69 }
70
92976ab6
RR
71 m_xpos = 0;
72 m_ypos = 0;
73 m_width = info.m_width;
74 m_height = 0;
e1e955e1 75}
c801d85f
KB
76
77void wxListItemData::SetText( const wxString &s )
78{
92976ab6 79 m_text = s;
e1e955e1 80}
c801d85f 81
debe6624 82void wxListItemData::SetImage( int image )
c801d85f 83{
92976ab6 84 m_image = image;
e1e955e1 85}
c801d85f 86
debe6624 87void wxListItemData::SetData( long data )
c801d85f 88{
92976ab6 89 m_data = data;
e1e955e1 90}
c801d85f 91
debe6624 92void wxListItemData::SetPosition( int x, int y )
c801d85f 93{
92976ab6
RR
94 m_xpos = x;
95 m_ypos = y;
e1e955e1 96}
c801d85f 97
1e6d9499 98void wxListItemData::SetSize( int width, int height )
c801d85f 99{
92976ab6
RR
100 if (width != -1) m_width = width;
101 if (height != -1) m_height = height;
e1e955e1 102}
c801d85f 103
fd9811b1 104bool wxListItemData::HasImage() const
c801d85f 105{
92976ab6 106 return (m_image >= 0);
e1e955e1 107}
c801d85f 108
fd9811b1 109bool wxListItemData::HasText() const
c801d85f 110{
92976ab6 111 return (!m_text.IsNull());
e1e955e1 112}
c801d85f 113
debe6624 114bool wxListItemData::IsHit( int x, int y ) const
c801d85f 115{
92976ab6 116 return ((x >= m_xpos) && (x <= m_xpos+m_width) && (y >= m_ypos) && (y <= m_ypos+m_height));
e1e955e1 117}
c801d85f
KB
118
119void wxListItemData::GetText( wxString &s )
120{
92976ab6 121 s = m_text;
e1e955e1 122}
c801d85f 123
fd9811b1 124int wxListItemData::GetX() const
c801d85f 125{
92976ab6 126 return m_xpos;
e1e955e1 127}
c801d85f 128
fd9811b1 129int wxListItemData::GetY() const
c801d85f 130{
92976ab6 131 return m_ypos;
e1e955e1 132}
c801d85f 133
fd9811b1 134int wxListItemData::GetWidth() const
c801d85f 135{
92976ab6 136 return m_width;
e1e955e1 137}
c801d85f 138
fd9811b1 139int wxListItemData::GetHeight() const
c801d85f 140{
92976ab6 141 return m_height;
e1e955e1 142}
c801d85f 143
fd9811b1 144int wxListItemData::GetImage() const
c801d85f 145{
92976ab6 146 return m_image;
e1e955e1 147}
c801d85f 148
0530737d 149void wxListItemData::GetItem( wxListItem &info ) const
c801d85f 150{
92976ab6
RR
151 info.m_text = m_text;
152 info.m_image = m_image;
153 info.m_data = m_data;
c801d85f 154
0530737d
VZ
155 if ( m_attr )
156 {
157 if ( m_attr->HasTextColour() )
158 info.SetTextColour(m_attr->GetTextColour());
159 if ( m_attr->HasBackgroundColour() )
160 info.SetBackgroundColour(m_attr->GetBackgroundColour());
161 if ( m_attr->HasFont() )
162 info.SetFont(m_attr->GetFont());
163 }
e1e955e1 164}
c801d85f
KB
165
166//-----------------------------------------------------------------------------
167// wxListHeaderData
168//-----------------------------------------------------------------------------
169
170IMPLEMENT_DYNAMIC_CLASS(wxListHeaderData,wxObject);
171
fd9811b1 172wxListHeaderData::wxListHeaderData()
c801d85f 173{
92976ab6
RR
174 m_mask = 0;
175 m_image = 0;
176 m_format = 0;
177 m_width = 0;
178 m_xpos = 0;
179 m_ypos = 0;
180 m_height = 0;
e1e955e1 181}
c801d85f
KB
182
183wxListHeaderData::wxListHeaderData( const wxListItem &item )
184{
92976ab6
RR
185 SetItem( item );
186 m_xpos = 0;
187 m_ypos = 0;
188 m_height = 0;
e1e955e1 189}
c801d85f
KB
190
191void wxListHeaderData::SetItem( const wxListItem &item )
192{
92976ab6
RR
193 m_mask = item.m_mask;
194 m_text = item.m_text;
195 m_image = item.m_image;
196 m_format = item.m_format;
197 m_width = item.m_width;
198 if (m_width < 0) m_width = 80;
199 if (m_width < 6) m_width = 6;
e1e955e1 200}
c801d85f 201
debe6624 202void wxListHeaderData::SetPosition( int x, int y )
c801d85f 203{
92976ab6
RR
204 m_xpos = x;
205 m_ypos = y;
e1e955e1 206}
c801d85f 207
debe6624 208void wxListHeaderData::SetHeight( int h )
c801d85f 209{
92976ab6 210 m_height = h;
e1e955e1 211}
c801d85f 212
debe6624 213void wxListHeaderData::SetWidth( int w )
c801d85f 214{
92976ab6
RR
215 m_width = w;
216 if (m_width < 0) m_width = 80;
217 if (m_width < 6) m_width = 6;
e1e955e1 218}
c801d85f 219
debe6624 220void wxListHeaderData::SetFormat( int format )
c801d85f 221{
92976ab6 222 m_format = format;
e1e955e1 223}
c801d85f 224
fd9811b1 225bool wxListHeaderData::HasImage() const
c801d85f 226{
92976ab6 227 return (m_image != 0);
e1e955e1 228}
c801d85f 229
fd9811b1 230bool wxListHeaderData::HasText() const
c801d85f 231{
92976ab6 232 return (m_text.Length() > 0);
e1e955e1 233}
c801d85f
KB
234
235bool wxListHeaderData::IsHit( int x, int y ) const
236{
92976ab6 237 return ((x >= m_xpos) && (x <= m_xpos+m_width) && (y >= m_ypos) && (y <= m_ypos+m_height));
e1e955e1 238}
c801d85f
KB
239
240void wxListHeaderData::GetItem( wxListItem &item )
241{
92976ab6
RR
242 item.m_mask = m_mask;
243 item.m_text = m_text;
244 item.m_image = m_image;
245 item.m_format = m_format;
246 item.m_width = m_width;
e1e955e1 247}
c801d85f
KB
248
249void wxListHeaderData::GetText( wxString &s )
250{
92976ab6 251 s = m_text;
e1e955e1 252}
c801d85f 253
fd9811b1 254int wxListHeaderData::GetImage() const
c801d85f 255{
92976ab6 256 return m_image;
e1e955e1 257}
c801d85f 258
fd9811b1 259int wxListHeaderData::GetWidth() const
c801d85f 260{
92976ab6 261 return m_width;
e1e955e1 262}
c801d85f 263
fd9811b1 264int wxListHeaderData::GetFormat() const
c801d85f 265{
92976ab6 266 return m_format;
e1e955e1 267}
c801d85f
KB
268
269//-----------------------------------------------------------------------------
270// wxListLineData
271//-----------------------------------------------------------------------------
272
273IMPLEMENT_DYNAMIC_CLASS(wxListLineData,wxObject);
274
debe6624 275wxListLineData::wxListLineData( wxListMainWindow *owner, int mode, wxBrush *hilightBrush )
c801d85f 276{
92976ab6
RR
277 m_mode = mode;
278 m_hilighted = FALSE;
279 m_owner = owner;
280 m_hilightBrush = hilightBrush;
281 m_items.DeleteContents( TRUE );
282 m_spacing = 0;
e1e955e1 283}
c801d85f 284
1e6d9499 285void wxListLineData::CalculateSize( wxDC *dc, int spacing )
c801d85f 286{
92976ab6
RR
287 m_spacing = spacing;
288 switch (m_mode)
c801d85f 289 {
92976ab6
RR
290 case wxLC_ICON:
291 {
292 m_bound_all.width = m_spacing;
293 m_bound_all.height = m_spacing+13;
294 wxNode *node = m_items.First();
295 if (node)
296 {
297 wxListItemData *item = (wxListItemData*)node->Data();
0530737d 298 wxString s = item->GetText();
13111b2a 299 wxCoord lw,lh;
92976ab6
RR
300 dc->GetTextExtent( s, &lw, &lh );
301 if (lw > m_spacing) m_bound_all.width = lw;
302 }
303 break;
304 }
305 case wxLC_LIST:
306 {
307 wxNode *node = m_items.First();
308 if (node)
309 {
310 wxListItemData *item = (wxListItemData*)node->Data();
0530737d 311 wxString s = item->GetText();
13111b2a 312 wxCoord lw,lh;
92976ab6
RR
313 dc->GetTextExtent( s, &lw, &lh );
314 m_bound_all.width = lw;
315 m_bound_all.height = lh;
0b855868
RR
316 if (item->HasImage())
317 {
5dd26b08
JS
318#ifdef __WIN16__
319 int w = 0;
320 int h = 0;
321#else
13111b2a
VZ
322 wxCoord w = 0;
323 wxCoord h = 0;
5dd26b08 324#endif
0b855868 325 m_owner->GetImageSize( item->GetImage(), w, h );
bffa1c77
VZ
326 m_bound_all.width += 4 + w;
327 if (h > m_bound_all.height) m_bound_all.height = h;
328 }
92976ab6
RR
329 }
330 break;
331 }
332 case wxLC_REPORT:
333 {
334 m_bound_all.width = 0;
335 m_bound_all.height = 0;
336 wxNode *node = m_items.First();
337 while (node)
338 {
339 wxListItemData *item = (wxListItemData*)node->Data();
340 wxString s;
341 item->GetText( s );
342 if (s.IsNull()) s = "H";
13111b2a 343 wxCoord lw,lh;
7c74e7fe 344 dc->GetTextExtent( s, &lw, &lh );
92976ab6 345 item->SetSize( item->GetWidth(), lh );
7c74e7fe 346 m_bound_all.width += lw;
92976ab6
RR
347 m_bound_all.height = lh;
348 node = node->Next();
349 }
350 break;
351 }
e1e955e1 352 }
e1e955e1 353}
c801d85f 354
1e6d9499 355void wxListLineData::SetPosition( wxDC *dc, int x, int y, int window_width )
c801d85f 356{
0b855868
RR
357 m_bound_all.x = x;
358 m_bound_all.y = y;
359 switch (m_mode)
360 {
361 case wxLC_ICON:
c801d85f 362 {
0b855868
RR
363 AssignRect( m_bound_icon, 0, 0, 0, 0 );
364 AssignRect( m_bound_label, 0, 0, 0, 0 );
365 AssignRect( m_bound_hilight, m_bound_all );
366 wxNode *node = m_items.First();
367 if (node)
368 {
369 wxListItemData *item = (wxListItemData*)node->Data();
370 if (item->HasImage())
371 {
372 wxListItemData *item = (wxListItemData*)node->Data();
373 int w = 0;
374 int h = 0;
375 m_owner->GetImageSize( item->GetImage(), w, h );
376 m_bound_icon.x = m_bound_all.x + (m_spacing/2) - (w/2);
377 m_bound_icon.y = m_bound_all.y + m_spacing - h - 5;
378 m_bound_icon.width = w;
379 m_bound_icon.height = h;
380 if (!item->HasText())
381 {
382 AssignRect( m_bound_hilight, m_bound_icon );
383 m_bound_hilight.x -= 5;
384 m_bound_hilight.y -= 5;
385 m_bound_hilight.width += 9;
386 m_bound_hilight.height += 9;
387 }
388 }
389 if (item->HasText())
390 {
391 wxString s;
392 item->GetText( s );
13111b2a 393 wxCoord lw,lh;
0b855868
RR
394 dc->GetTextExtent( s, &lw, &lh );
395 if (m_bound_all.width > m_spacing)
396 m_bound_label.x = m_bound_all.x;
397 else
398 m_bound_label.x = m_bound_all.x + (m_spacing/2) - lw/2;
399 m_bound_label.y = m_bound_all.y + m_bound_all.height - lh;
400 m_bound_label.width = lw;
401 m_bound_label.height = lh;
402 AssignRect( m_bound_hilight, m_bound_label );
403 m_bound_hilight.x -= 2;
404 m_bound_hilight.y -= 2;
405 m_bound_hilight.width += 4;
406 m_bound_hilight.height += 4;
407 }
408 }
409 break;
e1e955e1 410 }
0b855868 411 case wxLC_LIST:
c801d85f 412 {
0b855868
RR
413 AssignRect( m_bound_label, m_bound_all );
414 m_bound_all.x -= 2;
415 m_bound_all.y -= 2;
416 m_bound_all.width += 4;
417 m_bound_all.height += 3;
418 AssignRect( m_bound_hilight, m_bound_all );
419 AssignRect( m_bound_icon, 0, 0, 0, 0 );
420 wxNode *node = m_items.First();
421 if (node)
422 {
423 wxListItemData *item = (wxListItemData*)node->Data();
424 if (item->HasImage())
bffa1c77 425 {
0b855868
RR
426 m_bound_icon.x = m_bound_all.x + 2;
427 m_bound_icon.y = m_bound_all.y + 2;
bffa1c77
VZ
428 int w;
429 int h;
0b855868
RR
430 m_owner->GetImageSize( item->GetImage(), w, h );
431 m_bound_icon.width = w;
432 m_bound_icon.height = h;
bffa1c77
VZ
433 m_bound_label.x += 4 + w;
434 m_bound_label.width -= 4 + w;
435 }
436 }
0b855868
RR
437 break;
438 }
439 case wxLC_REPORT:
440 {
13111b2a 441 wxCoord lw,lh;
0b855868
RR
442 dc->GetTextExtent( "H", &lw, &lh );
443 m_bound_all.x = 0;
444 m_bound_all.y -= 0;
445 m_bound_all.height = lh+3;
446 m_bound_all.width = window_width;
447 AssignRect( m_bound_hilight, m_bound_all );
448 AssignRect( m_bound_label, m_bound_all );
449 AssignRect( m_bound_icon, 0, 0, 0, 0 );
450 wxNode *node = m_items.First();
451 if (node)
452 {
453 wxListItemData *item = (wxListItemData*)node->Data();
454 wxString s;
455 item->GetText( s );
bffa1c77 456 if (s.IsEmpty()) s = wxT("H");
13111b2a 457 wxCoord lw,lh;
0b855868 458 dc->GetTextExtent( s, &lw, &lh );
bffa1c77
VZ
459 m_bound_label.width = lw;
460 m_bound_label.height = lh;
461 if (item->HasImage())
462 {
0b855868
RR
463 m_bound_icon.x = m_bound_all.x + 2;
464 m_bound_icon.y = m_bound_all.y + 2;
bffa1c77
VZ
465 int w;
466 int h;
0b855868
RR
467 m_owner->GetImageSize( item->GetImage(), w, h );
468 m_bound_icon.width = w;
469 m_bound_icon.height = h;
bffa1c77
VZ
470 m_bound_label.x += 4 + w;
471 }
472 }
0b855868 473 break;
e1e955e1 474 }
e1e955e1 475 }
e1e955e1 476}
c801d85f 477
debe6624 478void wxListLineData::SetColumnPosition( int index, int x )
c801d85f 479{
6f2a55e3 480 wxNode *node = m_items.Nth( (size_t)index );
92976ab6
RR
481 if (node)
482 {
483 wxListItemData *item = (wxListItemData*)node->Data();
484 item->SetPosition( x, m_bound_all.y+1 );
485 }
e1e955e1 486}
c801d85f
KB
487
488void wxListLineData::GetSize( int &width, int &height )
489{
139adb6a
RR
490 width = m_bound_all.width;
491 height = m_bound_all.height;
e1e955e1 492}
c801d85f
KB
493
494void wxListLineData::GetExtent( int &x, int &y, int &width, int &height )
495{
139adb6a
RR
496 x = m_bound_all.x;
497 y = m_bound_all.y;
498 width = m_bound_all.width;
499 height = m_bound_all.height;
e1e955e1 500}
c801d85f
KB
501
502void wxListLineData::GetLabelExtent( int &x, int &y, int &width, int &height )
503{
139adb6a
RR
504 x = m_bound_label.x;
505 y = m_bound_label.y;
506 width = m_bound_label.width;
507 height = m_bound_label.height;
e1e955e1 508}
c801d85f 509
0a240683 510void wxListLineData::GetRect( wxRect &rect )
c801d85f 511{
139adb6a 512 AssignRect( rect, m_bound_all );
e1e955e1 513}
c801d85f 514
debe6624 515long wxListLineData::IsHit( int x, int y )
c801d85f 516{
139adb6a
RR
517 wxNode *node = m_items.First();
518 if (node)
519 {
520 wxListItemData *item = (wxListItemData*)node->Data();
521 if (item->HasImage() && IsInRect( x, y, m_bound_icon )) return wxLIST_HITTEST_ONITEMICON;
522 if (item->HasText() && IsInRect( x, y, m_bound_label )) return wxLIST_HITTEST_ONITEMLABEL;
523// if (!(item->HasImage() || item->HasText())) return 0;
524 }
525 // if there is no icon or text = empty
526 if (IsInRect( x, y, m_bound_all )) return wxLIST_HITTEST_ONITEMICON;
527 return 0;
e1e955e1 528}
c801d85f 529
debe6624 530void wxListLineData::InitItems( int num )
c801d85f 531{
139adb6a 532 for (int i = 0; i < num; i++) m_items.Append( new wxListItemData() );
e1e955e1 533}
c801d85f 534
debe6624 535void wxListLineData::SetItem( int index, const wxListItem &info )
c801d85f 536{
139adb6a
RR
537 wxNode *node = m_items.Nth( index );
538 if (node)
539 {
540 wxListItemData *item = (wxListItemData*)node->Data();
541 item->SetItem( info );
542 }
e1e955e1 543}
c801d85f 544
1e6d9499 545void wxListLineData::GetItem( int index, wxListItem &info )
c801d85f 546{
139adb6a
RR
547 int i = index;
548 wxNode *node = m_items.Nth( i );
549 if (node)
550 {
551 wxListItemData *item = (wxListItemData*)node->Data();
552 item->GetItem( info );
553 }
e1e955e1 554}
c801d85f 555
debe6624 556void wxListLineData::GetText( int index, wxString &s )
c801d85f 557{
139adb6a
RR
558 int i = index;
559 wxNode *node = m_items.Nth( i );
560 s = "";
561 if (node)
562 {
563 wxListItemData *item = (wxListItemData*)node->Data();
564 item->GetText( s );
565 }
e1e955e1 566}
c801d85f 567
debe6624 568void wxListLineData::SetText( int index, const wxString s )
c801d85f 569{
139adb6a
RR
570 int i = index;
571 wxNode *node = m_items.Nth( i );
572 if (node)
573 {
574 wxListItemData *item = (wxListItemData*)node->Data();
575 item->SetText( s );
576 }
e1e955e1 577}
c801d85f 578
debe6624 579int wxListLineData::GetImage( int index )
c801d85f 580{
139adb6a
RR
581 int i = index;
582 wxNode *node = m_items.Nth( i );
583 if (node)
584 {
585 wxListItemData *item = (wxListItemData*)node->Data();
586 return item->GetImage();
587 }
588 return -1;
e1e955e1 589}
c801d85f 590
0530737d
VZ
591void wxListLineData::SetAttributes(wxDC *dc,
592 const wxListItemAttr *attr,
593 const wxColour& colText,
470caaf9
VZ
594 const wxFont& font,
595 bool hilight)
0530737d 596{
470caaf9
VZ
597 // don't use foregroud colour for drawing highlighted items - this might
598 // make them completely invisible (and there is no way to do bit
599 // arithmetics on wxColour, unfortunately)
600 if ( !hilight && attr && attr->HasTextColour() )
0530737d
VZ
601 {
602 dc->SetTextForeground(attr->GetTextColour());
603 }
604 else
605 {
606 dc->SetTextForeground(colText);
607 }
608
609 if ( attr && attr->HasFont() )
610 {
611 dc->SetFont(attr->GetFont());
612 }
613 else
614 {
615 dc->SetFont(font);
616 }
617}
618
1e6d9499 619void wxListLineData::DoDraw( wxDC *dc, bool hilight, bool paintBG )
c801d85f 620{
6f2a55e3
VZ
621 wxCoord dev_x = dc->LogicalToDeviceX( m_bound_all.x-2 );
622 wxCoord dev_y = dc->LogicalToDeviceY( m_bound_all.y-2 );
623 wxCoord dev_w = dc->LogicalToDeviceXRel( m_bound_all.width+4 );
624 wxCoord dev_h = dc->LogicalToDeviceYRel( m_bound_all.height+4 );
004fd0c8 625
139adb6a 626 if (!m_owner->IsExposed( dev_x, dev_y, dev_w, dev_h ))
004fd0c8 627 {
139adb6a
RR
628 return;
629 }
bd8289c1 630
0530737d
VZ
631 wxWindow *listctrl = m_owner->GetParent();
632
633 // default foreground colour
634 wxColour colText;
635 if ( hilight )
636 {
637 colText = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_HIGHLIGHTTEXT );
638 }
639 else
640 {
641 colText = listctrl->GetForegroundColour();
642 }
643
644 // default font
645 wxFont font = listctrl->GetFont();
646
647 // VZ: currently we set the colours/fonts only once, but like this (i.e.
648 // using SetAttributes() inside the loop), it will be trivial to
649 // customize the subitems (in report mode) too.
650 wxListItemData *item = (wxListItemData*)m_items.First()->Data();
651 wxListItemAttr *attr = item->GetAttributes();
470caaf9 652 SetAttributes(dc, attr, colText, font, hilight);
0530737d
VZ
653
654 bool hasBgCol = attr && attr->HasBackgroundColour();
655 if ( paintBG || hasBgCol )
c801d85f 656 {
63852e78
RR
657 if (hilight)
658 {
659 dc->SetBrush( * m_hilightBrush );
63852e78
RR
660 }
661 else
662 {
0530737d
VZ
663 if ( hasBgCol )
664 dc->SetBrush(wxBrush(attr->GetBackgroundColour(), wxSOLID));
665 else
666 dc->SetBrush( * wxWHITE_BRUSH );
63852e78 667 }
0530737d
VZ
668
669 dc->SetPen( * wxTRANSPARENT_PEN );
63852e78
RR
670 dc->DrawRectangle( m_bound_hilight.x, m_bound_hilight.y,
671 m_bound_hilight.width, m_bound_hilight.height );
e1e955e1 672 }
004fd0c8 673
63852e78 674 if (m_mode == wxLC_REPORT)
c801d85f 675 {
63852e78
RR
676 wxNode *node = m_items.First();
677 while (node)
678 {
679 wxListItemData *item = (wxListItemData*)node->Data();
680 dc->SetClippingRegion( item->GetX(), item->GetY(), item->GetWidth()-3, item->GetHeight() );
681 int x = item->GetX();
682 if (item->HasImage())
683 {
684 int y = 0;
685 m_owner->DrawImage( item->GetImage(), dc, x, item->GetY() );
686 m_owner->GetImageSize( item->GetImage(), x, y );
687 x += item->GetX() + 5;
688 }
689 if (item->HasText())
690 {
0530737d 691 dc->DrawText( item->GetText(), x, item->GetY() );
63852e78
RR
692 }
693 dc->DestroyClippingRegion();
694 node = node->Next();
695 }
e1e955e1 696 }
63852e78 697 else
c801d85f 698 {
63852e78
RR
699 wxNode *node = m_items.First();
700 if (node)
701 {
702 wxListItemData *item = (wxListItemData*)node->Data();
703 if (item->HasImage())
704 {
705 m_owner->DrawImage( item->GetImage(), dc, m_bound_icon.x, m_bound_icon.y );
706 }
707 if (item->HasText())
708 {
0530737d 709 dc->DrawText( item->GetText(), m_bound_label.x, m_bound_label.y );
63852e78
RR
710 }
711 }
e1e955e1 712 }
e1e955e1 713}
c801d85f 714
debe6624 715void wxListLineData::Hilight( bool on )
c801d85f 716{
63852e78 717 if (on == m_hilighted) return;
6e228e42 718 m_hilighted = on;
63852e78
RR
719 if (on)
720 m_owner->SelectLine( this );
721 else
722 m_owner->DeselectLine( this );
e1e955e1 723}
c801d85f
KB
724
725void wxListLineData::ReverseHilight( void )
726{
63852e78
RR
727 m_hilighted = !m_hilighted;
728 if (m_hilighted)
729 m_owner->SelectLine( this );
730 else
731 m_owner->DeselectLine( this );
e1e955e1 732}
c801d85f 733
1e6d9499 734void wxListLineData::DrawRubberBand( wxDC *dc, bool on )
c801d85f 735{
63852e78
RR
736 if (on)
737 {
738 dc->SetPen( * wxBLACK_PEN );
739 dc->SetBrush( * wxTRANSPARENT_BRUSH );
740 dc->DrawRectangle( m_bound_hilight.x, m_bound_hilight.y,
741 m_bound_hilight.width, m_bound_hilight.height );
742 }
e1e955e1 743}
c801d85f 744
1e6d9499 745void wxListLineData::Draw( wxDC *dc )
c801d85f 746{
63852e78 747 DoDraw( dc, m_hilighted, m_hilighted );
e1e955e1 748}
c801d85f 749
0a240683 750bool wxListLineData::IsInRect( int x, int y, const wxRect &rect )
c801d85f 751{
004fd0c8 752 return ((x >= rect.x) && (x <= rect.x+rect.width) &&
63852e78 753 (y >= rect.y) && (y <= rect.y+rect.height));
e1e955e1 754}
c801d85f
KB
755
756bool wxListLineData::IsHilighted( void )
757{
63852e78 758 return m_hilighted;
e1e955e1 759}
c801d85f 760
0a240683 761void wxListLineData::AssignRect( wxRect &dest, int x, int y, int width, int height )
c801d85f 762{
63852e78
RR
763 dest.x = x;
764 dest.y = y;
765 dest.width = width;
766 dest.height = height;
e1e955e1 767}
c801d85f 768
0a240683 769void wxListLineData::AssignRect( wxRect &dest, const wxRect &source )
c801d85f 770{
63852e78
RR
771 dest.x = source.x;
772 dest.y = source.y;
773 dest.width = source.width;
774 dest.height = source.height;
e1e955e1 775}
c801d85f
KB
776
777//-----------------------------------------------------------------------------
778// wxListHeaderWindow
779//-----------------------------------------------------------------------------
780
781IMPLEMENT_DYNAMIC_CLASS(wxListHeaderWindow,wxWindow);
782
783BEGIN_EVENT_TABLE(wxListHeaderWindow,wxWindow)
63852e78
RR
784 EVT_PAINT (wxListHeaderWindow::OnPaint)
785 EVT_MOUSE_EVENTS (wxListHeaderWindow::OnMouse)
786 EVT_SET_FOCUS (wxListHeaderWindow::OnSetFocus)
c801d85f
KB
787END_EVENT_TABLE()
788
789wxListHeaderWindow::wxListHeaderWindow( void )
790{
63852e78
RR
791 m_owner = (wxListMainWindow *) NULL;
792 m_currentCursor = (wxCursor *) NULL;
793 m_resizeCursor = (wxCursor *) NULL;
cfb50f14 794 m_isDragging = FALSE;
e1e955e1 795}
c801d85f 796
bd8289c1 797wxListHeaderWindow::wxListHeaderWindow( wxWindow *win, wxWindowID id, wxListMainWindow *owner,
debe6624
JS
798 const wxPoint &pos, const wxSize &size,
799 long style, const wxString &name ) :
c801d85f
KB
800 wxWindow( win, id, pos, size, style, name )
801{
63852e78 802 m_owner = owner;
c801d85f 803// m_currentCursor = wxSTANDARD_CURSOR;
63852e78
RR
804 m_currentCursor = (wxCursor *) NULL;
805 m_resizeCursor = new wxCursor( wxCURSOR_SIZEWE );
cfb50f14
RR
806 m_isDragging = FALSE;
807 SetBackgroundColour( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE ) );
e1e955e1 808}
c801d85f 809
a367b9b3
JS
810wxListHeaderWindow::~wxListHeaderWindow( void )
811{
63852e78 812 delete m_resizeCursor;
a367b9b3
JS
813}
814
1e6d9499 815void wxListHeaderWindow::DoDrawRect( wxDC *dc, int x, int y, int w, int h )
c801d85f 816{
63852e78 817 const int m_corner = 1;
c801d85f 818
63852e78 819 dc->SetBrush( *wxTRANSPARENT_BRUSH );
c801d85f 820
63852e78
RR
821 dc->SetPen( *wxBLACK_PEN );
822 dc->DrawLine( x+w-m_corner+1, y, x+w, y+h ); // right (outer)
17867d61 823 dc->DrawRectangle( x, y+h, w+1, 1 ); // bottom (outer)
bd8289c1 824
63852e78 825 wxPen pen( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNSHADOW ), 1, wxSOLID );
004fd0c8 826
63852e78
RR
827 dc->SetPen( pen );
828 dc->DrawLine( x+w-m_corner, y, x+w-1, y+h ); // right (inner)
829 dc->DrawRectangle( x+1, y+h-1, w-2, 1 ); // bottom (inner)
bd8289c1 830
63852e78
RR
831 dc->SetPen( *wxWHITE_PEN );
832 dc->DrawRectangle( x, y, w-m_corner+1, 1 ); // top (outer)
833 dc->DrawRectangle( x, y, 1, h ); // left (outer)
834 dc->DrawLine( x, y+h-1, x+1, y+h-1 );
835 dc->DrawLine( x+w-1, y, x+w-1, y+1 );
e1e955e1 836}
c801d85f
KB
837
838void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
839{
63852e78
RR
840 wxPaintDC dc( this );
841 PrepareDC( dc );
7c74e7fe 842#if wxUSE_GENERIC_LIST_EXTENSIONS
bffa1c77
VZ
843 if ( m_owner->GetMode() & wxLC_REPORT )
844 {
845 int x , y ;
846 int xpix , ypix ;
847
848 m_owner->GetScrollPixelsPerUnit( &xpix , &ypix ) ;
849 m_owner->ViewStart( &x, &y ) ;
850 dc.SetDeviceOrigin( -x * xpix, 0 );
851 }
7c74e7fe 852#endif
63852e78 853 dc.BeginDrawing();
bd8289c1 854
63852e78 855 dc.SetFont( GetFont() );
bd8289c1 856
63852e78
RR
857 int w = 0;
858 int h = 0;
859 int x = 0;
860 int y = 0;
861 GetClientSize( &w, &h );
c801d85f 862
f60d0f94 863 dc.SetBackgroundMode(wxTRANSPARENT);
63852e78 864 dc.SetTextForeground( *wxBLACK );
70846f0a
VZ
865
866 // do *not* use the listctrl colour for headers - one day we will have a
867 // function to set it separately
c801d85f 868
63852e78
RR
869 x = 1;
870 y = 1;
871 int numColumns = m_owner->GetColumnCount();
872 wxListItem item;
873 for (int i = 0; i < numColumns; i++)
874 {
875 m_owner->GetColumn( i, item );
876 int cw = item.m_width-2;
7c74e7fe 877#if wxUSE_GENERIC_LIST_EXTENSIONS
bffa1c77 878 if ((i+1 == numColumns) || ( dc.LogicalToDeviceX(x+item.m_width) > w-5))
470caaf9 879 cw = dc.DeviceToLogicalX(w)-x-1;
7c74e7fe 880#else
470caaf9
VZ
881 if ((i+1 == numColumns) || (x+item.m_width > w-5))
882 cw = w-x-1;
7c74e7fe 883#endif
63852e78 884 dc.SetPen( *wxWHITE_PEN );
c801d85f 885
63852e78
RR
886 DoDrawRect( &dc, x, y, cw, h-2 );
887 dc.SetClippingRegion( x, y, cw-5, h-4 );
888 dc.DrawText( item.m_text, x+4, y+3 );
889 dc.DestroyClippingRegion();
890 x += item.m_width;
7c74e7fe
SC
891#if wxUSE_GENERIC_LIST_EXTENSIONS
892 if (dc.LogicalToDeviceX(x) > w+5) break;
893#else
63852e78 894 if (x > w+5) break;
7c74e7fe 895#endif
63852e78
RR
896 }
897 dc.EndDrawing();
e1e955e1 898}
c801d85f 899
0208334d
RR
900void wxListHeaderWindow::DrawCurrent()
901{
63852e78
RR
902 int x1 = m_currentX;
903 int y1 = 0;
904 int x2 = m_currentX-1;
905 int y2 = 0;
906 int dummy;
907 m_owner->GetClientSize( &dummy, &y2 );
908 ClientToScreen( &x1, &y1 );
909 m_owner->ClientToScreen( &x2, &y2 );
0208334d 910
63852e78 911 wxScreenDC dc;
3c679789 912 dc.SetLogicalFunction( wxINVERT );
63852e78
RR
913 dc.SetPen( wxPen( *wxBLACK, 2, wxSOLID ) );
914 dc.SetBrush( *wxTRANSPARENT_BRUSH );
0208334d 915
63852e78 916 dc.DrawLine( x1, y1, x2, y2 );
0208334d 917
63852e78 918 dc.SetLogicalFunction( wxCOPY );
0208334d 919
63852e78
RR
920 dc.SetPen( wxNullPen );
921 dc.SetBrush( wxNullBrush );
0208334d
RR
922}
923
c801d85f
KB
924void wxListHeaderWindow::OnMouse( wxMouseEvent &event )
925{
6f2a55e3
VZ
926 wxCoord x = (wxCoord)event.GetX();
927 wxCoord y = (wxCoord)event.GetY();
cfb50f14 928 if (m_isDragging)
0208334d 929 {
63852e78
RR
930 DrawCurrent();
931 if (event.ButtonUp())
932 {
933 ReleaseMouse();
cfb50f14 934 m_isDragging = FALSE;
63852e78
RR
935 m_owner->SetColumnWidth( m_column, m_currentX-m_minX );
936 }
937 else
938 {
939 int size_x = 0;
940 int dummy;
941 GetClientSize( &size_x, & dummy );
942 if (x > m_minX+7)
943 m_currentX = x;
944 else
945 m_currentX = m_minX+7;
946 if (m_currentX > size_x-7) m_currentX = size_x-7;
947 DrawCurrent();
948 }
949 return;
0208334d 950 }
bd8289c1 951
63852e78
RR
952 m_minX = 0;
953 bool hit_border = FALSE;
954 int xpos = 0;
7b848b0d 955 for (int j = 0; j < m_owner->GetColumnCount(); j++)
bd8289c1 956 {
63852e78 957 xpos += m_owner->GetColumnWidth( j );
8636aed8 958 m_column = j;
1d81a219 959 if ((abs(x-xpos) < 3) && (y < 22) && (m_column < m_owner->GetColumnCount()-1))
63852e78
RR
960 {
961 hit_border = TRUE;
63852e78
RR
962 break;
963 }
bffa1c77
VZ
964 if (x-xpos < 0)
965 {
966 break;
967 }
63852e78 968 m_minX = xpos;
0208334d 969 }
bd8289c1 970
8636aed8 971 if (event.LeftDown())
c801d85f 972 {
8636aed8 973 if (hit_border)
bffa1c77 974 {
8636aed8
RR
975 m_isDragging = TRUE;
976 m_currentX = x;
977 DrawCurrent();
978 CaptureMouse();
979 return;
bffa1c77
VZ
980 }
981 else
982 {
8636aed8
RR
983 wxListEvent le( wxEVT_COMMAND_LIST_COL_CLICK, GetParent()->GetId() );
984 le.SetEventObject( GetParent() );
bffa1c77 985 le.m_col = m_column;
8636aed8 986 GetParent()->GetEventHandler()->ProcessEvent( le );
bffa1c77
VZ
987 return;
988 }
c801d85f 989 }
63852e78
RR
990
991 if (event.Moving())
c801d85f 992 {
63852e78
RR
993 if (hit_border)
994 {
995 if (m_currentCursor == wxSTANDARD_CURSOR) SetCursor( * m_resizeCursor );
996 m_currentCursor = m_resizeCursor;
997 }
998 else
999 {
1000 if (m_currentCursor != wxSTANDARD_CURSOR) SetCursor( * wxSTANDARD_CURSOR );
1001 m_currentCursor = wxSTANDARD_CURSOR;
1002 }
e1e955e1 1003 }
e1e955e1 1004}
c801d85f
KB
1005
1006void wxListHeaderWindow::OnSetFocus( wxFocusEvent &WXUNUSED(event) )
1007{
63852e78 1008 m_owner->SetFocus();
e1e955e1 1009}
c801d85f
KB
1010
1011//-----------------------------------------------------------------------------
1012// wxListRenameTimer (internal)
1013//-----------------------------------------------------------------------------
1014
bd8289c1
VZ
1015wxListRenameTimer::wxListRenameTimer( wxListMainWindow *owner )
1016{
63852e78 1017 m_owner = owner;
e1e955e1 1018}
c801d85f 1019
bd8289c1
VZ
1020void wxListRenameTimer::Notify()
1021{
63852e78 1022 m_owner->OnRenameTimer();
e1e955e1 1023}
c801d85f 1024
ee7ee469
RR
1025//-----------------------------------------------------------------------------
1026// wxListTextCtrl (internal)
1027//-----------------------------------------------------------------------------
1028
1029IMPLEMENT_DYNAMIC_CLASS(wxListTextCtrl,wxTextCtrl);
bd8289c1 1030
ee7ee469 1031BEGIN_EVENT_TABLE(wxListTextCtrl,wxTextCtrl)
63852e78
RR
1032 EVT_CHAR (wxListTextCtrl::OnChar)
1033 EVT_KILL_FOCUS (wxListTextCtrl::OnKillFocus)
ee7ee469
RR
1034END_EVENT_TABLE()
1035
674ac8b9
VZ
1036wxListTextCtrl::wxListTextCtrl( wxWindow *parent,
1037 const wxWindowID id,
1038 bool *accept,
1039 wxString *res,
1040 wxListMainWindow *owner,
1041 const wxString &value,
1042 const wxPoint &pos,
1043 const wxSize &size,
1044 int style,
1045 const wxValidator& validator,
1046 const wxString &name )
1047 : wxTextCtrl( parent, id, value, pos, size, style, validator, name )
ee7ee469 1048{
63852e78
RR
1049 m_res = res;
1050 m_accept = accept;
1051 m_owner = owner;
5f1ea0ee
RR
1052 (*m_accept) = FALSE;
1053 (*m_res) = "";
1054 m_startValue = value;
ee7ee469
RR
1055}
1056
1057void wxListTextCtrl::OnChar( wxKeyEvent &event )
1058{
63852e78
RR
1059 if (event.m_keyCode == WXK_RETURN)
1060 {
1061 (*m_accept) = TRUE;
1062 (*m_res) = GetValue();
bce1406b
RR
1063
1064 if (!wxPendingDelete.Member(this))
1065 wxPendingDelete.Append(this);
1066
1067 if ((*m_accept) && ((*m_res) != m_startValue))
1068 m_owner->OnRenameAccept();
1069
63852e78
RR
1070 return;
1071 }
1072 if (event.m_keyCode == WXK_ESCAPE)
1073 {
1074 (*m_accept) = FALSE;
1075 (*m_res) = "";
bce1406b
RR
1076
1077 if (!wxPendingDelete.Member(this))
1078 wxPendingDelete.Append(this);
1079
63852e78
RR
1080 return;
1081 }
bce1406b 1082
63852e78
RR
1083 event.Skip();
1084}
1085
1086void wxListTextCtrl::OnKillFocus( wxFocusEvent &WXUNUSED(event) )
1087{
bce1406b
RR
1088 if (!wxPendingDelete.Member(this))
1089 wxPendingDelete.Append(this);
004fd0c8 1090
5f1ea0ee
RR
1091 if ((*m_accept) && ((*m_res) != m_startValue))
1092 m_owner->OnRenameAccept();
ee7ee469
RR
1093}
1094
c801d85f
KB
1095//-----------------------------------------------------------------------------
1096// wxListMainWindow
1097//-----------------------------------------------------------------------------
1098
1099IMPLEMENT_DYNAMIC_CLASS(wxListMainWindow,wxScrolledWindow);
bd8289c1 1100
c801d85f
KB
1101BEGIN_EVENT_TABLE(wxListMainWindow,wxScrolledWindow)
1102 EVT_PAINT (wxListMainWindow::OnPaint)
1103 EVT_SIZE (wxListMainWindow::OnSize)
1104 EVT_MOUSE_EVENTS (wxListMainWindow::OnMouse)
1105 EVT_CHAR (wxListMainWindow::OnChar)
3dfb93fd 1106 EVT_KEY_DOWN (wxListMainWindow::OnKeyDown)
c801d85f
KB
1107 EVT_SET_FOCUS (wxListMainWindow::OnSetFocus)
1108 EVT_KILL_FOCUS (wxListMainWindow::OnKillFocus)
2fa7c206 1109 EVT_SCROLLWIN (wxListMainWindow::OnScroll)
c801d85f
KB
1110END_EVENT_TABLE()
1111
fd9811b1 1112wxListMainWindow::wxListMainWindow()
c801d85f 1113{
139adb6a
RR
1114 m_mode = 0;
1115 m_lines.DeleteContents( TRUE );
1116 m_columns.DeleteContents( TRUE );
1117 m_current = (wxListLineData *) NULL;
1118 m_visibleLines = 0;
1119 m_hilightBrush = (wxBrush *) NULL;
1120 m_xScroll = 0;
1121 m_yScroll = 0;
1122 m_dirty = TRUE;
1123 m_small_image_list = (wxImageList *) NULL;
1124 m_normal_image_list = (wxImageList *) NULL;
1125 m_small_spacing = 30;
1126 m_normal_spacing = 40;
1127 m_hasFocus = FALSE;
1128 m_usedKeys = TRUE;
1129 m_lastOnSame = FALSE;
1130 m_renameTimer = new wxListRenameTimer( this );
1131 m_isCreated = FALSE;
1132 m_dragCount = 0;
e1e955e1 1133}
c801d85f 1134
bd8289c1 1135wxListMainWindow::wxListMainWindow( wxWindow *parent, wxWindowID id,
c801d85f 1136 const wxPoint &pos, const wxSize &size,
debe6624 1137 long style, const wxString &name ) :
a367b9b3 1138 wxScrolledWindow( parent, id, pos, size, style|wxHSCROLL|wxVSCROLL, name )
c801d85f 1139{
139adb6a
RR
1140 m_mode = style;
1141 m_lines.DeleteContents( TRUE );
1142 m_columns.DeleteContents( TRUE );
1143 m_current = (wxListLineData *) NULL;
1144 m_dirty = TRUE;
1145 m_visibleLines = 0;
1146 m_hilightBrush = new wxBrush( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_HIGHLIGHT), wxSOLID );
1147 m_small_image_list = (wxImageList *) NULL;
1148 m_normal_image_list = (wxImageList *) NULL;
1149 m_small_spacing = 30;
1150 m_normal_spacing = 40;
1151 m_hasFocus = FALSE;
1152 m_dragCount = 0;
1153 m_isCreated = FALSE;
1154 wxSize sz = size;
1155 sz.y = 25;
bd8289c1 1156
139adb6a
RR
1157 if (m_mode & wxLC_REPORT)
1158 {
7c74e7fe
SC
1159#if wxUSE_GENERIC_LIST_EXTENSIONS
1160 m_xScroll = 15;
1161#else
139adb6a 1162 m_xScroll = 0;
7c74e7fe 1163#endif
139adb6a
RR
1164 m_yScroll = 15;
1165 }
1166 else
1167 {
1168 m_xScroll = 15;
1169 m_yScroll = 0;
1170 }
1171 SetScrollbars( m_xScroll, m_yScroll, 0, 0, 0, 0 );
bd8289c1 1172
139adb6a
RR
1173 m_usedKeys = TRUE;
1174 m_lastOnSame = FALSE;
1175 m_renameTimer = new wxListRenameTimer( this );
1176 m_renameAccept = FALSE;
c801d85f 1177
91fc2bdc 1178 SetBackgroundColour( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_LISTBOX ) );
e1e955e1 1179}
c801d85f 1180
fd9811b1 1181wxListMainWindow::~wxListMainWindow()
c801d85f 1182{
12c1b46a
RR
1183 DeleteEverything();
1184
139adb6a 1185 if (m_hilightBrush) delete m_hilightBrush;
004fd0c8 1186
139adb6a 1187 delete m_renameTimer;
e1e955e1 1188}
c801d85f
KB
1189
1190void wxListMainWindow::RefreshLine( wxListLineData *line )
1191{
e6527f9d 1192 if (m_dirty) return;
25e3a937 1193
139adb6a
RR
1194 int x = 0;
1195 int y = 0;
1196 int w = 0;
1197 int h = 0;
1198 if (line)
1199 {
1200 wxClientDC dc(this);
1201 PrepareDC( dc );
1202 line->GetExtent( x, y, w, h );
0a240683 1203 wxRect rect(
139adb6a
RR
1204 dc.LogicalToDeviceX(x-3),
1205 dc.LogicalToDeviceY(y-3),
1206 dc.LogicalToDeviceXRel(w+6),
1207 dc.LogicalToDeviceXRel(h+6) );
1208 Refresh( TRUE, &rect );
1209 }
e1e955e1 1210}
c801d85f
KB
1211
1212void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
1213{
f60d0f94
JS
1214 // Note: a wxPaintDC must be constructed even if no drawing is
1215 // done (a Windows requirement).
1216 wxPaintDC dc( this );
1217 PrepareDC( dc );
1218
139adb6a 1219 if (m_dirty) return;
004fd0c8 1220
139adb6a 1221 if (m_lines.GetCount() == 0) return;
bd8289c1 1222
139adb6a 1223 dc.BeginDrawing();
c801d85f 1224
139adb6a 1225 dc.SetFont( GetFont() );
004fd0c8 1226
139adb6a
RR
1227 if (m_mode & wxLC_REPORT)
1228 {
1229 int lineSpacing = 0;
1230 wxListLineData *line = (wxListLineData*)m_lines.First()->Data();
1231 int dummy = 0;
1232 line->GetSize( dummy, lineSpacing );
1233 lineSpacing += 1;
bffa1c77 1234
139adb6a 1235 int y_s = m_yScroll*GetScrollPos( wxVERTICAL );
bffa1c77 1236
139adb6a 1237 wxNode *node = m_lines.Nth( y_s / lineSpacing );
bffa1c77
VZ
1238 for (int i = 0; i < m_visibleLines+2; i++)
1239 {
1240 if (!node) break;
1241
139adb6a
RR
1242 line = (wxListLineData*)node->Data();
1243 line->Draw( &dc );
1244 node = node->Next();
bffa1c77 1245 }
139adb6a
RR
1246 }
1247 else
1248 {
1249 wxNode *node = m_lines.First();
1250 while (node)
1251 {
1252 wxListLineData *line = (wxListLineData*)node->Data();
1253 line->Draw( &dc );
1254 node = node->Next();
1255 }
1256 }
004fd0c8 1257
139adb6a 1258 if (m_current) m_current->DrawRubberBand( &dc, m_hasFocus );
c801d85f 1259
139adb6a 1260 dc.EndDrawing();
e1e955e1 1261}
c801d85f 1262
debe6624 1263void wxListMainWindow::HilightAll( bool on )
c801d85f 1264{
139adb6a
RR
1265 wxNode *node = m_lines.First();
1266 while (node)
c801d85f 1267 {
139adb6a
RR
1268 wxListLineData *line = (wxListLineData *)node->Data();
1269 if (line->IsHilighted() != on)
1270 {
1271 line->Hilight( on );
1272 RefreshLine( line );
1273 }
1274 node = node->Next();
e1e955e1 1275 }
e1e955e1 1276}
c801d85f 1277
7798a18e 1278void wxListMainWindow::SendNotify( wxListLineData *line, wxEventType command )
c801d85f 1279{
139adb6a
RR
1280 wxListEvent le( command, GetParent()->GetId() );
1281 le.SetEventObject( GetParent() );
1282 le.m_itemIndex = GetIndexOfLine( line );
1283 line->GetItem( 0, le.m_item );
6e228e42
RR
1284 GetParent()->GetEventHandler()->ProcessEvent( le );
1285// GetParent()->GetEventHandler()->AddPendingEvent( le );
e1e955e1 1286}
c801d85f
KB
1287
1288void wxListMainWindow::FocusLine( wxListLineData *WXUNUSED(line) )
1289{
1290// SendNotify( line, wxEVT_COMMAND_LIST_ITEM_FOCUSSED );
e1e955e1 1291}
c801d85f
KB
1292
1293void wxListMainWindow::UnfocusLine( wxListLineData *WXUNUSED(line) )
1294{
1295// SendNotify( line, wxEVT_COMMAND_LIST_ITEM_UNFOCUSSED );
e1e955e1 1296}
c801d85f
KB
1297
1298void wxListMainWindow::SelectLine( wxListLineData *line )
1299{
139adb6a 1300 SendNotify( line, wxEVT_COMMAND_LIST_ITEM_SELECTED );
e1e955e1 1301}
c801d85f
KB
1302
1303void wxListMainWindow::DeselectLine( wxListLineData *line )
1304{
139adb6a 1305 SendNotify( line, wxEVT_COMMAND_LIST_ITEM_DESELECTED );
e1e955e1 1306}
c801d85f
KB
1307
1308void wxListMainWindow::DeleteLine( wxListLineData *line )
1309{
139adb6a 1310 SendNotify( line, wxEVT_COMMAND_LIST_DELETE_ITEM );
e1e955e1 1311}
c801d85f 1312
e179bd65 1313/* *** */
ee7ee469 1314
5f1ea0ee 1315void wxListMainWindow::EditLabel( long item )
c801d85f 1316{
6f2a55e3 1317 wxNode *node = m_lines.Nth( (size_t)item );
223d09f6 1318 wxCHECK_RET( node, wxT("wrong index in wxListCtrl::Edit()") );
004fd0c8 1319
e179bd65
RR
1320 m_currentEdit = (wxListLineData*) node->Data();
1321
fd9811b1 1322 wxListEvent le( wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT, GetParent()->GetId() );
139adb6a 1323 le.SetEventObject( GetParent() );
e179bd65
RR
1324 le.m_itemIndex = GetIndexOfLine( m_currentEdit );
1325 m_currentEdit->GetItem( 0, le.m_item );
139adb6a 1326 GetParent()->GetEventHandler()->ProcessEvent( le );
004fd0c8 1327
86f975a8 1328 if (!le.IsAllowed())
5f1ea0ee 1329 return;
004fd0c8 1330
dc6c62a9
RR
1331 // We have to call this here because the label in
1332 // question might just have been added and no screen
1333 // update taken place.
1334 if (m_dirty) wxYield();
1335
92976ab6 1336 wxString s;
e179bd65 1337 m_currentEdit->GetText( 0, s );
92976ab6
RR
1338 int x = 0;
1339 int y = 0;
1340 int w = 0;
1341 int h = 0;
e179bd65 1342 m_currentEdit->GetLabelExtent( x, y, w, h );
004fd0c8 1343
92976ab6
RR
1344 wxClientDC dc(this);
1345 PrepareDC( dc );
1346 x = dc.LogicalToDeviceX( x );
1347 y = dc.LogicalToDeviceY( y );
bd8289c1 1348
92976ab6
RR
1349 wxListTextCtrl *text = new wxListTextCtrl(
1350 this, -1, &m_renameAccept, &m_renameRes, this, s, wxPoint(x-4,y-4), wxSize(w+11,h+8) );
1351 text->SetFocus();
e1e955e1 1352}
c801d85f 1353
e179bd65
RR
1354void wxListMainWindow::OnRenameTimer()
1355{
223d09f6 1356 wxCHECK_RET( m_current, wxT("invalid m_current") );
004fd0c8 1357
e179bd65
RR
1358 Edit( m_lines.IndexOf( m_current ) );
1359}
1360
c801d85f
KB
1361void wxListMainWindow::OnRenameAccept()
1362{
e179bd65
RR
1363 wxListEvent le( wxEVT_COMMAND_LIST_END_LABEL_EDIT, GetParent()->GetId() );
1364 le.SetEventObject( GetParent() );
1365 le.m_itemIndex = GetIndexOfLine( m_currentEdit );
1366 m_currentEdit->GetItem( 0, le.m_item );
1367 le.m_item.m_text = m_renameRes;
1368 GetParent()->GetEventHandler()->ProcessEvent( le );
004fd0c8 1369
e179bd65 1370 if (!le.IsAllowed()) return;
004fd0c8 1371
5f1ea0ee
RR
1372 wxListItem info;
1373 info.m_mask = wxLIST_MASK_TEXT;
1374 info.m_itemId = le.m_itemIndex;
1375 info.m_text = m_renameRes;
aaa37c0d 1376 info.SetTextColour(le.m_item.GetTextColour());
5f1ea0ee 1377 SetItem( info );
e1e955e1 1378}
c801d85f
KB
1379
1380void wxListMainWindow::OnMouse( wxMouseEvent &event )
1381{
92976ab6 1382 if (GetParent()->GetEventHandler()->ProcessEvent( event)) return;
e3e65dac 1383
92976ab6
RR
1384 if (!m_current) return;
1385 if (m_dirty) return;
0b855868 1386 if ( !(event.Dragging() || event.ButtonDown() || event.LeftUp() || event.ButtonDClick()) ) return;
c801d85f 1387
92976ab6
RR
1388 wxClientDC dc(this);
1389 PrepareDC(dc);
6f2a55e3
VZ
1390 wxCoord x = dc.DeviceToLogicalX( (wxCoord)event.GetX() );
1391 wxCoord y = dc.DeviceToLogicalY( (wxCoord)event.GetY() );
004fd0c8 1392
51cc4dad 1393 /* Did we actually hit an item ? */
92976ab6
RR
1394 long hitResult = 0;
1395 wxNode *node = m_lines.First();
1396 wxListLineData *line = (wxListLineData *) NULL;
1397 while (node)
1398 {
1399 line = (wxListLineData*)node->Data();
1400 hitResult = line->IsHit( x, y );
1401 if (hitResult) break;
1402 line = (wxListLineData *) NULL;
1403 node = node->Next();
1404 }
bd8289c1 1405
fd9811b1 1406 if (event.Dragging())
92976ab6 1407 {
fd9811b1 1408 if (m_dragCount == 0)
bffa1c77
VZ
1409 m_dragStart = wxPoint(x,y);
1410
fd9811b1 1411 m_dragCount++;
bffa1c77
VZ
1412
1413 if (m_dragCount != 3) return;
1414
1415 int command = wxEVT_COMMAND_LIST_BEGIN_DRAG;
1416 if (event.RightIsDown()) command = wxEVT_COMMAND_LIST_BEGIN_RDRAG;
1417
fd9811b1 1418 wxListEvent le( command, GetParent()->GetId() );
92976ab6 1419 le.SetEventObject( GetParent() );
bffa1c77
VZ
1420 le.m_pointDrag = m_dragStart;
1421 GetParent()->GetEventHandler()->ProcessEvent( le );
1422
1423 return;
92976ab6 1424 }
fd9811b1
RR
1425 else
1426 {
1427 m_dragCount = 0;
1428 }
bd8289c1 1429
92976ab6 1430 if (!line) return;
bd8289c1 1431
92976ab6
RR
1432 if (event.ButtonDClick())
1433 {
1434 m_usedKeys = FALSE;
1435 m_lastOnSame = FALSE;
1436 m_renameTimer->Stop();
004fd0c8 1437
435fe83e 1438 SendNotify( line, wxEVT_COMMAND_LIST_ITEM_ACTIVATED );
004fd0c8 1439
92976ab6
RR
1440 return;
1441 }
bd8289c1 1442
92976ab6 1443 if (event.LeftUp() && m_lastOnSame)
c801d85f 1444 {
92976ab6
RR
1445 m_usedKeys = FALSE;
1446 if ((line == m_current) &&
1447 (hitResult == wxLIST_HITTEST_ONITEMLABEL) &&
1448 (m_mode & wxLC_EDIT_LABELS) )
1449 {
1450 m_renameTimer->Start( 100, TRUE );
1451 }
1452 m_lastOnSame = FALSE;
1453 return;
e1e955e1 1454 }
bd8289c1 1455
92976ab6 1456 if (event.RightDown())
b204641e 1457 {
92976ab6
RR
1458 SendNotify( line, wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK );
1459 return;
b204641e 1460 }
004fd0c8 1461
92976ab6 1462 if (event.MiddleDown())
b204641e 1463 {
92976ab6
RR
1464 SendNotify( line, wxEVT_COMMAND_LIST_ITEM_MIDDLE_CLICK );
1465 return;
1466 }
004fd0c8 1467
92976ab6
RR
1468 if (event.LeftDown())
1469 {
1470 m_usedKeys = FALSE;
1471 wxListLineData *oldCurrent = m_current;
1472 if (m_mode & wxLC_SINGLE_SEL)
b204641e 1473 {
92976ab6
RR
1474 m_current = line;
1475 HilightAll( FALSE );
1476 m_current->ReverseHilight();
1477 RefreshLine( m_current );
e1e955e1 1478 }
92976ab6 1479 else
b204641e 1480 {
473d087e 1481 if (event.ControlDown())
92976ab6
RR
1482 {
1483 m_current = line;
1484 m_current->ReverseHilight();
1485 RefreshLine( m_current );
1486 }
473d087e 1487 else if (event.ShiftDown())
92976ab6
RR
1488 {
1489 m_current = line;
bffa1c77 1490
92976ab6
RR
1491 int numOfCurrent = -1;
1492 node = m_lines.First();
1493 while (node)
1494 {
1495 wxListLineData *test_line = (wxListLineData*)node->Data();
1496 numOfCurrent++;
1497 if (test_line == oldCurrent) break;
1498 node = node->Next();
1499 }
bffa1c77 1500
92976ab6
RR
1501 int numOfLine = -1;
1502 node = m_lines.First();
1503 while (node)
1504 {
1505 wxListLineData *test_line = (wxListLineData*)node->Data();
1506 numOfLine++;
1507 if (test_line == line) break;
1508 node = node->Next();
1509 }
1510
1511 if (numOfLine < numOfCurrent)
004fd0c8 1512 {
bffa1c77
VZ
1513 int i = numOfLine;
1514 numOfLine = numOfCurrent;
1515 numOfCurrent = i;
1516 }
1517
92976ab6
RR
1518 wxNode *node = m_lines.Nth( numOfCurrent );
1519 for (int i = 0; i <= numOfLine-numOfCurrent; i++)
1520 {
1521 wxListLineData *test_line= (wxListLineData*)node->Data();
1522 test_line->Hilight(TRUE);
1523 RefreshLine( test_line );
1524 node = node->Next();
1525 }
1526 }
1527 else
1528 {
1529 m_current = line;
1530 HilightAll( FALSE );
1531 m_current->ReverseHilight();
1532 RefreshLine( m_current );
1533 }
e1e955e1 1534 }
92976ab6
RR
1535 if (m_current != oldCurrent)
1536 {
1537 RefreshLine( oldCurrent );
1538 UnfocusLine( oldCurrent );
1539 FocusLine( m_current );
1540 }
1541 m_lastOnSame = (m_current == oldCurrent);
1542 return;
e1e955e1 1543 }
e1e955e1 1544}
c801d85f 1545
e179bd65 1546void wxListMainWindow::MoveToFocus()
c801d85f 1547{
92976ab6 1548 if (!m_current) return;
004fd0c8 1549
cf3da716
RR
1550 int item_x = 0;
1551 int item_y = 0;
1552 int item_w = 0;
1553 int item_h = 0;
1554 m_current->GetExtent( item_x, item_y, item_w, item_h );
1555
1556 int client_w = 0;
1557 int client_h = 0;
1558 GetClientSize( &client_w, &client_h );
1559
1560 int view_x = m_xScroll*GetScrollPos( wxHORIZONTAL );
1561 int view_y = m_yScroll*GetScrollPos( wxVERTICAL );
004fd0c8 1562
92976ab6
RR
1563 if (m_mode & wxLC_REPORT)
1564 {
cf3da716
RR
1565 if (item_y-5 < view_y )
1566 Scroll( -1, (item_y-5)/m_yScroll );
1567 if (item_y+item_h+5 > view_y+client_h)
1568 Scroll( -1, (item_y+item_h-client_h+15)/m_yScroll );
92976ab6
RR
1569 }
1570 else
1571 {
cf3da716
RR
1572 if (item_x-view_x < 5)
1573 Scroll( (item_x-5)/m_xScroll, -1 );
1574 if (item_x+item_w-5 > view_x+client_w)
1575 Scroll( (item_x+item_w-client_w+15)/m_xScroll, -1 );
92976ab6 1576 }
e1e955e1 1577}
c801d85f
KB
1578
1579void wxListMainWindow::OnArrowChar( wxListLineData *newCurrent, bool shiftDown )
1580{
92976ab6
RR
1581 if ((m_mode & wxLC_SINGLE_SEL) || (m_usedKeys == FALSE)) m_current->Hilight( FALSE );
1582 wxListLineData *oldCurrent = m_current;
1583 m_current = newCurrent;
92976ab6
RR
1584 if (shiftDown || (m_mode & wxLC_SINGLE_SEL)) m_current->Hilight( TRUE );
1585 RefreshLine( m_current );
1586 RefreshLine( oldCurrent );
1587 FocusLine( m_current );
1588 UnfocusLine( oldCurrent );
cf3da716 1589 MoveToFocus();
e1e955e1 1590}
c801d85f 1591
3dfb93fd
RR
1592void wxListMainWindow::OnKeyDown( wxKeyEvent &event )
1593{
1594 wxWindow *parent = GetParent();
004fd0c8 1595
3dfb93fd
RR
1596 /* we propagate the key event up */
1597 wxKeyEvent ke( wxEVT_KEY_DOWN );
1598 ke.m_shiftDown = event.m_shiftDown;
1599 ke.m_controlDown = event.m_controlDown;
1600 ke.m_altDown = event.m_altDown;
1601 ke.m_metaDown = event.m_metaDown;
1602 ke.m_keyCode = event.m_keyCode;
1603 ke.m_x = event.m_x;
1604 ke.m_y = event.m_y;
1605 ke.SetEventObject( parent );
1606 if (parent->GetEventHandler()->ProcessEvent( ke )) return;
004fd0c8 1607
3dfb93fd
RR
1608 event.Skip();
1609}
004fd0c8 1610
c801d85f
KB
1611void wxListMainWindow::OnChar( wxKeyEvent &event )
1612{
51cc4dad 1613 wxWindow *parent = GetParent();
004fd0c8 1614
51cc4dad
RR
1615 /* we send a list_key event up */
1616 wxListEvent le( wxEVT_COMMAND_LIST_KEY_DOWN, GetParent()->GetId() );
6f2a55e3 1617 le.m_code = (int)event.KeyCode();
51cc4dad
RR
1618 le.SetEventObject( parent );
1619 parent->GetEventHandler()->ProcessEvent( le );
1620
3dfb93fd
RR
1621 /* we propagate the char event up */
1622 wxKeyEvent ke( wxEVT_CHAR );
51cc4dad
RR
1623 ke.m_shiftDown = event.m_shiftDown;
1624 ke.m_controlDown = event.m_controlDown;
1625 ke.m_altDown = event.m_altDown;
1626 ke.m_metaDown = event.m_metaDown;
1627 ke.m_keyCode = event.m_keyCode;
1628 ke.m_x = event.m_x;
1629 ke.m_y = event.m_y;
1630 ke.SetEventObject( parent );
1631 if (parent->GetEventHandler()->ProcessEvent( ke )) return;
004fd0c8 1632
012a03e0
RR
1633 if (event.KeyCode() == WXK_TAB)
1634 {
1635 wxNavigationKeyEvent nevent;
1636 nevent.SetDirection( !event.ShiftDown() );
8253c7fd 1637 nevent.SetEventObject( GetParent()->GetParent() );
012a03e0 1638 nevent.SetCurrentFocus( m_parent );
8253c7fd 1639 if (GetParent()->GetParent()->GetEventHandler()->ProcessEvent( nevent )) return;
012a03e0 1640 }
004fd0c8 1641
51cc4dad
RR
1642 /* no item -> nothing to do */
1643 if (!m_current)
c801d85f 1644 {
51cc4dad
RR
1645 event.Skip();
1646 return;
e1e955e1 1647 }
51cc4dad
RR
1648
1649 switch (event.KeyCode())
c801d85f 1650 {
51cc4dad
RR
1651 case WXK_UP:
1652 {
1653 wxNode *node = m_lines.Member( m_current )->Previous();
1654 if (node) OnArrowChar( (wxListLineData*)node->Data(), event.ShiftDown() );
1655 break;
1656 }
1657 case WXK_DOWN:
1658 {
1659 wxNode *node = m_lines.Member( m_current )->Next();
1660 if (node) OnArrowChar( (wxListLineData*)node->Data(), event.ShiftDown() );
1661 break;
1662 }
1663 case WXK_END:
1664 {
1665 wxNode *node = m_lines.Last();
1666 OnArrowChar( (wxListLineData*)node->Data(), event.ShiftDown() );
1667 break;
1668 }
1669 case WXK_HOME:
1670 {
1671 wxNode *node = m_lines.First();
1672 OnArrowChar( (wxListLineData*)node->Data(), event.ShiftDown() );
1673 break;
1674 }
1675 case WXK_PRIOR:
1676 {
1677 int steps = 0;
004fd0c8 1678 if (m_mode & wxLC_REPORT)
bffa1c77
VZ
1679 {
1680 steps = m_visibleLines-1;
1681 }
51cc4dad
RR
1682 else
1683 {
1684 int pos = 0;
1685 wxNode *node = m_lines.First();
1686 for (;;) { if (m_current == (wxListLineData*)node->Data()) break; pos++; node = node->Next(); }
1687 steps = pos % m_visibleLines;
1688 }
1689 wxNode *node = m_lines.Member( m_current );
1690 for (int i = 0; i < steps; i++) if (node->Previous()) node = node->Previous();
1691 if (node) OnArrowChar( (wxListLineData*)node->Data(), event.ShiftDown() );
1692 break;
1693 }
1694 case WXK_NEXT:
1695 {
1696 int steps = 0;
004fd0c8 1697 if (m_mode & wxLC_REPORT)
bffa1c77
VZ
1698 {
1699 steps = m_visibleLines-1;
1700 }
51cc4dad
RR
1701 else
1702 {
1703 int pos = 0; wxNode *node = m_lines.First();
1704 for (;;) { if (m_current == (wxListLineData*)node->Data()) break; pos++; node = node->Next(); }
1705 steps = m_visibleLines-(pos % m_visibleLines)-1;
1706 }
1707 wxNode *node = m_lines.Member( m_current );
1708 for (int i = 0; i < steps; i++) if (node->Next()) node = node->Next();
1709 if (node) OnArrowChar( (wxListLineData*)node->Data(), event.ShiftDown() );
1710 break;
1711 }
1712 case WXK_LEFT:
1713 {
1714 if (!(m_mode & wxLC_REPORT))
1715 {
1716 wxNode *node = m_lines.Member( m_current );
1717 for (int i = 0; i <m_visibleLines; i++) if (node->Previous()) node = node->Previous();
1718 if (node) OnArrowChar( (wxListLineData*)node->Data(), event.ShiftDown() );
1719 }
1720 break;
1721 }
1722 case WXK_RIGHT:
1723 {
1724 if (!(m_mode & wxLC_REPORT))
1725 {
1726 wxNode *node = m_lines.Member( m_current );
1727 for (int i = 0; i <m_visibleLines; i++) if (node->Next()) node = node->Next();
1728 if (node) OnArrowChar( (wxListLineData*)node->Data(), event.ShiftDown() );
1729 }
1730 break;
1731 }
1732 case WXK_SPACE:
1733 {
1734 m_current->ReverseHilight();
1735 RefreshLine( m_current );
1736 break;
1737 }
1738 case WXK_INSERT:
1739 {
1740 if (!(m_mode & wxLC_SINGLE_SEL))
1741 {
1742 wxListLineData *oldCurrent = m_current;
1743 m_current->ReverseHilight();
1744 wxNode *node = m_lines.Member( m_current )->Next();
1745 if (node) m_current = (wxListLineData*)node->Data();
51cc4dad
RR
1746 RefreshLine( oldCurrent );
1747 RefreshLine( m_current );
1748 UnfocusLine( oldCurrent );
1749 FocusLine( m_current );
cf3da716 1750 MoveToFocus();
51cc4dad
RR
1751 }
1752 break;
1753 }
1754 case WXK_RETURN:
1755 case WXK_EXECUTE:
1756 {
1757 wxListEvent le( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, GetParent()->GetId() );
1758 le.SetEventObject( GetParent() );
1759 le.m_itemIndex = GetIndexOfLine( m_current );
1760 m_current->GetItem( 0, le.m_item );
1761 GetParent()->GetEventHandler()->ProcessEvent( le );
1762 break;
1763 }
1764 default:
1765 {
1766 event.Skip();
1767 return;
1768 }
e1e955e1 1769 }
51cc4dad 1770 m_usedKeys = TRUE;
e1e955e1 1771}
c801d85f 1772
cae5359f
RR
1773#ifdef __WXGTK__
1774extern wxWindow *g_focusWindow;
1775#endif
1776
c801d85f
KB
1777void wxListMainWindow::OnSetFocus( wxFocusEvent &WXUNUSED(event) )
1778{
63852e78
RR
1779 m_hasFocus = TRUE;
1780 RefreshLine( m_current );
bd8289c1 1781
63852e78 1782 if (!GetParent()) return;
004fd0c8 1783
cae5359f
RR
1784#ifdef __WXGTK__
1785 g_focusWindow = GetParent();
1786#endif
bd8289c1 1787
63852e78
RR
1788 wxFocusEvent event( wxEVT_SET_FOCUS, GetParent()->GetId() );
1789 event.SetEventObject( GetParent() );
1790 GetParent()->GetEventHandler()->ProcessEvent( event );
e1e955e1 1791}
c801d85f
KB
1792
1793void wxListMainWindow::OnKillFocus( wxFocusEvent &WXUNUSED(event) )
1794{
63852e78
RR
1795 m_hasFocus = FALSE;
1796 RefreshLine( m_current );
e1e955e1 1797}
c801d85f
KB
1798
1799void wxListMainWindow::OnSize( wxSizeEvent &WXUNUSED(event) )
1800{
1801/*
1802 We don't even allow the wxScrolledWindow::AdjustScrollbars() call
004fd0c8 1803
c801d85f 1804*/
e1e955e1 1805}
c801d85f 1806
1e6d9499 1807void wxListMainWindow::DrawImage( int index, wxDC *dc, int x, int y )
c801d85f 1808{
63852e78
RR
1809 if ((m_mode & wxLC_ICON) && (m_normal_image_list))
1810 {
1811 m_normal_image_list->Draw( index, *dc, x, y, wxIMAGELIST_DRAW_TRANSPARENT );
1812 return;
1813 }
1814 if ((m_mode & wxLC_SMALL_ICON) && (m_small_image_list))
1815 {
1816 m_small_image_list->Draw( index, *dc, x, y, wxIMAGELIST_DRAW_TRANSPARENT );
1817 }
0b855868
RR
1818 if ((m_mode & wxLC_LIST) && (m_small_image_list))
1819 {
1820 m_small_image_list->Draw( index, *dc, x, y, wxIMAGELIST_DRAW_TRANSPARENT );
1821 }
63852e78
RR
1822 if ((m_mode & wxLC_REPORT) && (m_small_image_list))
1823 {
1824 m_small_image_list->Draw( index, *dc, x, y, wxIMAGELIST_DRAW_TRANSPARENT );
1825 return;
1826 }
e1e955e1 1827}
c801d85f
KB
1828
1829void wxListMainWindow::GetImageSize( int index, int &width, int &height )
1830{
63852e78
RR
1831 if ((m_mode & wxLC_ICON) && (m_normal_image_list))
1832 {
1833 m_normal_image_list->GetSize( index, width, height );
1834 return;
1835 }
1836 if ((m_mode & wxLC_SMALL_ICON) && (m_small_image_list))
1837 {
1838 m_small_image_list->GetSize( index, width, height );
1839 return;
1840 }
0b855868
RR
1841 if ((m_mode & wxLC_LIST) && (m_small_image_list))
1842 {
1843 m_small_image_list->GetSize( index, width, height );
1844 return;
1845 }
63852e78
RR
1846 if ((m_mode & wxLC_REPORT) && (m_small_image_list))
1847 {
1848 m_small_image_list->GetSize( index, width, height );
1849 return;
1850 }
1851 width = 0;
1852 height = 0;
e1e955e1 1853}
c801d85f
KB
1854
1855int wxListMainWindow::GetTextLength( wxString &s )
1856{
1e6d9499 1857 wxClientDC dc( this );
13111b2a
VZ
1858 wxCoord lw = 0;
1859 wxCoord lh = 0;
139adb6a
RR
1860 dc.GetTextExtent( s, &lw, &lh );
1861 return lw + 6;
e1e955e1 1862}
c801d85f
KB
1863
1864int wxListMainWindow::GetIndexOfLine( const wxListLineData *line )
1865{
139adb6a
RR
1866 int i = 0;
1867 wxNode *node = m_lines.First();
1868 while (node)
1869 {
1870 if (line == (wxListLineData*)node->Data()) return i;
1871 i++;
1872 node = node->Next();
1873 }
1874 return -1;
e1e955e1 1875}
c801d85f 1876
debe6624 1877void wxListMainWindow::SetImageList( wxImageList *imageList, int which )
c801d85f 1878{
139adb6a
RR
1879 m_dirty = TRUE;
1880 if (which == wxIMAGE_LIST_NORMAL) m_normal_image_list = imageList;
1881 if (which == wxIMAGE_LIST_SMALL) m_small_image_list = imageList;
e1e955e1 1882}
c801d85f 1883
debe6624 1884void wxListMainWindow::SetItemSpacing( int spacing, bool isSmall )
c801d85f 1885{
139adb6a
RR
1886 m_dirty = TRUE;
1887 if (isSmall)
1888 {
1889 m_small_spacing = spacing;
1890 }
1891 else
1892 {
1893 m_normal_spacing = spacing;
1894 }
e1e955e1 1895}
c801d85f 1896
debe6624 1897int wxListMainWindow::GetItemSpacing( bool isSmall )
c801d85f 1898{
139adb6a 1899 if (isSmall) return m_small_spacing; else return m_normal_spacing;
e1e955e1 1900}
c801d85f 1901
debe6624 1902void wxListMainWindow::SetColumn( int col, wxListItem &item )
c801d85f 1903{
63852e78
RR
1904 m_dirty = TRUE;
1905 wxNode *node = m_columns.Nth( col );
1906 if (node)
1907 {
1908 if (item.m_width == wxLIST_AUTOSIZE_USEHEADER) item.m_width = GetTextLength( item.m_text )+7;
1909 wxListHeaderData *column = (wxListHeaderData*)node->Data();
1910 column->SetItem( item );
1911 }
1912 wxListCtrl *lc = (wxListCtrl*) GetParent();
1913 if (lc->m_headerWin) lc->m_headerWin->Refresh();
e1e955e1 1914}
c801d85f 1915
debe6624 1916void wxListMainWindow::SetColumnWidth( int col, int width )
c801d85f 1917{
63852e78 1918 if (!(m_mode & wxLC_REPORT)) return;
0208334d 1919
63852e78 1920 m_dirty = TRUE;
bd8289c1 1921
0180dad6
RR
1922 wxNode *node = (wxNode*) NULL;
1923
1924 if (width == wxLIST_AUTOSIZE_USEHEADER) width = 80;
1925 if (width == wxLIST_AUTOSIZE)
1926 {
1927 wxClientDC dc(this);
1928 dc.SetFont( GetFont() );
1929 int max = 10;
1930 node = m_lines.First();
1931 while (node)
1932 {
1933 wxListLineData *line = (wxListLineData*)node->Data();
1934 wxNode *n = line->m_items.Nth( col );
1935 if (n)
1936 {
1937 wxListItemData *item = (wxListItemData*)n->Data();
bffa1c77 1938 int current = 0, ix = 0, iy = 0;
13111b2a 1939 wxCoord lx = 0, ly = 0;
bffa1c77
VZ
1940 if (item->HasImage())
1941 {
0180dad6 1942 GetImageSize( item->GetImage(), ix, iy );
bffa1c77
VZ
1943 current = ix + 5;
1944 }
1945 if (item->HasText())
1946 {
1947 wxString str;
1948 item->GetText( str );
1949 dc.GetTextExtent( str, &lx, &ly );
1950 current += lx;
1951 }
1952 if (current > max) max = current;
0180dad6
RR
1953 }
1954 node = node->Next();
1955 }
bffa1c77 1956 width = max+10;
0180dad6
RR
1957 }
1958
1959 node = m_columns.Nth( col );
63852e78
RR
1960 if (node)
1961 {
1962 wxListHeaderData *column = (wxListHeaderData*)node->Data();
1963 column->SetWidth( width );
1964 }
bd8289c1 1965
63852e78
RR
1966 node = m_lines.First();
1967 while (node)
0208334d 1968 {
63852e78
RR
1969 wxListLineData *line = (wxListLineData*)node->Data();
1970 wxNode *n = line->m_items.Nth( col );
1971 if (n)
1972 {
1973 wxListItemData *item = (wxListItemData*)n->Data();
1974 item->SetSize( width, -1 );
1975 }
1976 node = node->Next();
0208334d 1977 }
bd8289c1 1978
63852e78
RR
1979 wxListCtrl *lc = (wxListCtrl*) GetParent();
1980 if (lc->m_headerWin) lc->m_headerWin->Refresh();
e1e955e1 1981}
c801d85f 1982
debe6624 1983void wxListMainWindow::GetColumn( int col, wxListItem &item )
c801d85f 1984{
63852e78
RR
1985 wxNode *node = m_columns.Nth( col );
1986 if (node)
1987 {
1988 wxListHeaderData *column = (wxListHeaderData*)node->Data();
1989 column->GetItem( item );
1990 }
1991 else
1992 {
1993 item.m_format = 0;
1994 item.m_width = 0;
1995 item.m_text = "";
1996 item.m_image = 0;
1997 item.m_data = 0;
1998 }
e1e955e1 1999}
c801d85f 2000
bd8289c1 2001int wxListMainWindow::GetColumnWidth( int col )
c801d85f 2002{
92976ab6
RR
2003 wxNode *node = m_columns.Nth( col );
2004 if (node)
2005 {
2006 wxListHeaderData *column = (wxListHeaderData*)node->Data();
2007 return column->GetWidth();
2008 }
2009 else
2010 {
004fd0c8 2011 return 0;
92976ab6 2012 }
e1e955e1 2013}
c801d85f 2014
e179bd65 2015int wxListMainWindow::GetColumnCount()
c801d85f 2016{
92976ab6 2017 return m_columns.Number();
e1e955e1 2018}
c801d85f 2019
e179bd65 2020int wxListMainWindow::GetCountPerPage()
c801d85f 2021{
92976ab6 2022 return m_visibleLines;
e1e955e1 2023}
c801d85f
KB
2024
2025void wxListMainWindow::SetItem( wxListItem &item )
2026{
92976ab6 2027 m_dirty = TRUE;
6f2a55e3 2028 wxNode *node = m_lines.Nth( (size_t)item.m_itemId );
92976ab6
RR
2029 if (node)
2030 {
2031 wxListLineData *line = (wxListLineData*)node->Data();
2032 if (m_mode & wxLC_REPORT) item.m_width = GetColumnWidth( item.m_col )-3;
2033 line->SetItem( item.m_col, item );
2034 }
e1e955e1 2035}
c801d85f 2036
debe6624 2037void wxListMainWindow::SetItemState( long item, long state, long stateMask )
c801d85f 2038{
92976ab6 2039 // m_dirty = TRUE; no recalcs needed
bd8289c1 2040
92976ab6 2041 wxListLineData *oldCurrent = m_current;
bd8289c1 2042
92976ab6 2043 if (stateMask & wxLIST_STATE_FOCUSED)
c801d85f 2044 {
6f2a55e3 2045 wxNode *node = m_lines.Nth( (size_t)item );
92976ab6
RR
2046 if (node)
2047 {
2048 wxListLineData *line = (wxListLineData*)node->Data();
2049 UnfocusLine( m_current );
2050 m_current = line;
2051 FocusLine( m_current );
2052 RefreshLine( m_current );
00a39542 2053 if (oldCurrent) RefreshLine( oldCurrent );
92976ab6 2054 }
e1e955e1 2055 }
bd8289c1 2056
92976ab6 2057 if (stateMask & wxLIST_STATE_SELECTED)
c801d85f 2058 {
6f2a55e3 2059 bool on = (state & wxLIST_STATE_SELECTED) != 0;
92976ab6
RR
2060 if (!on && (m_mode & wxLC_SINGLE_SEL)) return;
2061
6f2a55e3 2062 wxNode *node = m_lines.Nth( (size_t)item );
92976ab6
RR
2063 if (node)
2064 {
2065 wxListLineData *line = (wxListLineData*)node->Data();
2066 if (m_mode & wxLC_SINGLE_SEL)
2067 {
2068 UnfocusLine( m_current );
2069 m_current = line;
2070 FocusLine( m_current );
00a39542 2071 if (oldCurrent) oldCurrent->Hilight( FALSE );
92976ab6 2072 RefreshLine( m_current );
00a39542 2073 if (oldCurrent) RefreshLine( oldCurrent );
92976ab6 2074 }
6f2a55e3 2075 bool on = (state & wxLIST_STATE_SELECTED) != 0;
bffa1c77
VZ
2076 if (on != line->IsHilighted())
2077 {
139adb6a
RR
2078 line->Hilight( on );
2079 RefreshLine( line );
bffa1c77 2080 }
92976ab6 2081 }
e1e955e1 2082 }
e1e955e1 2083}
c801d85f 2084
debe6624 2085int wxListMainWindow::GetItemState( long item, long stateMask )
c801d85f 2086{
92976ab6
RR
2087 int ret = wxLIST_STATE_DONTCARE;
2088 if (stateMask & wxLIST_STATE_FOCUSED)
c801d85f 2089 {
6f2a55e3 2090 wxNode *node = m_lines.Nth( (size_t)item );
92976ab6
RR
2091 if (node)
2092 {
2093 wxListLineData *line = (wxListLineData*)node->Data();
2094 if (line == m_current) ret |= wxLIST_STATE_FOCUSED;
2095 }
e1e955e1 2096 }
92976ab6 2097 if (stateMask & wxLIST_STATE_SELECTED)
c801d85f 2098 {
6f2a55e3 2099 wxNode *node = m_lines.Nth( (size_t)item );
92976ab6
RR
2100 if (node)
2101 {
2102 wxListLineData *line = (wxListLineData*)node->Data();
2103 if (line->IsHilighted()) ret |= wxLIST_STATE_FOCUSED;
2104 }
e1e955e1 2105 }
92976ab6 2106 return ret;
e1e955e1 2107}
c801d85f
KB
2108
2109void wxListMainWindow::GetItem( wxListItem &item )
2110{
6f2a55e3 2111 wxNode *node = m_lines.Nth( (size_t)item.m_itemId );
92976ab6
RR
2112 if (node)
2113 {
2114 wxListLineData *line = (wxListLineData*)node->Data();
2115 line->GetItem( item.m_col, item );
2116 }
2117 else
2118 {
2119 item.m_mask = 0;
2120 item.m_text = "";
2121 item.m_image = 0;
2122 item.m_data = 0;
2123 }
e1e955e1 2124}
c801d85f 2125
e179bd65 2126int wxListMainWindow::GetItemCount()
c801d85f 2127{
92976ab6 2128 return m_lines.Number();
e1e955e1 2129}
c801d85f 2130
0a240683 2131void wxListMainWindow::GetItemRect( long index, wxRect &rect )
c801d85f 2132{
6f2a55e3 2133 wxNode *node = m_lines.Nth( (size_t)index );
92976ab6
RR
2134 if (node)
2135 {
2136 wxListLineData *line = (wxListLineData*)node->Data();
2137 line->GetRect( rect );
2138 }
2139 else
2140 {
2141 rect.x = 0;
2142 rect.y = 0;
2143 rect.width = 0;
2144 rect.height = 0;
2145 }
e1e955e1 2146}
c801d85f 2147
e3e65dac
RR
2148bool wxListMainWindow::GetItemPosition(long item, wxPoint& pos)
2149{
6f2a55e3 2150 wxNode *node = m_lines.Nth( (size_t)item );
92976ab6
RR
2151 if (node)
2152 {
0a240683 2153 wxRect rect;
92976ab6
RR
2154 wxListLineData *line = (wxListLineData*)node->Data();
2155 line->GetRect( rect );
2156 pos.x = rect.x;
2157 pos.y = rect.y;
2158 }
2159 else
2160 {
2161 pos.x = 0;
2162 pos.y = 0;
2163 }
2164 return TRUE;
e1e955e1 2165}
e3e65dac 2166
e179bd65 2167int wxListMainWindow::GetSelectedItemCount()
c801d85f 2168{
92976ab6
RR
2169 int ret = 0;
2170 wxNode *node = m_lines.First();
2171 while (node)
2172 {
2173 wxListLineData *line = (wxListLineData*)node->Data();
2174 if (line->IsHilighted()) ret++;
2175 node = node->Next();
2176 }
2177 return ret;
e1e955e1 2178}
c801d85f 2179
debe6624 2180void wxListMainWindow::SetMode( long mode )
c801d85f 2181{
92976ab6
RR
2182 m_dirty = TRUE;
2183 m_mode = mode;
bd8289c1 2184
92976ab6 2185 DeleteEverything();
bd8289c1 2186
92976ab6
RR
2187 if (m_mode & wxLC_REPORT)
2188 {
7c74e7fe
SC
2189#if wxUSE_GENERIC_LIST_EXTENSIONS
2190 m_xScroll = 15;
2191#else
92976ab6 2192 m_xScroll = 0;
7c74e7fe 2193#endif
92976ab6
RR
2194 m_yScroll = 15;
2195 }
2196 else
2197 {
2198 m_xScroll = 15;
2199 m_yScroll = 0;
2200 }
e1e955e1 2201}
c801d85f 2202
e179bd65 2203long wxListMainWindow::GetMode() const
c801d85f 2204{
63852e78 2205 return m_mode;
e1e955e1 2206}
c801d85f 2207
e179bd65 2208void wxListMainWindow::CalculatePositions()
c801d85f 2209{
92976ab6 2210 if (!m_lines.First()) return;
e487524e 2211
1e6d9499 2212 wxClientDC dc( this );
92976ab6 2213 dc.SetFont( GetFont() );
c801d85f 2214
92976ab6
RR
2215 int iconSpacing = 0;
2216 if (m_mode & wxLC_ICON) iconSpacing = m_normal_spacing;
2217 if (m_mode & wxLC_SMALL_ICON) iconSpacing = m_small_spacing;
004fd0c8 2218
92976ab6
RR
2219 // we take the first line (which also can be an icon or
2220 // an a text item in wxLC_ICON and wxLC_LIST modes) to
2221 // measure the size of the line
004fd0c8 2222
92976ab6
RR
2223 int lineWidth = 0;
2224 int lineHeight = 0;
2225 int lineSpacing = 0;
c801d85f 2226
92976ab6
RR
2227 wxListLineData *line = (wxListLineData*)m_lines.First()->Data();
2228 line->CalculateSize( &dc, iconSpacing );
2229 int dummy = 0;
2230 line->GetSize( dummy, lineSpacing );
2231 lineSpacing += 4;
bd8289c1 2232
92976ab6
RR
2233 int clientWidth = 0;
2234 int clientHeight = 0;
bd8289c1 2235
92976ab6 2236 if (m_mode & wxLC_REPORT)
c801d85f 2237 {
92976ab6
RR
2238 int x = 4;
2239 int y = 1;
2240 int entireHeight = m_lines.Number() * lineSpacing + 2;
2241 int scroll_pos = GetScrollPos( wxVERTICAL );
7c74e7fe 2242#if wxUSE_GENERIC_LIST_EXTENSIONS
7c0ea335 2243 int x_scroll_pos = GetScrollPos( wxHORIZONTAL );
7c74e7fe 2244#else
8b53e5a2 2245 SetScrollbars( m_xScroll, m_yScroll, 0, (entireHeight+15) / m_yScroll, 0, scroll_pos, TRUE );
7c74e7fe 2246#endif
92976ab6
RR
2247 GetClientSize( &clientWidth, &clientHeight );
2248
2249 wxNode* node = m_lines.First();
7c74e7fe 2250 int entireWidth = 0 ;
92976ab6
RR
2251 while (node)
2252 {
2253 wxListLineData *line = (wxListLineData*)node->Data();
2254 line->CalculateSize( &dc, iconSpacing );
2255 line->SetPosition( &dc, x, y, clientWidth );
2256 int col_x = 2;
2257 for (int i = 0; i < GetColumnCount(); i++)
2258 {
2259 line->SetColumnPosition( i, col_x );
2260 col_x += GetColumnWidth( i );
2261 }
7c74e7fe
SC
2262 entireWidth = wxMax( entireWidth , col_x ) ;
2263#if wxUSE_GENERIC_LIST_EXTENSIONS
2264 line->SetPosition( &dc, x, y, col_x );
2265#endif
92976ab6
RR
2266 y += lineSpacing; // one pixel blank line between items
2267 node = node->Next();
2268 }
bffa1c77 2269 m_visibleLines = clientHeight / lineSpacing;
7c74e7fe 2270#if wxUSE_GENERIC_LIST_EXTENSIONS
bffa1c77 2271 SetScrollbars( m_xScroll, m_yScroll, entireWidth / m_xScroll , (entireHeight+15) / m_yScroll, x_scroll_pos , scroll_pos, TRUE );
7c74e7fe 2272#endif
e1e955e1 2273 }
92976ab6
RR
2274 else
2275 {
2276 // at first we try without any scrollbar. if the items don't
2277 // fit into the window, we recalculate after subtracting an
2278 // approximated 15 pt for the horizontal scrollbar
004fd0c8 2279
92976ab6 2280 GetSize( &clientWidth, &clientHeight );
bffa1c77 2281 clientHeight -= 4; // sunken frame
bd8289c1 2282
92976ab6 2283 int entireWidth = 0;
bd8289c1 2284
92976ab6 2285 for (int tries = 0; tries < 2; tries++)
e487524e 2286 {
92976ab6
RR
2287 entireWidth = 0;
2288 int x = 5; // painting is done at x-2
2289 int y = 5; // painting is done at y-2
2290 int maxWidth = 0;
0b855868 2291 m_visibleLines = 0;
bffa1c77 2292 int m_currentVisibleLines = 0;
92976ab6
RR
2293 wxNode *node = m_lines.First();
2294 while (node)
2295 {
bffa1c77 2296 m_currentVisibleLines++;
92976ab6
RR
2297 wxListLineData *line = (wxListLineData*)node->Data();
2298 line->CalculateSize( &dc, iconSpacing );
2299 line->SetPosition( &dc, x, y, clientWidth );
2300 line->GetSize( lineWidth, lineHeight );
2301 if (lineWidth > maxWidth) maxWidth = lineWidth;
2302 y += lineSpacing;
bffa1c77
VZ
2303 if (m_currentVisibleLines > m_visibleLines)
2304 m_visibleLines = m_currentVisibleLines;
8b53e5a2 2305 if (y+lineSpacing-6 >= clientHeight) // -6 for earlier "line breaking"
92976ab6 2306 {
bffa1c77 2307 m_currentVisibleLines = 0;
92976ab6 2308 y = 5;
8b53e5a2
RR
2309 x += maxWidth+6;
2310 entireWidth += maxWidth+6;
92976ab6
RR
2311 maxWidth = 0;
2312 }
2313 node = node->Next();
2314 if (!node) entireWidth += maxWidth;
2315 if ((tries == 0) && (entireWidth > clientWidth))
2316 {
2317 clientHeight -= 15; // scrollbar height
0b855868 2318 m_visibleLines = 0;
bffa1c77 2319 m_currentVisibleLines = 0;
92976ab6
RR
2320 break;
2321 }
2322 if (!node) tries = 1; // everything fits, no second try required
2323 }
e487524e 2324 }
bffa1c77 2325
92976ab6
RR
2326 int scroll_pos = GetScrollPos( wxHORIZONTAL );
2327 SetScrollbars( m_xScroll, m_yScroll, (entireWidth+15) / m_xScroll, 0, scroll_pos, 0, TRUE );
e1e955e1 2328 }
e1e955e1 2329}
c801d85f
KB
2330
2331void wxListMainWindow::RealizeChanges( void )
2332{
92976ab6
RR
2333 if (!m_current)
2334 {
2335 wxNode *node = m_lines.First();
2336 if (node) m_current = (wxListLineData*)node->Data();
2337 }
2338 if (m_current)
2339 {
2340 FocusLine( m_current );
2341 if (m_mode & wxLC_SINGLE_SEL) m_current->Hilight( TRUE );
2342 }
e1e955e1 2343}
c801d85f 2344
19695fbd
VZ
2345long wxListMainWindow::GetNextItem( long item,
2346 int WXUNUSED(geometry),
2347 int state )
c801d85f 2348{
d1022fd6
VZ
2349 long ret = item,
2350 max = GetItemCount();
2351 wxCHECK_MSG( (ret == -1) || (ret < max), -1,
13771c08 2352 _T("invalid listctrl index in GetNextItem()") );
19695fbd
VZ
2353
2354 // notice that we start with the next item (or the first one if item == -1)
2355 // and this is intentional to allow writing a simple loop to iterate over
2356 // all selected items
d1022fd6
VZ
2357 ret++;
2358 if ( ret == max )
2359 {
2360 // this is not an error because the index was ok initially, just no
2361 // such item
2362 return -1;
2363 }
2364
2365 wxNode *node = m_lines.Nth( (size_t)ret );
63852e78
RR
2366 while (node)
2367 {
2368 wxListLineData *line = (wxListLineData*)node->Data();
19695fbd
VZ
2369 if ((state & wxLIST_STATE_FOCUSED) && (line == m_current))
2370 return ret;
2371 if ((state & wxLIST_STATE_SELECTED) && (line->IsHilighted()))
2372 return ret;
2373 if (!state)
2374 return ret;
63852e78 2375 ret++;
19695fbd 2376
63852e78
RR
2377 node = node->Next();
2378 }
19695fbd 2379
63852e78 2380 return -1;
e1e955e1 2381}
c801d85f 2382
debe6624 2383void wxListMainWindow::DeleteItem( long index )
c801d85f 2384{
63852e78 2385 m_dirty = TRUE;
6f2a55e3 2386 wxNode *node = m_lines.Nth( (size_t)index );
63852e78
RR
2387 if (node)
2388 {
2389 wxListLineData *line = (wxListLineData*)node->Data();
2390 if (m_current == line) m_current = (wxListLineData *) NULL;
2391 DeleteLine( line );
2392 m_lines.DeleteNode( node );
2393 }
e1e955e1 2394}
c801d85f 2395
debe6624 2396void wxListMainWindow::DeleteColumn( int col )
c801d85f 2397{
5b077d48 2398 wxCHECK_RET( col < (int)m_columns.GetCount(),
223d09f6 2399 wxT("attempting to delete inexistent column in wxListView") );
bd8289c1 2400
5b077d48
RR
2401 m_dirty = TRUE;
2402 wxNode *node = m_columns.Nth( col );
2403 if (node) m_columns.DeleteNode( node );
e1e955e1 2404}
c801d85f 2405
12c1b46a 2406void wxListMainWindow::DeleteAllItems()
c801d85f 2407{
5b077d48
RR
2408 m_dirty = TRUE;
2409 m_current = (wxListLineData *) NULL;
7c0ea335
VZ
2410
2411 // to make the deletion of all items faster, we don't send the
2412 // notifications in this case: this is compatible with wxMSW and
2413 // documented in DeleteAllItems() description
bffa1c77 2414
12c1b46a
RR
2415 wxListEvent event( wxEVT_COMMAND_LIST_DELETE_ALL_ITEMS, GetParent()->GetId() );
2416 event.SetEventObject( GetParent() );
2417 GetParent()->GetEventHandler()->ProcessEvent( event );
7c0ea335 2418
5b077d48 2419 m_lines.Clear();
e1e955e1 2420}
c801d85f 2421
12c1b46a 2422void wxListMainWindow::DeleteEverything()
c801d85f 2423{
12c1b46a
RR
2424 DeleteAllItems();
2425
5b077d48 2426 m_columns.Clear();
e1e955e1 2427}
c801d85f 2428
debe6624 2429void wxListMainWindow::EnsureVisible( long index )
c801d85f 2430{
dc6c62a9
RR
2431 // We have to call this here because the label in
2432 // question might just have been added and no screen
2433 // update taken place.
2434 if (m_dirty) wxYield();
2435
5b077d48
RR
2436 wxListLineData *oldCurrent = m_current;
2437 m_current = (wxListLineData *) NULL;
6f2a55e3 2438 wxNode *node = m_lines.Nth( (size_t)index );
5b077d48
RR
2439 if (node) m_current = (wxListLineData*)node->Data();
2440 if (m_current) MoveToFocus();
2441 m_current = oldCurrent;
e1e955e1 2442}
c801d85f 2443
debe6624 2444long wxListMainWindow::FindItem(long start, const wxString& str, bool WXUNUSED(partial) )
c801d85f 2445{
5b077d48
RR
2446 long pos = start;
2447 wxString tmp = str;
2448 if (pos < 0) pos = 0;
6f2a55e3 2449 wxNode *node = m_lines.Nth( (size_t)pos );
5b077d48
RR
2450 while (node)
2451 {
2452 wxListLineData *line = (wxListLineData*)node->Data();
2453 wxString s = "";
2454 line->GetText( 0, s );
2455 if (s == tmp) return pos;
2456 node = node->Next();
2457 pos++;
2458 }
2459 return -1;
e1e955e1 2460}
c801d85f 2461
debe6624 2462long wxListMainWindow::FindItem(long start, long data)
c801d85f 2463{
5b077d48
RR
2464 long pos = start;
2465 if (pos < 0) pos = 0;
6f2a55e3 2466 wxNode *node = m_lines.Nth( (size_t)pos );
5b077d48
RR
2467 while (node)
2468 {
2469 wxListLineData *line = (wxListLineData*)node->Data();
2470 wxListItem item;
2471 line->GetItem( 0, item );
2472 if (item.m_data == data) return pos;
2473 node = node->Next();
2474 pos++;
2475 }
2476 return -1;
e1e955e1 2477}
c801d85f 2478
debe6624 2479long wxListMainWindow::HitTest( int x, int y, int &flags )
c801d85f 2480{
5b077d48
RR
2481 wxNode *node = m_lines.First();
2482 int count = 0;
2483 while (node)
c801d85f 2484 {
5b077d48
RR
2485 wxListLineData *line = (wxListLineData*)node->Data();
2486 long ret = line->IsHit( x, y );
2487 if (ret & flags)
2488 {
6f2a55e3 2489 flags = (int)ret;
5b077d48
RR
2490 return count;
2491 }
2492 node = node->Next();
2493 count++;
e1e955e1 2494 }
5b077d48 2495 return -1;
e1e955e1 2496}
c801d85f
KB
2497
2498void wxListMainWindow::InsertItem( wxListItem &item )
2499{
5b077d48
RR
2500 m_dirty = TRUE;
2501 int mode = 0;
2502 if (m_mode & wxLC_REPORT) mode = wxLC_REPORT;
2503 else if (m_mode & wxLC_LIST) mode = wxLC_LIST;
2504 else if (m_mode & wxLC_ICON) mode = wxLC_ICON;
2505 else if (m_mode & wxLC_SMALL_ICON) mode = wxLC_ICON; // no typo
004fd0c8 2506
5b077d48 2507 wxListLineData *line = new wxListLineData( this, mode, m_hilightBrush );
004fd0c8 2508
5b077d48
RR
2509 if (m_mode & wxLC_REPORT)
2510 {
2511 line->InitItems( GetColumnCount() );
2512 item.m_width = GetColumnWidth( 0 )-3;
2513 }
2514 else
2515 {
2516 line->InitItems( 1 );
2517 }
004fd0c8 2518
5b077d48
RR
2519 line->SetItem( 0, item );
2520 if ((item.m_itemId >= 0) && (item.m_itemId < (int)m_lines.GetCount()))
2521 {
6f2a55e3 2522 wxNode *node = m_lines.Nth( (size_t)item.m_itemId );
5b077d48
RR
2523 if (node) m_lines.Insert( node, line );
2524 }
2525 else
2526 {
2527 m_lines.Append( line );
2528 }
e1e955e1 2529}
c801d85f 2530
debe6624 2531void wxListMainWindow::InsertColumn( long col, wxListItem &item )
c801d85f 2532{
5b077d48
RR
2533 m_dirty = TRUE;
2534 if (m_mode & wxLC_REPORT)
3db7be80 2535 {
5b077d48
RR
2536 if (item.m_width == wxLIST_AUTOSIZE_USEHEADER) item.m_width = GetTextLength( item.m_text );
2537 wxListHeaderData *column = new wxListHeaderData( item );
2538 if ((col >= 0) && (col < (int)m_columns.GetCount()))
2539 {
6f2a55e3 2540 wxNode *node = m_columns.Nth( (size_t)col );
5b077d48
RR
2541 if (node)
2542 m_columns.Insert( node, column );
2543 }
2544 else
2545 {
2546 m_columns.Append( column );
2547 }
3db7be80 2548 }
e1e955e1 2549}
c801d85f
KB
2550
2551wxListCtrlCompare list_ctrl_compare_func_2;
2552long list_ctrl_compare_data;
2553
004fd0c8 2554int LINKAGEMODE list_ctrl_compare_func_1( const void *arg1, const void *arg2 )
c801d85f 2555{
5b077d48
RR
2556 wxListLineData *line1 = *((wxListLineData**)arg1);
2557 wxListLineData *line2 = *((wxListLineData**)arg2);
2558 wxListItem item;
2559 line1->GetItem( 0, item );
2560 long data1 = item.m_data;
2561 line2->GetItem( 0, item );
2562 long data2 = item.m_data;
2563 return list_ctrl_compare_func_2( data1, data2, list_ctrl_compare_data );
e1e955e1 2564}
c801d85f
KB
2565
2566void wxListMainWindow::SortItems( wxListCtrlCompare fn, long data )
2567{
5b077d48
RR
2568 list_ctrl_compare_func_2 = fn;
2569 list_ctrl_compare_data = data;
2570 m_lines.Sort( list_ctrl_compare_func_1 );
af7c1052 2571 m_dirty = TRUE;
e1e955e1 2572}
c801d85f 2573
7c74e7fe
SC
2574void wxListMainWindow::OnScroll(wxScrollWinEvent& event)
2575{
bffa1c77 2576 wxScrolledWindow::OnScroll( event ) ;
7c74e7fe
SC
2577#if wxUSE_GENERIC_LIST_EXTENSIONS
2578
2579 if (event.GetOrientation() == wxHORIZONTAL && ( m_mode & wxLC_REPORT ))
2580 {
bffa1c77
VZ
2581 wxListCtrl* lc = wxDynamicCast( GetParent() , wxListCtrl ) ;
2582 if ( lc )
2583 {
2584 lc->m_headerWin->Refresh() ;
7c74e7fe 2585#ifdef __WXMAC__
bffa1c77 2586 lc->m_headerWin->MacUpdateImmediately() ;
7c74e7fe 2587#endif
bffa1c77 2588 }
7c74e7fe
SC
2589 }
2590#endif
2591}
2592
c801d85f
KB
2593// -------------------------------------------------------------------------------------
2594// wxListItem
2595// -------------------------------------------------------------------------------------
2596
2597IMPLEMENT_DYNAMIC_CLASS(wxListItem, wxObject)
2598
fd9811b1 2599wxListItem::wxListItem()
c801d85f 2600{
63852e78
RR
2601 m_mask = 0;
2602 m_itemId = 0;
2603 m_col = 0;
2604 m_state = 0;
2605 m_stateMask = 0;
2606 m_image = 0;
2607 m_data = 0;
2608 m_format = wxLIST_FORMAT_CENTRE;
2609 m_width = 0;
aaa37c0d
VZ
2610
2611 m_attr = NULL;
c801d85f
KB
2612}
2613
9b00bb16
RR
2614void wxListItem::Clear()
2615{
2616 m_mask = 0;
2617 m_itemId = 0;
2618 m_col = 0;
2619 m_state = 0;
2620 m_stateMask = 0;
2621 m_image = 0;
2622 m_data = 0;
2623 m_format = wxLIST_FORMAT_CENTRE;
2624 m_width = 0;
2625 m_text = wxEmptyString;
2626
2627 if (m_attr) delete m_attr;
2628 m_attr = NULL;
2629}
2630
2631void wxListItem::ClearAttributes()
2632{
2633 if (m_attr) delete m_attr;
2634 m_attr = NULL;
2635}
2636
c801d85f
KB
2637// -------------------------------------------------------------------------------------
2638// wxListEvent
2639// -------------------------------------------------------------------------------------
2640
92976ab6 2641IMPLEMENT_DYNAMIC_CLASS(wxListEvent, wxNotifyEvent)
c801d85f 2642
8f79098a 2643wxListEvent::wxListEvent( wxEventType commandType, int id ):
92976ab6 2644 wxNotifyEvent( commandType, id )
c801d85f 2645{
5b077d48
RR
2646 m_code = 0;
2647 m_itemIndex = 0;
2648 m_oldItemIndex = 0;
2649 m_col = 0;
2650 m_cancelled = FALSE;
2651 m_pointDrag.x = 0;
2652 m_pointDrag.y = 0;
e1e955e1 2653}
c801d85f 2654
72a7edf0
RR
2655void wxListEvent::CopyObject(wxObject& object_dest) const
2656{
2657 wxListEvent *obj = (wxListEvent *)&object_dest;
2658
2659 wxNotifyEvent::CopyObject(object_dest);
2660
2661 obj->m_code = m_code;
2662 obj->m_itemIndex = m_itemIndex;
2663 obj->m_oldItemIndex = m_oldItemIndex;
2664 obj->m_col = m_col;
2665 obj->m_cancelled = m_cancelled;
2666 obj->m_pointDrag = m_pointDrag;
2667 obj->m_item.m_mask = m_item.m_mask;
2668 obj->m_item.m_itemId = m_item.m_itemId;
2669 obj->m_item.m_col = m_item.m_col;
2670 obj->m_item.m_state = m_item.m_state;
2671 obj->m_item.m_stateMask = m_item.m_stateMask;
2672 obj->m_item.m_text = m_item.m_text;
2673 obj->m_item.m_image = m_item.m_image;
2674 obj->m_item.m_data = m_item.m_data;
2675 obj->m_item.m_format = m_item.m_format;
2676 obj->m_item.m_width = m_item.m_width;
aaa37c0d
VZ
2677
2678 if ( m_item.HasAttributes() )
2679 {
2680 obj->m_item.SetTextColour(m_item.GetTextColour());
2681 }
72a7edf0
RR
2682}
2683
c801d85f
KB
2684// -------------------------------------------------------------------------------------
2685// wxListCtrl
2686// -------------------------------------------------------------------------------------
2687
2688IMPLEMENT_DYNAMIC_CLASS(wxListCtrl, wxControl)
2689
2690BEGIN_EVENT_TABLE(wxListCtrl,wxControl)
2691 EVT_SIZE (wxListCtrl::OnSize)
53010e52 2692 EVT_IDLE (wxListCtrl::OnIdle)
c801d85f
KB
2693END_EVENT_TABLE()
2694
fd9811b1 2695wxListCtrl::wxListCtrl()
c801d85f 2696{
5b077d48
RR
2697 m_imageListNormal = (wxImageList *) NULL;
2698 m_imageListSmall = (wxImageList *) NULL;
2699 m_imageListState = (wxImageList *) NULL;
2700 m_mainWin = (wxListMainWindow*) NULL;
2701 m_headerWin = (wxListHeaderWindow*) NULL;
c801d85f
KB
2702}
2703
fd9811b1 2704wxListCtrl::~wxListCtrl()
c801d85f
KB
2705{
2706}
2707
25e3a937
VZ
2708bool wxListCtrl::Create(wxWindow *parent,
2709 wxWindowID id,
2710 const wxPoint &pos,
2711 const wxSize &size,
2712 long style,
25e3a937 2713 const wxValidator &validator,
25e3a937 2714 const wxString &name)
c801d85f 2715{
5b077d48
RR
2716 m_imageListNormal = (wxImageList *) NULL;
2717 m_imageListSmall = (wxImageList *) NULL;
2718 m_imageListState = (wxImageList *) NULL;
2719 m_mainWin = (wxListMainWindow*) NULL;
2720 m_headerWin = (wxListHeaderWindow*) NULL;
bd8289c1 2721
25e3a937 2722 if ( !(style & (wxLC_REPORT | wxLC_LIST | wxLC_ICON)) )
5b077d48 2723 {
25e3a937 2724 style = style | wxLC_LIST;
5b077d48 2725 }
098963c3
BJ
2726
2727 bool ret = wxControl::Create( parent, id, pos, size, style, validator, name );
2728
fc3463cc 2729
25e3a937
VZ
2730 if (style & wxSUNKEN_BORDER)
2731 style -= wxSUNKEN_BORDER;
bd8289c1 2732
25e3a937 2733 m_mainWin = new wxListMainWindow( this, -1, wxPoint(0,0), size, style );
bd8289c1 2734
f03fc89f 2735 if (HasFlag(wxLC_REPORT))
ea451729 2736 {
5b077d48 2737 m_headerWin = new wxListHeaderWindow( this, -1, m_mainWin, wxPoint(0,0), wxSize(size.x,23), wxTAB_TRAVERSAL );
ea451729
RR
2738 if (HasFlag(wxLC_NO_HEADER))
2739 m_headerWin->Show( FALSE );
2740 }
5b077d48 2741 else
ea451729 2742 {
5b077d48 2743 m_headerWin = (wxListHeaderWindow *) NULL;
ea451729 2744 }
bd8289c1 2745
91fc2bdc 2746 SetBackgroundColour( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_LISTBOX ) );
58dea4b0 2747
5b077d48 2748 return ret;
e1e955e1 2749}
c801d85f
KB
2750
2751void wxListCtrl::OnSize( wxSizeEvent &WXUNUSED(event) )
2752{
5b077d48 2753 /* handled in OnIdle */
bd8289c1 2754
5b077d48 2755 if (m_mainWin) m_mainWin->m_dirty = TRUE;
e1e955e1 2756}
c801d85f 2757
debe6624 2758void wxListCtrl::SetSingleStyle( long style, bool add )
c801d85f 2759{
f03fc89f 2760 long flag = GetWindowStyle();
bd8289c1 2761
5b077d48
RR
2762 if (add)
2763 {
2764 if (style & wxLC_MASK_TYPE) flag = flag & ~wxLC_MASK_TYPE;
2765 if (style & wxLC_MASK_ALIGN) flag = flag & ~wxLC_MASK_ALIGN;
2766 if (style & wxLC_MASK_SORT) flag = flag & ~wxLC_MASK_SORT;
2767 }
c801d85f 2768
5b077d48
RR
2769 if (add)
2770 {
2771 flag |= style;
2772 }
2773 else
2774 {
2775 if (flag & style) flag -= style;
2776 }
bd8289c1 2777
5b077d48 2778 SetWindowStyleFlag( flag );
e1e955e1 2779}
c801d85f 2780
debe6624 2781void wxListCtrl::SetWindowStyleFlag( long flag )
c801d85f 2782{
121a3581
RR
2783 if (m_mainWin)
2784 {
2785 m_mainWin->DeleteEverything();
c801d85f 2786
121a3581
RR
2787 int width = 0;
2788 int height = 0;
2789 GetClientSize( &width, &height );
c801d85f 2790
121a3581 2791 m_mainWin->SetMode( flag );
bd8289c1 2792
121a3581 2793 if (flag & wxLC_REPORT)
5b077d48 2794 {
121a3581 2795 if (!HasFlag(wxLC_REPORT))
5b077d48 2796 {
121a3581
RR
2797 if (!m_headerWin)
2798 {
004fd0c8 2799 m_headerWin = new wxListHeaderWindow( this, -1, m_mainWin,
bffa1c77
VZ
2800 wxPoint(0,0), wxSize(width,23), wxTAB_TRAVERSAL );
2801 if (HasFlag(wxLC_NO_HEADER))
2802 m_headerWin->Show( FALSE );
121a3581
RR
2803 }
2804 else
004fd0c8 2805 {
bffa1c77
VZ
2806 if (flag & wxLC_NO_HEADER)
2807 m_headerWin->Show( FALSE );
2808 else
8636aed8 2809 m_headerWin->Show( TRUE );
004fd0c8 2810 }
5b077d48
RR
2811 }
2812 }
121a3581 2813 else
5b077d48 2814 {
8636aed8 2815 if (HasFlag(wxLC_REPORT) && !(HasFlag(wxLC_NO_HEADER)))
121a3581
RR
2816 {
2817 m_headerWin->Show( FALSE );
2818 }
bffa1c77 2819 }
e1e955e1 2820 }
004fd0c8 2821
5b077d48 2822 wxWindow::SetWindowStyleFlag( flag );
e1e955e1 2823}
c801d85f 2824
e487524e 2825bool wxListCtrl::GetColumn(int col, wxListItem &item) const
c801d85f 2826{
5b077d48
RR
2827 m_mainWin->GetColumn( col, item );
2828 return TRUE;
e1e955e1 2829}
c801d85f 2830
debe6624 2831bool wxListCtrl::SetColumn( int col, wxListItem& item )
c801d85f 2832{
5b077d48
RR
2833 m_mainWin->SetColumn( col, item );
2834 return TRUE;
e1e955e1 2835}
c801d85f 2836
e487524e 2837int wxListCtrl::GetColumnWidth( int col ) const
c801d85f 2838{
5b077d48 2839 return m_mainWin->GetColumnWidth( col );
e1e955e1 2840}
c801d85f 2841
debe6624 2842bool wxListCtrl::SetColumnWidth( int col, int width )
c801d85f 2843{
5b077d48
RR
2844 m_mainWin->SetColumnWidth( col, width );
2845 return TRUE;
e1e955e1 2846}
c801d85f 2847
fd9811b1 2848int wxListCtrl::GetCountPerPage() const
c801d85f
KB
2849{
2850 return m_mainWin->GetCountPerPage(); // different from Windows ?
e1e955e1 2851}
c801d85f 2852
e487524e 2853bool wxListCtrl::GetItem( wxListItem &info ) const
c801d85f 2854{
5b077d48
RR
2855 m_mainWin->GetItem( info );
2856 return TRUE;
e1e955e1 2857}
c801d85f
KB
2858
2859bool wxListCtrl::SetItem( wxListItem &info )
2860{
5b077d48
RR
2861 m_mainWin->SetItem( info );
2862 return TRUE;
e1e955e1 2863}
c801d85f 2864
debe6624 2865long wxListCtrl::SetItem( long index, int col, const wxString& label, int imageId )
c801d85f 2866{
5b077d48
RR
2867 wxListItem info;
2868 info.m_text = label;
2869 info.m_mask = wxLIST_MASK_TEXT;
2870 info.m_itemId = index;
2871 info.m_col = col;
2872 if ( imageId > -1 )
2873 {
2874 info.m_image = imageId;
2875 info.m_mask |= wxLIST_MASK_IMAGE;
2876 };
2877 m_mainWin->SetItem(info);
2878 return TRUE;
e1e955e1 2879}
c801d85f 2880
e487524e 2881int wxListCtrl::GetItemState( long item, long stateMask ) const
c801d85f 2882{
5b077d48 2883 return m_mainWin->GetItemState( item, stateMask );
e1e955e1 2884}
c801d85f 2885
debe6624 2886bool wxListCtrl::SetItemState( long item, long state, long stateMask )
c801d85f 2887{
5b077d48
RR
2888 m_mainWin->SetItemState( item, state, stateMask );
2889 return TRUE;
e1e955e1 2890}
c801d85f 2891
debe6624 2892bool wxListCtrl::SetItemImage( long item, int image, int WXUNUSED(selImage) )
c801d85f 2893{
5b077d48
RR
2894 wxListItem info;
2895 info.m_image = image;
2896 info.m_mask = wxLIST_MASK_IMAGE;
2897 info.m_itemId = item;
2898 m_mainWin->SetItem( info );
2899 return TRUE;
e1e955e1 2900}
c801d85f 2901
e487524e 2902wxString wxListCtrl::GetItemText( long item ) const
c801d85f 2903{
5b077d48
RR
2904 wxListItem info;
2905 info.m_itemId = item;
2906 m_mainWin->GetItem( info );
2907 return info.m_text;
e1e955e1 2908}
c801d85f 2909
debe6624 2910void wxListCtrl::SetItemText( long item, const wxString &str )
c801d85f 2911{
5b077d48
RR
2912 wxListItem info;
2913 info.m_mask = wxLIST_MASK_TEXT;
2914 info.m_itemId = item;
2915 info.m_text = str;
2916 m_mainWin->SetItem( info );
e1e955e1 2917}
c801d85f 2918
e487524e 2919long wxListCtrl::GetItemData( long item ) const
c801d85f 2920{
5b077d48
RR
2921 wxListItem info;
2922 info.m_itemId = item;
2923 m_mainWin->GetItem( info );
2924 return info.m_data;
e1e955e1 2925}
c801d85f 2926
debe6624 2927bool wxListCtrl::SetItemData( long item, long data )
c801d85f 2928{
5b077d48
RR
2929 wxListItem info;
2930 info.m_mask = wxLIST_MASK_DATA;
2931 info.m_itemId = item;
2932 info.m_data = data;
2933 m_mainWin->SetItem( info );
2934 return TRUE;
e1e955e1 2935}
c801d85f 2936
0a240683 2937bool wxListCtrl::GetItemRect( long item, wxRect &rect, int WXUNUSED(code) ) const
c801d85f 2938{
5b077d48
RR
2939 m_mainWin->GetItemRect( item, rect );
2940 return TRUE;
e1e955e1 2941}
c801d85f 2942
e487524e 2943bool wxListCtrl::GetItemPosition( long item, wxPoint& pos ) const
c801d85f 2944{
5b077d48
RR
2945 m_mainWin->GetItemPosition( item, pos );
2946 return TRUE;
e1e955e1 2947}
c801d85f 2948
debe6624 2949bool wxListCtrl::SetItemPosition( long WXUNUSED(item), const wxPoint& WXUNUSED(pos) )
c801d85f 2950{
5b077d48 2951 return 0;
e1e955e1 2952}
c801d85f 2953
fd9811b1 2954int wxListCtrl::GetItemCount() const
c801d85f 2955{
5b077d48 2956 return m_mainWin->GetItemCount();
e1e955e1 2957}
c801d85f 2958
fd9811b1 2959int wxListCtrl::GetColumnCount() const
92976ab6 2960{
5b077d48 2961 return m_mainWin->GetColumnCount();
92976ab6
RR
2962}
2963
33d0b396
RR
2964void wxListCtrl::SetItemSpacing( int spacing, bool isSmall )
2965{
5b077d48 2966 m_mainWin->SetItemSpacing( spacing, isSmall );
e1e955e1 2967}
33d0b396 2968
e487524e 2969int wxListCtrl::GetItemSpacing( bool isSmall ) const
c801d85f 2970{
5b077d48 2971 return m_mainWin->GetItemSpacing( isSmall );
e1e955e1 2972}
c801d85f 2973
fd9811b1 2974int wxListCtrl::GetSelectedItemCount() const
c801d85f 2975{
5b077d48 2976 return m_mainWin->GetSelectedItemCount();
e1e955e1 2977}
c801d85f 2978
fd9811b1 2979wxColour wxListCtrl::GetTextColour() const
c801d85f 2980{
0530737d 2981 return GetForegroundColour();
e1e955e1 2982}
c801d85f 2983
0530737d 2984void wxListCtrl::SetTextColour(const wxColour& col)
c801d85f 2985{
0530737d 2986 SetForegroundColour(col);
e1e955e1 2987}
c801d85f 2988
fd9811b1 2989long wxListCtrl::GetTopItem() const
c801d85f 2990{
5b077d48 2991 return 0;
e1e955e1 2992}
c801d85f 2993
6de97a3b 2994long wxListCtrl::GetNextItem( long item, int geom, int state ) const
c801d85f 2995{
5b077d48 2996 return m_mainWin->GetNextItem( item, geom, state );
e1e955e1 2997}
c801d85f 2998
e487524e 2999wxImageList *wxListCtrl::GetImageList(int which) const
c801d85f 3000{
5b077d48
RR
3001 if (which == wxIMAGE_LIST_NORMAL)
3002 {
3003 return m_imageListNormal;
3004 }
3005 else if (which == wxIMAGE_LIST_SMALL)
3006 {
3007 return m_imageListSmall;
3008 }
3009 else if (which == wxIMAGE_LIST_STATE)
3010 {
3011 return m_imageListState;
3012 }
3013 return (wxImageList *) NULL;
e1e955e1 3014}
c801d85f 3015
debe6624 3016void wxListCtrl::SetImageList( wxImageList *imageList, int which )
c801d85f 3017{
5b077d48 3018 m_mainWin->SetImageList( imageList, which );
e1e955e1 3019}
c801d85f 3020
debe6624 3021bool wxListCtrl::Arrange( int WXUNUSED(flag) )
c801d85f 3022{
5b077d48 3023 return 0;
e1e955e1 3024}
c801d85f 3025
debe6624 3026bool wxListCtrl::DeleteItem( long item )
c801d85f 3027{
5b077d48
RR
3028 m_mainWin->DeleteItem( item );
3029 return TRUE;
e1e955e1 3030}
c801d85f 3031
fd9811b1 3032bool wxListCtrl::DeleteAllItems()
c801d85f 3033{
5b077d48
RR
3034 m_mainWin->DeleteAllItems();
3035 return TRUE;
e1e955e1 3036}
c801d85f 3037
4f22cf8d 3038bool wxListCtrl::DeleteAllColumns()
bd8289c1
VZ
3039{
3040 for ( size_t n = 0; n < m_mainWin->m_columns.GetCount(); n++ )
3041 DeleteColumn(n);
bffa1c77 3042
5b077d48 3043 return TRUE;
4f22cf8d
RR
3044}
3045
3046void wxListCtrl::ClearAll()
3047{
5b077d48 3048 m_mainWin->DeleteEverything();
bd8289c1
VZ
3049}
3050
debe6624 3051bool wxListCtrl::DeleteColumn( int col )
c801d85f 3052{
5b077d48
RR
3053 m_mainWin->DeleteColumn( col );
3054 return TRUE;
e1e955e1 3055}
c801d85f 3056
e179bd65 3057void wxListCtrl::Edit( long item )
c801d85f 3058{
e179bd65 3059 m_mainWin->Edit( item );
e1e955e1 3060}
c801d85f 3061
debe6624 3062bool wxListCtrl::EnsureVisible( long item )
c801d85f 3063{
5b077d48
RR
3064 m_mainWin->EnsureVisible( item );
3065 return TRUE;
e1e955e1 3066}
c801d85f 3067
debe6624 3068long wxListCtrl::FindItem( long start, const wxString& str, bool partial )
c801d85f 3069{
5b077d48 3070 return m_mainWin->FindItem( start, str, partial );
e1e955e1 3071}
c801d85f 3072
debe6624 3073long wxListCtrl::FindItem( long start, long data )
c801d85f 3074{
5b077d48 3075 return m_mainWin->FindItem( start, data );
e1e955e1 3076}
c801d85f 3077
bd8289c1 3078long wxListCtrl::FindItem( long WXUNUSED(start), const wxPoint& WXUNUSED(pt),
debe6624 3079 int WXUNUSED(direction))
c801d85f 3080{
5b077d48 3081 return 0;
e1e955e1 3082}
c801d85f
KB
3083
3084long wxListCtrl::HitTest( const wxPoint &point, int &flags )
3085{
5b077d48 3086 return m_mainWin->HitTest( (int)point.x, (int)point.y, flags );
e1e955e1 3087}
c801d85f
KB
3088
3089long wxListCtrl::InsertItem( wxListItem& info )
3090{
5b077d48 3091 m_mainWin->InsertItem( info );
2ebcd5f5 3092 return info.m_itemId;
e1e955e1 3093}
c801d85f 3094
debe6624 3095long wxListCtrl::InsertItem( long index, const wxString &label )
c801d85f 3096{
51cc4dad
RR
3097 wxListItem info;
3098 info.m_text = label;
3099 info.m_mask = wxLIST_MASK_TEXT;
3100 info.m_itemId = index;
3101 return InsertItem( info );
e1e955e1 3102}
c801d85f 3103
debe6624 3104long wxListCtrl::InsertItem( long index, int imageIndex )
c801d85f 3105{
51cc4dad
RR
3106 wxListItem info;
3107 info.m_mask = wxLIST_MASK_IMAGE;
3108 info.m_image = imageIndex;
3109 info.m_itemId = index;
3110 return InsertItem( info );
e1e955e1 3111}
c801d85f 3112
debe6624 3113long wxListCtrl::InsertItem( long index, const wxString &label, int imageIndex )
c801d85f 3114{
51cc4dad
RR
3115 wxListItem info;
3116 info.m_text = label;
3117 info.m_image = imageIndex;
3118 info.m_mask = wxLIST_MASK_TEXT | wxLIST_MASK_IMAGE;
3119 info.m_itemId = index;
3120 return InsertItem( info );
e1e955e1 3121}
c801d85f 3122
debe6624 3123long wxListCtrl::InsertColumn( long col, wxListItem &item )
c801d85f 3124{
d3e90957 3125 wxASSERT( m_headerWin );
51cc4dad 3126 m_mainWin->InsertColumn( col, item );
d3e90957 3127 m_headerWin->Refresh();
25e3a937 3128
51cc4dad 3129 return 0;
e1e955e1 3130}
c801d85f 3131
debe6624
JS
3132long wxListCtrl::InsertColumn( long col, const wxString &heading,
3133 int format, int width )
c801d85f 3134{
51cc4dad
RR
3135 wxListItem item;
3136 item.m_mask = wxLIST_MASK_TEXT | wxLIST_MASK_FORMAT;
3137 item.m_text = heading;
3138 if (width >= -2)
3139 {
3140 item.m_mask |= wxLIST_MASK_WIDTH;
3141 item.m_width = width;
3142 }
3143 item.m_format = format;
c801d85f 3144
51cc4dad 3145 return InsertColumn( col, item );
e1e955e1 3146}
c801d85f 3147
debe6624 3148bool wxListCtrl::ScrollList( int WXUNUSED(dx), int WXUNUSED(dy) )
c801d85f 3149{
51cc4dad 3150 return 0;
e1e955e1 3151}
c801d85f
KB
3152
3153// Sort items.
3154// fn is a function which takes 3 long arguments: item1, item2, data.
3155// item1 is the long data associated with a first item (NOT the index).
3156// item2 is the long data associated with a second item (NOT the index).
3157// data is the same value as passed to SortItems.
3158// The return value is a negative number if the first item should precede the second
3159// item, a positive number of the second item should precede the first,
3160// or zero if the two items are equivalent.
3161// data is arbitrary data to be passed to the sort function.
3162
3163bool wxListCtrl::SortItems( wxListCtrlCompare fn, long data )
3164{
51cc4dad
RR
3165 m_mainWin->SortItems( fn, data );
3166 return TRUE;
e1e955e1 3167}
c801d85f 3168
e3e65dac 3169void wxListCtrl::OnIdle( wxIdleEvent &WXUNUSED(event) )
53010e52 3170{
51cc4dad 3171 if (!m_mainWin->m_dirty) return;
53010e52 3172
51cc4dad
RR
3173 int cw = 0;
3174 int ch = 0;
3175 GetClientSize( &cw, &ch );
bd8289c1 3176
51cc4dad
RR
3177 int x = 0;
3178 int y = 0;
3179 int w = 0;
3180 int h = 0;
bd8289c1 3181
8636aed8 3182 if (HasFlag(wxLC_REPORT) && !HasFlag(wxLC_NO_HEADER))
51cc4dad
RR
3183 {
3184 m_headerWin->GetPosition( &x, &y );
3185 m_headerWin->GetSize( &w, &h );
3186 if ((x != 0) || (y != 0) || (w != cw) || (h != 23))
3187 m_headerWin->SetSize( 0, 0, cw, 23 );
3188
3189 m_mainWin->GetPosition( &x, &y );
3190 m_mainWin->GetSize( &w, &h );
3191 if ((x != 0) || (y != 24) || (w != cw) || (h != ch-24))
3192 m_mainWin->SetSize( 0, 24, cw, ch-24 );
3193 }
3194 else
3195 {
3196 m_mainWin->GetPosition( &x, &y );
3197 m_mainWin->GetSize( &w, &h );
3198 if ((x != 0) || (y != 24) || (w != cw) || (h != ch))
3199 m_mainWin->SetSize( 0, 0, cw, ch );
3200 }
bd8289c1 3201
51cc4dad
RR
3202 m_mainWin->CalculatePositions();
3203 m_mainWin->RealizeChanges();
3204 m_mainWin->m_dirty = FALSE;
3205 m_mainWin->Refresh();
e1e955e1 3206}
53010e52 3207
f03fc89f 3208bool wxListCtrl::SetBackgroundColour( const wxColour &colour )
bd8289c1 3209{
f03fc89f
VZ
3210 if ( !wxWindow::SetBackgroundColour( colour ) )
3211 return FALSE;
58dea4b0 3212
51cc4dad
RR
3213 if (m_mainWin)
3214 {
3215 m_mainWin->SetBackgroundColour( colour );
3216 m_mainWin->m_dirty = TRUE;
3217 }
004fd0c8 3218
51cc4dad
RR
3219 if (m_headerWin)
3220 {
cfb50f14 3221// m_headerWin->SetBackgroundColour( colour );
51cc4dad 3222 }
f03fc89f
VZ
3223
3224 return TRUE;
e4d06860
RR
3225}
3226
f03fc89f 3227bool wxListCtrl::SetForegroundColour( const wxColour &colour )
bd8289c1 3228{
f03fc89f
VZ
3229 if ( !wxWindow::SetForegroundColour( colour ) )
3230 return FALSE;
004fd0c8 3231
51cc4dad
RR
3232 if (m_mainWin)
3233 {
3234 m_mainWin->SetForegroundColour( colour );
3235 m_mainWin->m_dirty = TRUE;
3236 }
004fd0c8 3237
51cc4dad
RR
3238 if (m_headerWin)
3239 {
3240 m_headerWin->SetForegroundColour( colour );
3241 }
f03fc89f
VZ
3242
3243 return TRUE;
e4d06860 3244}
bd8289c1 3245
f03fc89f 3246bool wxListCtrl::SetFont( const wxFont &font )
bd8289c1 3247{
f03fc89f
VZ
3248 if ( !wxWindow::SetFont( font ) )
3249 return FALSE;
004fd0c8 3250
51cc4dad
RR
3251 if (m_mainWin)
3252 {
3253 m_mainWin->SetFont( font );
3254 m_mainWin->m_dirty = TRUE;
3255 }
004fd0c8 3256
51cc4dad
RR
3257 if (m_headerWin)
3258 {
3259 m_headerWin->SetFont( font );
3260 }
f03fc89f
VZ
3261
3262 return TRUE;
e4d06860 3263}
c801d85f 3264