]> git.saurik.com Git - wxWidgets.git/blob - src/os2/listctrl.cpp
OnEnter/OnDragOver API update (compiles, links, somewhat runs under wxGTK)
[wxWidgets.git] / src / os2 / listctrl.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: listctrl.cpp
3 // Purpose: wxListCtrl. See also Robert's generic wxListCtrl
4 // Author: David Webster
5 // Modified by:
6 // Created: 10/10/99
7 // RCS-ID: $Id$
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #ifndef WX_PRECOMP
16 #include "wx/wx.h"
17 #endif
18
19 #include "wx/listctrl.h"
20 #include "wx/log.h"
21
22 #include "wx/os2/private.h"
23
24 // TODO: not sure if we will need these
25 /*
26 static void wxConvertToOS2ListItem(const wxListCtrl *ctrl, wxListItem& info, LV_ITEM& tvItem);
27 static void wxConvertFromOS2ListItem(const wxListCtrl *ctrl, wxListItem& info, LV_ITEM& tvItem, HWND getFullInfo = 0);
28 */
29
30 #if !USE_SHARED_LIBRARY
31 IMPLEMENT_DYNAMIC_CLASS(wxListCtrl, wxControl)
32 IMPLEMENT_DYNAMIC_CLASS(wxListItem, wxObject)
33 #endif
34
35 wxListCtrl::wxListCtrl()
36 {
37 m_imageListNormal = NULL;
38 m_imageListSmall = NULL;
39 m_imageListState = NULL;
40 m_baseStyle = 0;
41 m_colCount = 0;
42 m_textCtrl = NULL;
43 }
44
45 bool wxListCtrl::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
46 long style, const wxValidator& validator, const wxString& name)
47 {
48 m_imageListNormal = NULL;
49 m_imageListSmall = NULL;
50 m_imageListState = NULL;
51 m_colCount = 0;
52
53 SetValidator(validator);
54 SetName(name);
55
56 int x = pos.x;
57 int y = pos.y;
58 int width = size.x;
59 int height = size.y;
60
61 m_windowStyle = style;
62
63 SetParent(parent);
64
65 m_windowId = (id == -1) ? NewControlId() : id;
66
67 if (parent) parent->AddChild(this);
68
69 // TODO create list control
70 // DWORD wstyle = WS_VISIBLE | WS_CHILD | WS_TABSTOP |
71 // LVS_SHAREIMAGELISTS | LVS_SHOWSELALWAYS;
72 // if ( wxStyleHasBorder(m_windowStyle) )
73 // wstyle |= WS_BORDER;
74 // m_baseStyle = wstyle;
75 //
76 // if ( !DoCreateControl(x, y, width, height) )
77 // return FALSE;
78 //
79 // if (parent)
80 // parent->AddChild(this);
81 return TRUE;
82 }
83
84 bool wxListCtrl::DoCreateControl(int x, int y, int w, int h)
85 {
86 DWORD wstyle = m_baseStyle;
87
88 bool want3D;
89 // TODO
90 // WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D);
91
92 // Even with extended styles, need to combine with WS_BORDER
93 // for them to look right.
94 // if ( want3D )
95 // wstyle |= WS_BORDER;
96
97 // long oldStyle = 0; // Dummy
98 // wstyle |= ConvertToMSWStyle(oldStyle, m_windowStyle);
99
100 // Create the ListView control.
101 // m_hWnd = (WXHWND)CreateWindowEx(exStyle,
102 // WC_LISTVIEW,
103 // wxT(""),
104 // wstyle,
105 // x, y, w, h,
106 // GetWinHwnd(GetParent()),
107 // (HMENU)m_windowId,
108 // wxGetInstance(),
109 // NULL);
110
111 // if ( !m_hWnd )
112 // {
113 // wxLogError(wxT("Can't create list control window."));
114 //
115 // return FALSE;
116 // }
117
118 // for comctl32.dll v 4.70+ we want to have this attribute because it's
119 // prettier (and also because wxGTK does it like this)
120 #ifdef ListView_SetExtendedListViewStyle
121 // if ( wstyle & LVS_REPORT )
122 // {
123 // ListView_SetExtendedListViewStyle(GetHwnd(),
124 // LVS_EX_FULLROWSELECT);
125 // }
126 #endif // ListView_SetExtendedListViewStyle
127
128 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW));
129 SetForegroundColour(GetParent()->GetForegroundColour());
130
131 // SubclassWin(m_hWnd);
132
133 return TRUE;
134 }
135
136 void wxListCtrl::UpdateStyle()
137 {
138 /*
139 if ( GetHWND() )
140 {
141 // The new window view style
142 long dummy;
143 DWORD dwStyleNew = ConvertToMSWStyle(dummy, m_windowStyle);
144 dwStyleNew |= m_baseStyle;
145
146 // Get the current window style.
147 DWORD dwStyleOld = ::GetWindowLong(GetHwnd(), GWL_STYLE);
148
149 // Only set the window style if the view bits have changed.
150 if ( dwStyleOld != dwStyleNew )
151 {
152 ::SetWindowLong(GetHwnd(), GWL_STYLE, dwStyleNew);
153 }
154 }
155 */
156 }
157 wxListCtrl::~wxListCtrl()
158 {
159 if (m_textCtrl)
160 {
161 m_textCtrl->UnsubclassWin();
162 m_textCtrl->SetHWND(0);
163 delete m_textCtrl;
164 m_textCtrl = NULL;
165 }
166 }
167
168 // Add or remove a single window style
169 void wxListCtrl::SetSingleStyle(long style, bool add)
170 {
171 long flag = GetWindowStyleFlag();
172
173 // Get rid of conflicting styles
174 if ( add )
175 {
176 if ( style & wxLC_MASK_TYPE)
177 flag = flag & ~wxLC_MASK_TYPE ;
178 if ( style & wxLC_MASK_ALIGN )
179 flag = flag & ~wxLC_MASK_ALIGN ;
180 if ( style & wxLC_MASK_SORT )
181 flag = flag & ~wxLC_MASK_SORT ;
182 }
183
184 if ( flag & style )
185 {
186 if ( !add )
187 flag -= style;
188 }
189 else
190 {
191 if ( add )
192 {
193 flag |= style;
194 }
195 }
196
197 m_windowStyle = flag;
198
199 UpdateStyle();
200 }
201
202 // Set the whole window style
203 void wxListCtrl::SetWindowStyleFlag(long flag)
204 {
205 m_windowStyle = flag;
206
207 UpdateStyle();
208 }
209
210 // Can be just a single style, or a bitlist
211 long wxListCtrl::ConvertToOS2Style(long& oldStyle, long style) const
212 {
213 long wstyle = 0;
214 /*
215 if ( style & wxLC_ICON )
216 {
217 if ( (oldStyle & LVS_TYPEMASK) == LVS_SMALLICON )
218 oldStyle -= LVS_SMALLICON;
219 if ( (oldStyle & LVS_TYPEMASK) == LVS_REPORT )
220 oldStyle -= LVS_REPORT;
221 if ( (oldStyle & LVS_TYPEMASK) == LVS_LIST )
222 oldStyle -= LVS_LIST;
223 wstyle |= LVS_ICON;
224 }
225
226 if ( style & wxLC_SMALL_ICON )
227 {
228 if ( (oldStyle & LVS_TYPEMASK) == LVS_ICON )
229 oldStyle -= LVS_ICON;
230 if ( (oldStyle & LVS_TYPEMASK) == LVS_REPORT )
231 oldStyle -= LVS_REPORT;
232 if ( (oldStyle & LVS_TYPEMASK) == LVS_LIST )
233 oldStyle -= LVS_LIST;
234 wstyle |= LVS_SMALLICON;
235 }
236
237 if ( style & wxLC_LIST )
238 {
239 if ( (oldStyle & LVS_TYPEMASK) == LVS_ICON )
240 oldStyle -= LVS_ICON;
241 if ( (oldStyle & LVS_TYPEMASK) == LVS_REPORT )
242 oldStyle -= LVS_REPORT;
243 if ( (oldStyle & LVS_TYPEMASK) == LVS_SMALLICON )
244 oldStyle -= LVS_SMALLICON;
245 wstyle |= LVS_LIST;
246 }
247
248 if ( style & wxLC_REPORT )
249 {
250 if ( (oldStyle & LVS_TYPEMASK) == LVS_ICON )
251 oldStyle -= LVS_ICON;
252 if ( (oldStyle & LVS_TYPEMASK) == LVS_LIST )
253 oldStyle -= LVS_LIST;
254 if ( (oldStyle & LVS_TYPEMASK) == LVS_SMALLICON )
255 oldStyle -= LVS_SMALLICON;
256
257 wstyle |= LVS_REPORT;
258 }
259
260 if ( style & wxLC_ALIGN_LEFT )
261 {
262 if ( oldStyle & LVS_ALIGNTOP )
263 oldStyle -= LVS_ALIGNTOP;
264 wstyle |= LVS_ALIGNLEFT;
265 }
266
267 if ( style & wxLC_ALIGN_TOP )
268 {
269 if ( oldStyle & LVS_ALIGNLEFT )
270 oldStyle -= LVS_ALIGNLEFT;
271 wstyle |= LVS_ALIGNTOP;
272 }
273
274 if ( style & wxLC_AUTOARRANGE )
275 wstyle |= LVS_AUTOARRANGE;
276
277 // Apparently, no such style (documentation wrong?)
278 // if ( style & wxLC_BUTTON )
279 // wstyle |= LVS_BUTTON;
280
281 if ( style & wxLC_NO_SORT_HEADER )
282 wstyle |= LVS_NOSORTHEADER;
283
284 if ( style & wxLC_NO_HEADER )
285 wstyle |= LVS_NOCOLUMNHEADER;
286
287 if ( style & wxLC_EDIT_LABELS )
288 wstyle |= LVS_EDITLABELS;
289
290 if ( style & wxLC_SINGLE_SEL )
291 wstyle |= LVS_SINGLESEL;
292
293 if ( style & wxLC_SORT_ASCENDING )
294 {
295 if ( oldStyle & LVS_SORTDESCENDING )
296 oldStyle -= LVS_SORTDESCENDING;
297 wstyle |= LVS_SORTASCENDING;
298 }
299
300 if ( style & wxLC_SORT_DESCENDING )
301 {
302 if ( oldStyle & LVS_SORTASCENDING )
303 oldStyle -= LVS_SORTASCENDING;
304 wstyle |= LVS_SORTDESCENDING;
305 }
306 */
307 return wstyle;
308 }
309
310 // Sets the background colour (GetBackgroundColour already implicit in
311 // wxWindow class)
312 bool wxListCtrl::SetBackgroundColour(const wxColour& col)
313 {
314 if ( !wxWindow::SetBackgroundColour(col) )
315 return FALSE;
316
317 // ListView_SetBkColor(GetHwnd(), PALETTERGB(col.Red(), col.Green(), col.Blue()));
318
319 return TRUE;
320 }
321
322 // Gets information about this column
323 bool wxListCtrl::GetColumn(int col, wxListItem& item) const
324 {
325 // TODO
326 return FALSE;
327 }
328
329 // Sets information about this column
330 bool wxListCtrl::SetColumn(int col, wxListItem& item)
331 {
332 // TODO
333 return FALSE;
334 }
335
336 // Gets the column width
337 int wxListCtrl::GetColumnWidth(int col) const
338 {
339 // TODO
340 return 0;
341 }
342
343 // Sets the column width
344 bool wxListCtrl::SetColumnWidth(int col, int width)
345 {
346 // TODO
347 return FALSE;
348 }
349
350 // Gets the number of items that can fit vertically in the
351 // visible area of the list control (list or report view)
352 // or the total number of items in the list control (icon
353 // or small icon view)
354 int wxListCtrl::GetCountPerPage() const
355 {
356 // TODO
357 return 0;
358 }
359
360 // Gets the edit control for editing labels.
361 wxTextCtrl* wxListCtrl::GetEditControl() const
362 {
363 return m_textCtrl;
364 }
365
366 // Gets information about the item
367 bool wxListCtrl::GetItem(wxListItem& info) const
368 {
369 // TODO
370 return FALSE;
371 }
372
373 // Sets information about the item
374 bool wxListCtrl::SetItem(wxListItem& info)
375 {
376 // TODO
377 return FALSE;
378 }
379
380 long wxListCtrl::SetItem(long index, int col, const wxString& label, int imageId)
381 {
382 wxListItem info;
383 info.m_text = label;
384 info.m_mask = wxLIST_MASK_TEXT;
385 info.m_itemId = index;
386 info.m_col = col;
387 if ( imageId > -1 )
388 {
389 info.m_image = imageId;
390 info.m_mask |= wxLIST_MASK_IMAGE;
391 }
392 return SetItem(info);
393 }
394
395
396 // Gets the item state
397 int wxListCtrl::GetItemState(long item, long stateMask) const
398 {
399 wxListItem info;
400
401 info.m_mask = wxLIST_MASK_STATE ;
402 info.m_stateMask = stateMask;
403 info.m_itemId = item;
404
405 if (!GetItem(info))
406 return 0;
407
408 return info.m_state;
409 }
410
411 // Sets the item state
412 bool wxListCtrl::SetItemState(long item, long state, long stateMask)
413 {
414 wxListItem info;
415
416 info.m_mask = wxLIST_MASK_STATE ;
417 info.m_state = state;
418 info.m_stateMask = stateMask;
419 info.m_itemId = item;
420
421 return SetItem(info);
422 }
423
424 // Sets the item image
425 bool wxListCtrl::SetItemImage(long item, int image, int selImage)
426 {
427 wxListItem info;
428
429 info.m_mask = wxLIST_MASK_IMAGE ;
430 info.m_image = image;
431 info.m_itemId = item;
432
433 return SetItem(info);
434 }
435
436 // Gets the item text
437 wxString wxListCtrl::GetItemText(long item) const
438 {
439 wxListItem info;
440
441 info.m_mask = wxLIST_MASK_TEXT ;
442 info.m_itemId = item;
443
444 if (!GetItem(info))
445 return wxString("");
446 return info.m_text;
447 }
448
449 // Sets the item text
450 void wxListCtrl::SetItemText(long item, const wxString& str)
451 {
452 wxListItem info;
453
454 info.m_mask = wxLIST_MASK_TEXT ;
455 info.m_itemId = item;
456 info.m_text = str;
457
458 SetItem(info);
459 }
460
461 // Gets the item data
462 long wxListCtrl::GetItemData(long item) const
463 {
464 wxListItem info;
465
466 info.m_mask = wxLIST_MASK_DATA ;
467 info.m_itemId = item;
468
469 if (!GetItem(info))
470 return 0;
471 return info.m_data;
472 }
473
474 // Sets the item data
475 bool wxListCtrl::SetItemData(long item, long data)
476 {
477 wxListItem info;
478
479 info.m_mask = wxLIST_MASK_DATA ;
480 info.m_itemId = item;
481 info.m_data = data;
482
483 return SetItem(info);
484 }
485
486 // Gets the item rectangle
487 bool wxListCtrl::GetItemRect(long item, wxRect& rect, int code) const
488 {
489 // TODO
490 return FALSE;
491 }
492
493 // Gets the item position
494 bool wxListCtrl::GetItemPosition(long item, wxPoint& pos) const
495 {
496 // TODO
497 return FALSE;
498 }
499
500 // Sets the item position.
501 bool wxListCtrl::SetItemPosition(long item, const wxPoint& pos)
502 {
503 // TODO
504 return FALSE;
505 }
506
507 // Gets the number of items in the list control
508 int wxListCtrl::GetItemCount() const
509 {
510 // TODO
511 return FALSE;
512 }
513
514 // Retrieves the spacing between icons in pixels.
515 // If small is TRUE, gets the spacing for the small icon
516 // view, otherwise the large icon view.
517 int wxListCtrl::GetItemSpacing(bool isSmall) const
518 {
519 // TODO
520 return FALSE;
521 }
522
523 // Gets the number of selected items in the list control
524 int wxListCtrl::GetSelectedItemCount() const
525 {
526 // TODO
527 return FALSE;
528 }
529
530 // Gets the text colour of the listview
531 wxColour wxListCtrl::GetTextColour() const
532 {
533 // TODO
534 return wxColour();
535 }
536
537 // Sets the text colour of the listview
538 void wxListCtrl::SetTextColour(const wxColour& col)
539 {
540 // TODO
541 }
542
543 // Gets the index of the topmost visible item when in
544 // list or report view
545 long wxListCtrl::GetTopItem() const
546 {
547 // TODO
548 return 0;
549 }
550
551 // Searches for an item, starting from 'item'.
552 // 'geometry' is one of
553 // wxLIST_NEXT_ABOVE/ALL/BELOW/LEFT/RIGHT.
554 // 'state' is a state bit flag, one or more of
555 // wxLIST_STATE_DROPHILITED/FOCUSED/SELECTED/CUT.
556 // item can be -1 to find the first item that matches the
557 // specified flags.
558 // Returns the item or -1 if unsuccessful.
559 long wxListCtrl::GetNextItem(long item, int geom, int state) const
560 {
561 // TODO
562 return 0;
563 }
564
565 wxImageList *wxListCtrl::GetImageList(int which) const
566 {
567 if ( which == wxIMAGE_LIST_NORMAL )
568 {
569 return m_imageListNormal;
570 }
571 else if ( which == wxIMAGE_LIST_SMALL )
572 {
573 return m_imageListSmall;
574 }
575 else if ( which == wxIMAGE_LIST_STATE )
576 {
577 return m_imageListState;
578 }
579 return NULL;
580 }
581
582 void wxListCtrl::SetImageList(wxImageList *imageList, int which)
583 {
584 int flags = 0;
585 if ( which == wxIMAGE_LIST_NORMAL )
586 {
587 m_imageListNormal = imageList;
588 }
589 else if ( which == wxIMAGE_LIST_SMALL )
590 {
591 m_imageListSmall = imageList;
592 }
593 else if ( which == wxIMAGE_LIST_STATE )
594 {
595 m_imageListState = imageList;
596 }
597 // TODO set image list
598 }
599
600 // Operations
601 ////////////////////////////////////////////////////////////////////////////
602
603 // Arranges the items
604 bool wxListCtrl::Arrange(int flag)
605 {
606 // TODO
607 return FALSE;
608 }
609
610 // Deletes an item
611 bool wxListCtrl::DeleteItem(long item)
612 {
613 // TODO
614 return FALSE;
615 }
616
617 // Deletes all items
618 bool wxListCtrl::DeleteAllItems()
619 {
620 // TODO
621 return FALSE;
622 }
623
624 // Deletes all items
625 bool wxListCtrl::DeleteAllColumns()
626 {
627 // TODO
628 return FALSE;
629 }
630
631 // Deletes a column
632 bool wxListCtrl::DeleteColumn(int col)
633 {
634 // TODO
635 return FALSE;
636 }
637
638 // Clears items, and columns if there are any.
639 void wxListCtrl::ClearAll()
640 {
641 DeleteAllItems();
642 if ( m_colCount > 0 )
643 DeleteAllColumns();
644 }
645
646 // Edit the label
647 wxTextCtrl* wxListCtrl::EditLabel(long item, wxClassInfo* textControlClass)
648 {
649 // TODO
650 return NULL;
651 }
652
653 // End label editing, optionally cancelling the edit
654 bool wxListCtrl::EndEditLabel(bool cancel)
655 {
656 // TODO
657 return FALSE;
658 }
659
660 // Ensures this item is visible
661 bool wxListCtrl::EnsureVisible(long item)
662 {
663 // TODO
664 return FALSE;
665 }
666
667 // Find an item whose label matches this string, starting from the item after 'start'
668 // or the beginning if 'start' is -1.
669 long wxListCtrl::FindItem(long start, const wxString& str, bool partial)
670 {
671 // TODO
672 return FALSE;
673 }
674
675 // Find an item whose data matches this data, starting from the item after 'start'
676 // or the beginning if 'start' is -1.
677 long wxListCtrl::FindItem(long start, long data)
678 {
679 // TODO
680 return 0;
681 }
682
683 // Find an item nearest this position in the specified direction, starting from
684 // the item after 'start' or the beginning if 'start' is -1.
685 long wxListCtrl::FindItem(long start, const wxPoint& pt, int direction)
686 {
687 // TODO
688 return 0;
689 }
690
691 // Determines which item (if any) is at the specified point,
692 // giving details in 'flags' (see wxLIST_HITTEST_... flags above)
693 long wxListCtrl::HitTest(const wxPoint& point, int& flags)
694 {
695 // TODO
696 return 0;
697 }
698
699 // Inserts an item, returning the index of the new item if successful,
700 // -1 otherwise.
701 long wxListCtrl::InsertItem(wxListItem& info)
702 {
703 // TODO
704 return 0;
705 }
706
707 long wxListCtrl::InsertItem(long index, const wxString& label)
708 {
709 wxListItem info;
710 info.m_text = label;
711 info.m_mask = wxLIST_MASK_TEXT;
712 info.m_itemId = index;
713 return InsertItem(info);
714 }
715
716 // Inserts an image item
717 long wxListCtrl::InsertItem(long index, int imageIndex)
718 {
719 wxListItem info;
720 info.m_image = imageIndex;
721 info.m_mask = wxLIST_MASK_IMAGE;
722 info.m_itemId = index;
723 return InsertItem(info);
724 }
725
726 // Inserts an image/string item
727 long wxListCtrl::InsertItem(long index, const wxString& label, int imageIndex)
728 {
729 wxListItem info;
730 info.m_image = imageIndex;
731 info.m_text = label;
732 info.m_mask = wxLIST_MASK_IMAGE | wxLIST_MASK_TEXT;
733 info.m_itemId = index;
734 return InsertItem(info);
735 }
736
737 // For list view mode (only), inserts a column.
738 long wxListCtrl::InsertColumn(long col, wxListItem& item)
739 {
740 // TODO
741 return 0;
742 }
743
744 long wxListCtrl::InsertColumn(long col, const wxString& heading, int format,
745 int width)
746 {
747 wxListItem item;
748 item.m_mask = wxLIST_MASK_TEXT | wxLIST_MASK_FORMAT;
749 item.m_text = heading;
750 if ( width > -1 )
751 {
752 item.m_mask |= wxLIST_MASK_WIDTH;
753 item.m_width = width;
754 }
755 item.m_format = format;
756
757 return InsertColumn(col, item);
758 }
759
760 // Scrolls the list control. If in icon, small icon or report view mode,
761 // x specifies the number of pixels to scroll. If in list view mode, x
762 // specifies the number of columns to scroll.
763 // If in icon, small icon or list view mode, y specifies the number of pixels
764 // to scroll. If in report view mode, y specifies the number of lines to scroll.
765 bool wxListCtrl::ScrollList(int dx, int dy)
766 {
767 // TODO
768 return FALSE;
769 }
770
771 // Sort items.
772
773 // fn is a function which takes 3 long arguments: item1, item2, data.
774 // item1 is the long data associated with a first item (NOT the index).
775 // item2 is the long data associated with a second item (NOT the index).
776 // data is the same value as passed to SortItems.
777 // The return value is a negative number if the first item should precede the second
778 // item, a positive number of the second item should precede the first,
779 // or zero if the two items are equivalent.
780
781 // data is arbitrary data to be passed to the sort function.
782 bool wxListCtrl::SortItems(wxListCtrlCompare fn, long data)
783 {
784 // TODO
785 return FALSE;
786 }
787
788 bool wxListCtrl::OS2Command(WXUINT cmd, WXWORD id)
789 {
790 /*
791 if (cmd == EN_UPDATE)
792 {
793 wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, id);
794 event.SetEventObject( this );
795 ProcessCommand(event);
796 return TRUE;
797 }
798 else if (cmd == EN_KILLFOCUS)
799 {
800 wxCommandEvent event(wxEVT_KILL_FOCUS, id);
801 event.SetEventObject( this );
802 ProcessCommand(event);
803 return TRUE;
804 }
805 else
806 return FALSE;
807 */
808 return FALSE;
809 }
810
811 bool wxListCtrl::OS2OnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
812 {
813 // TODO
814 /*
815 wxListEvent event(wxEVT_NULL, m_windowId);
816 wxEventType eventType = wxEVT_NULL;
817 NMHDR *hdr1 = (NMHDR *) lParam;
818 switch ( hdr1->code )
819 {
820 case LVN_BEGINRDRAG:
821 eventType = wxEVT_COMMAND_LIST_BEGIN_RDRAG;
822 // fall through
823
824 case LVN_BEGINDRAG:
825 if ( eventType == wxEVT_NULL )
826 {
827 eventType = wxEVT_COMMAND_LIST_BEGIN_DRAG;
828 }
829
830 {
831 NM_LISTVIEW *hdr = (NM_LISTVIEW *)lParam;
832 event.m_itemIndex = hdr->iItem;
833 event.m_pointDrag.x = hdr->ptAction.x;
834 event.m_pointDrag.y = hdr->ptAction.y;
835 }
836 break;
837
838 case LVN_BEGINLABELEDIT:
839 {
840 eventType = wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT;
841 LV_DISPINFO *info = (LV_DISPINFO *)lParam;
842 wxConvertFromMSWListItem(this, event.m_item, info->item, GetHwnd());
843 break;
844 }
845
846 case LVN_COLUMNCLICK:
847 {
848 eventType = wxEVT_COMMAND_LIST_COL_CLICK;
849 NM_LISTVIEW* hdr = (NM_LISTVIEW*)lParam;
850 event.m_itemIndex = -1;
851 event.m_col = hdr->iSubItem;
852 break;
853 }
854
855 case LVN_DELETEALLITEMS:
856 // what's the sense of generating a wxWin event for this when
857 // it's absolutely not portable?
858 #if 0
859 eventType = wxEVT_COMMAND_LIST_DELETE_ALL_ITEMS;
860 event.m_itemIndex = -1;
861 #endif // 0
862
863 // return TRUE to suppress all additional LVN_DELETEITEM
864 // notifications - this makes deleting all items from a list ctrl
865 // much faster
866 *result = TRUE;
867 return TRUE;
868
869 case LVN_DELETEITEM:
870 {
871 eventType = wxEVT_COMMAND_LIST_DELETE_ITEM;
872 NM_LISTVIEW* hdr = (NM_LISTVIEW*)lParam;
873 event.m_itemIndex = hdr->iItem;
874 break;
875 }
876 case LVN_ENDLABELEDIT:
877 {
878 eventType = wxEVT_COMMAND_LIST_END_LABEL_EDIT;
879 LV_DISPINFO *info = (LV_DISPINFO *)lParam;
880 wxConvertFromMSWListItem(this, event.m_item, info->item, GetHwnd());
881 if ( info->item.pszText == NULL || info->item.iItem == -1 )
882 event.m_cancelled = TRUE;
883 break;
884 }
885 case LVN_GETDISPINFO:
886 return FALSE;
887
888 // this provokes stack overflow: indeed, wxConvertFromMSWListItem()
889 // sends us WM_NOTIFY! As it doesn't do anything for now, just leave
890 // it out.
891 #if 0
892 {
893 // TODO: some text buffering here, I think
894 // TODO: API for getting Windows to retrieve values
895 // on demand.
896 eventType = wxEVT_COMMAND_LIST_GET_INFO;
897 LV_DISPINFO *info = (LV_DISPINFO *)lParam;
898 wxConvertFromMSWListItem(this, event.m_item, info->item, GetHwnd());
899 break;
900 }
901 #endif // 0
902
903 case LVN_INSERTITEM:
904 {
905 eventType = wxEVT_COMMAND_LIST_INSERT_ITEM;
906 NM_LISTVIEW* hdr = (NM_LISTVIEW*)lParam;
907 event.m_itemIndex = hdr->iItem;
908 break;
909 }
910 case LVN_ITEMCHANGED:
911 {
912 // This needs to be sent to wxListCtrl as a rather more
913 // concrete event. For now, just detect a selection
914 // or deselection.
915 NM_LISTVIEW* hdr = (NM_LISTVIEW*)lParam;
916 if ( (hdr->uNewState & LVIS_SELECTED) && !(hdr->uOldState & LVIS_SELECTED) )
917 {
918 eventType = wxEVT_COMMAND_LIST_ITEM_SELECTED;
919 event.m_itemIndex = hdr->iItem;
920 }
921 else if ( !(hdr->uNewState & LVIS_SELECTED) && (hdr->uOldState & LVIS_SELECTED) )
922 {
923 eventType = wxEVT_COMMAND_LIST_ITEM_DESELECTED;
924 event.m_itemIndex = hdr->iItem;
925 }
926 else
927 return FALSE;
928 break;
929 }
930
931 case LVN_KEYDOWN:
932 {
933 LV_KEYDOWN *info = (LV_KEYDOWN *)lParam;
934 WORD wVKey = info->wVKey;
935
936 // get the current selection
937 long lItem = GetNextItem(-1,
938 wxLIST_NEXT_ALL,
939 wxLIST_STATE_SELECTED);
940
941 // <Enter> or <Space> activate the selected item if any
942 if ( lItem != -1 && (wVKey == VK_RETURN || wVKey == VK_SPACE) )
943 {
944 // TODO this behaviour probably should be optional
945 eventType = wxEVT_COMMAND_LIST_ITEM_ACTIVATED;
946 event.m_itemIndex = lItem;
947 }
948 else
949 {
950 eventType = wxEVT_COMMAND_LIST_KEY_DOWN;
951 event.m_code = wxCharCodeMSWToWX(wVKey);
952 }
953 break;
954 }
955
956 case NM_DBLCLK:
957 // if the user processes it in wxEVT_COMMAND_LEFT_CLICK(), don't do
958 // anything else
959 if ( wxControl::MSWOnNotify(idCtrl, lParam, result) )
960 {
961 return TRUE;
962 }
963
964 // else translate it into wxEVT_COMMAND_LIST_ITEM_ACTIVATED event
965 eventType = wxEVT_COMMAND_LIST_ITEM_ACTIVATED;
966 break;
967
968 case LVN_SETDISPINFO:
969 {
970 eventType = wxEVT_COMMAND_LIST_SET_INFO;
971 LV_DISPINFO *info = (LV_DISPINFO *)lParam;
972 wxConvertFromMSWListItem(this, event.m_item, info->item, GetHwnd());
973 break;
974 }
975
976 default:
977 return wxControl::MSWOnNotify(idCtrl, lParam, result);
978 }
979
980 event.SetEventObject( this );
981 event.SetEventType(eventType);
982
983 if ( !GetEventHandler()->ProcessEvent(event) )
984 return FALSE;
985
986 if (hdr1->code == LVN_GETDISPINFO)
987 {
988 LV_DISPINFO *info = (LV_DISPINFO *)lParam;
989 if ( info->item.mask & LVIF_TEXT )
990 {
991 if ( !event.m_item.m_text.IsNull() )
992 {
993 info->item.pszText = AddPool(event.m_item.m_text);
994 info->item.cchTextMax = wxStrlen(info->item.pszText) + 1;
995 }
996 }
997 // wxConvertToMSWListItem(this, event.m_item, info->item);
998 }
999
1000 *result = !event.IsAllowed();
1001 */
1002 return TRUE;
1003 }
1004
1005 wxChar *wxListCtrl::AddPool(const wxString& str)
1006 {
1007 // Remove the first element if 3 strings exist
1008 if ( m_stringPool.Number() == 3 )
1009 {
1010 wxNode *node = m_stringPool.First();
1011 delete[] (char *)node->Data();
1012 delete node;
1013 }
1014 wxNode *node = m_stringPool.Add(WXSTRINGCAST str);
1015 return (wxChar *)node->Data();
1016 }
1017 // List item structure
1018 wxListItem::wxListItem()
1019 {
1020 m_mask = 0;
1021 m_itemId = 0;
1022 m_col = 0;
1023 m_state = 0;
1024 m_stateMask = 0;
1025 m_image = 0;
1026 m_data = 0;
1027
1028 m_format = wxLIST_FORMAT_CENTRE;
1029 m_width = 0;
1030 }
1031
1032 // TODO see if we need these
1033 /*
1034 static void wxConvertFromOS2ListItem(const wxListCtrl *ctrl, wxListItem& info, LV_ITEM& lvItem, HWND getFullInfo)
1035 {
1036 info.m_data = lvItem.lParam;
1037 info.m_mask = 0;
1038 info.m_state = 0;
1039 info.m_stateMask = 0;
1040 info.m_itemId = lvItem.iItem;
1041
1042 long oldMask = lvItem.mask;
1043
1044 bool needText = FALSE;
1045 if (getFullInfo != 0)
1046 {
1047 if ( lvItem.mask & LVIF_TEXT )
1048 needText = FALSE;
1049 else
1050 needText = TRUE;
1051
1052 if ( needText )
1053 {
1054 lvItem.pszText = new wxChar[513];
1055 lvItem.cchTextMax = 512;
1056 }
1057 // lvItem.mask |= TVIF_HANDLE | TVIF_STATE | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN | TVIF_PARAM;
1058 lvItem.mask |= LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
1059 ::SendMessage(getFullInfo, LVM_GETITEM, 0, (LPARAM)& lvItem);
1060 }
1061
1062 if ( lvItem.mask & LVIF_STATE )
1063 {
1064 info.m_mask |= wxLIST_MASK_STATE;
1065
1066 if ( lvItem.stateMask & LVIS_CUT)
1067 {
1068 info.m_stateMask |= wxLIST_STATE_CUT;
1069 if ( lvItem.state & LVIS_CUT )
1070 info.m_state |= wxLIST_STATE_CUT;
1071 }
1072 if ( lvItem.stateMask & LVIS_DROPHILITED)
1073 {
1074 info.m_stateMask |= wxLIST_STATE_DROPHILITED;
1075 if ( lvItem.state & LVIS_DROPHILITED )
1076 info.m_state |= wxLIST_STATE_DROPHILITED;
1077 }
1078 if ( lvItem.stateMask & LVIS_FOCUSED)
1079 {
1080 info.m_stateMask |= wxLIST_STATE_FOCUSED;
1081 if ( lvItem.state & LVIS_FOCUSED )
1082 info.m_state |= wxLIST_STATE_FOCUSED;
1083 }
1084 if ( lvItem.stateMask & LVIS_SELECTED)
1085 {
1086 info.m_stateMask |= wxLIST_STATE_SELECTED;
1087 if ( lvItem.state & LVIS_SELECTED )
1088 info.m_state |= wxLIST_STATE_SELECTED;
1089 }
1090 }
1091
1092 if ( lvItem.mask & LVIF_TEXT )
1093 {
1094 info.m_mask |= wxLIST_MASK_TEXT;
1095 info.m_text = lvItem.pszText;
1096 }
1097 if ( lvItem.mask & LVIF_IMAGE )
1098 {
1099 info.m_mask |= wxLIST_MASK_IMAGE;
1100 info.m_image = lvItem.iImage;
1101 }
1102 if ( lvItem.mask & LVIF_PARAM )
1103 info.m_mask |= wxLIST_MASK_DATA;
1104 if ( lvItem.mask & LVIF_DI_SETITEM )
1105 info.m_mask |= wxLIST_SET_ITEM;
1106 info.m_col = lvItem.iSubItem;
1107
1108 if (needText)
1109 {
1110 if (lvItem.pszText)
1111 delete[] lvItem.pszText;
1112 }
1113 lvItem.mask = oldMask;
1114 }
1115
1116 static void wxConvertToOS2ListItem(const wxListCtrl *ctrl, wxListItem& info, LV_ITEM& lvItem)
1117 {
1118 lvItem.iItem = (int) info.m_itemId;
1119
1120 lvItem.iImage = info.m_image;
1121 lvItem.lParam = info.m_data;
1122 lvItem.stateMask = 0;
1123 lvItem.state = 0;
1124 lvItem.mask = 0;
1125 lvItem.iSubItem = info.m_col;
1126
1127 if (info.m_mask & wxLIST_MASK_STATE)
1128 {
1129 lvItem.mask |= LVIF_STATE;
1130 if (info.m_stateMask & wxLIST_STATE_CUT)
1131 {
1132 lvItem.stateMask |= LVIS_CUT;
1133 if (info.m_state & wxLIST_STATE_CUT)
1134 lvItem.state |= LVIS_CUT;
1135 }
1136 if (info.m_stateMask & wxLIST_STATE_DROPHILITED)
1137 {
1138 lvItem.stateMask |= LVIS_DROPHILITED;
1139 if (info.m_state & wxLIST_STATE_DROPHILITED)
1140 lvItem.state |= LVIS_DROPHILITED;
1141 }
1142 if (info.m_stateMask & wxLIST_STATE_FOCUSED)
1143 {
1144 lvItem.stateMask |= LVIS_FOCUSED;
1145 if (info.m_state & wxLIST_STATE_FOCUSED)
1146 lvItem.state |= LVIS_FOCUSED;
1147 }
1148 if (info.m_stateMask & wxLIST_STATE_SELECTED)
1149 {
1150 lvItem.stateMask |= LVIS_SELECTED;
1151 if (info.m_state & wxLIST_STATE_SELECTED)
1152 lvItem.state |= LVIS_SELECTED;
1153 }
1154 }
1155
1156 if (info.m_mask & wxLIST_MASK_TEXT)
1157 {
1158 lvItem.mask |= LVIF_TEXT;
1159 if ( ctrl->GetWindowStyleFlag() & wxLC_USER_TEXT )
1160 {
1161 lvItem.pszText = LPSTR_TEXTCALLBACK;
1162 }
1163 else
1164 {
1165 lvItem.pszText = WXSTRINGCAST info.m_text;
1166 if ( lvItem.pszText )
1167 lvItem.cchTextMax = info.m_text.Length();
1168 else
1169 lvItem.cchTextMax = 0;
1170 }
1171 }
1172 if (info.m_mask & wxLIST_MASK_IMAGE)
1173 lvItem.mask |= LVIF_IMAGE;
1174 if (info.m_mask & wxLIST_MASK_DATA)
1175 lvItem.mask |= LVIF_PARAM;
1176 }
1177 */
1178
1179 // List event
1180 IMPLEMENT_DYNAMIC_CLASS(wxListEvent, wxCommandEvent)
1181
1182 wxListEvent::wxListEvent(wxEventType commandType, int id)
1183 : wxNotifyEvent(commandType, id)
1184 {
1185 m_code = 0;
1186 m_itemIndex = 0;
1187 m_col = 0;
1188 m_cancelled = FALSE;
1189 }
1190