]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/listctrl_mac.cpp
bc6232271d3ac17ab4269f5ebda7f4a0c9d40056
[wxWidgets.git] / src / mac / carbon / listctrl_mac.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/listctrl.cpp
3 // Purpose: wxListCtrl
4 // Author: Julian Smart
5 // Modified by: Agron Selimaj
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 #if wxUSE_LISTCTRL
28
29 #ifndef WX_PRECOMP
30 #include "wx/app.h"
31 #include "wx/intl.h"
32 #include "wx/log.h"
33 #include "wx/settings.h"
34 #include "wx/dcclient.h"
35 #include "wx/textctrl.h"
36 #endif
37
38 #include "wx/mac/uma.h"
39
40 #include "wx/imaglist.h"
41 #include "wx/listctrl.h"
42 #include "wx/sysopt.h"
43
44 #define wxMAC_ALWAYS_USE_GENERIC_LISTCTRL wxT("mac.listctrl.always_use_generic")
45
46 #if wxUSE_EXTENDED_RTTI
47 WX_DEFINE_FLAGS( wxListCtrlStyle )
48
49 wxBEGIN_FLAGS( wxListCtrlStyle )
50 // new style border flags, we put them first to
51 // use them for streaming out
52 wxFLAGS_MEMBER(wxBORDER_SIMPLE)
53 wxFLAGS_MEMBER(wxBORDER_SUNKEN)
54 wxFLAGS_MEMBER(wxBORDER_DOUBLE)
55 wxFLAGS_MEMBER(wxBORDER_RAISED)
56 wxFLAGS_MEMBER(wxBORDER_STATIC)
57 wxFLAGS_MEMBER(wxBORDER_NONE)
58
59 // old style border flags
60 wxFLAGS_MEMBER(wxSIMPLE_BORDER)
61 wxFLAGS_MEMBER(wxSUNKEN_BORDER)
62 wxFLAGS_MEMBER(wxDOUBLE_BORDER)
63 wxFLAGS_MEMBER(wxRAISED_BORDER)
64 wxFLAGS_MEMBER(wxSTATIC_BORDER)
65 wxFLAGS_MEMBER(wxBORDER)
66
67 // standard window styles
68 wxFLAGS_MEMBER(wxTAB_TRAVERSAL)
69 wxFLAGS_MEMBER(wxCLIP_CHILDREN)
70 wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW)
71 wxFLAGS_MEMBER(wxWANTS_CHARS)
72 wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE)
73 wxFLAGS_MEMBER(wxALWAYS_SHOW_SB )
74 wxFLAGS_MEMBER(wxVSCROLL)
75 wxFLAGS_MEMBER(wxHSCROLL)
76
77 wxFLAGS_MEMBER(wxLC_LIST)
78 wxFLAGS_MEMBER(wxLC_REPORT)
79 wxFLAGS_MEMBER(wxLC_ICON)
80 wxFLAGS_MEMBER(wxLC_SMALL_ICON)
81 wxFLAGS_MEMBER(wxLC_ALIGN_TOP)
82 wxFLAGS_MEMBER(wxLC_ALIGN_LEFT)
83 wxFLAGS_MEMBER(wxLC_AUTOARRANGE)
84 wxFLAGS_MEMBER(wxLC_USER_TEXT)
85 wxFLAGS_MEMBER(wxLC_EDIT_LABELS)
86 wxFLAGS_MEMBER(wxLC_NO_HEADER)
87 wxFLAGS_MEMBER(wxLC_SINGLE_SEL)
88 wxFLAGS_MEMBER(wxLC_SORT_ASCENDING)
89 wxFLAGS_MEMBER(wxLC_SORT_DESCENDING)
90 wxFLAGS_MEMBER(wxLC_VIRTUAL)
91
92 wxEND_FLAGS( wxListCtrlStyle )
93
94 IMPLEMENT_DYNAMIC_CLASS_XTI(wxListCtrl, wxControl,"wx/listctrl.h")
95
96 wxBEGIN_PROPERTIES_TABLE(wxListCtrl)
97 wxEVENT_PROPERTY( TextUpdated , wxEVT_COMMAND_TEXT_UPDATED , wxCommandEvent )
98
99 wxPROPERTY_FLAGS( WindowStyle , wxListCtrlStyle , long , SetWindowStyleFlag , GetWindowStyleFlag , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style
100 wxEND_PROPERTIES_TABLE()
101
102 wxBEGIN_HANDLERS_TABLE(wxListCtrl)
103 wxEND_HANDLERS_TABLE()
104
105 wxCONSTRUCTOR_5( wxListCtrl , wxWindow* , Parent , wxWindowID , Id , wxPoint , Position , wxSize , Size , long , WindowStyle )
106
107 /*
108 TODO : Expose more information of a list's layout etc. via appropriate objects (à la NotebookPageInfo)
109 */
110 #else
111 IMPLEMENT_DYNAMIC_CLASS(wxListCtrl, wxControl)
112 #endif
113
114 IMPLEMENT_DYNAMIC_CLASS(wxListView, wxListCtrl)
115 IMPLEMENT_DYNAMIC_CLASS(wxListItem, wxObject)
116
117 IMPLEMENT_DYNAMIC_CLASS(wxListEvent, wxNotifyEvent)
118
119 WX_DECLARE_EXPORTED_LIST(wxListItem, wxListItemList);
120 #include "wx/listimpl.cpp"
121 WX_DEFINE_LIST(wxListItemList)
122
123 class wxMacListCtrlItem : public wxMacListBoxItem
124 {
125 public:
126 wxMacListCtrlItem();
127
128 virtual void Notification(wxMacDataItemBrowserControl *owner ,
129 DataBrowserItemNotification message,
130 DataBrowserItemDataRef itemData ) const;
131
132 virtual void SetColumnInfo( unsigned int column, wxListItem* item );
133 virtual wxListItem* GetColumnInfo( unsigned int column );
134 virtual bool HasColumnInfo( unsigned int column );
135
136 virtual void SetColumnTextValue( unsigned int column, const wxString& text );
137 virtual const wxString& GetColumnTextValue( unsigned int column );
138
139 virtual int GetColumnImageValue( unsigned int column );
140 virtual void SetColumnImageValue( unsigned int column, int imageIndex );
141
142 virtual OSStatus GetSetData( wxMacDataItemBrowserControl *owner ,
143 DataBrowserPropertyID property,
144 DataBrowserItemDataRef itemData,
145 bool changeValue );
146
147
148 virtual ~wxMacListCtrlItem();
149 protected:
150 wxListItemList m_rowItems;
151 };
152
153 // TODO: Make a better name!!
154 class wxMacDataBrowserListCtrlControl : public wxMacDataItemBrowserControl
155 {
156 public:
157 wxMacDataBrowserListCtrlControl( wxWindow *peer, const wxPoint& pos, const wxSize& size, long style );
158 virtual ~wxMacDataBrowserListCtrlControl();
159
160 // create a list item (can be a subclass of wxMacListBoxItem)
161
162 virtual wxMacListCtrlItem* CreateItem();
163
164 virtual void MacInsertItem( unsigned int n, wxListItem* item );
165 virtual void MacSetColumnInfo( unsigned int row, unsigned int column, wxListItem* item );
166 virtual void MacGetColumnInfo( unsigned int row, unsigned int column, wxListItem& item );
167 virtual void UpdateState(wxMacDataItem* dataItem, wxListItem* item);
168
169 protected:
170 wxClientDataType m_clientDataItemsType;
171
172 };
173
174 // TODO: This gives errors, find out why.
175 //BEGIN_EVENT_TABLE(wxListCtrl, wxControl)
176 // EVT_PAINT(wxListCtrl::OnPaint)
177 //END_EVENT_TABLE()
178
179 // ============================================================================
180 // implementation
181 // ============================================================================
182
183 wxMacListControl* wxListCtrl::GetPeer() const
184 {
185 return dynamic_cast<wxMacListControl*>(m_peer);
186 }
187
188 // ----------------------------------------------------------------------------
189 // wxListCtrl construction
190 // ----------------------------------------------------------------------------
191
192 void wxListCtrl::Init()
193 {
194 m_imageListNormal = NULL;
195 m_imageListSmall = NULL;
196 m_imageListState = NULL;
197
198 // keep track of if we created our own image lists, or if they were assigned
199 // to us.
200 m_ownsImageListNormal = m_ownsImageListSmall = m_ownsImageListState = false;
201 m_colCount = 0;
202 m_count = 0;
203 m_textCtrl = NULL;
204 m_genericImpl = NULL;
205 m_dbImpl = NULL;
206 }
207
208 bool wxListCtrl::Create(wxWindow *parent,
209 wxWindowID id,
210 const wxPoint& pos,
211 const wxSize& size,
212 long style,
213 const wxValidator& validator,
214 const wxString& name)
215 {
216
217 // for now, we'll always use the generic list control for ICON and LIST views,
218 // because they dynamically change the number of columns on resize.
219 // Also, allow the user to set it to use the list ctrl as well.
220 if ( (wxSystemOptions::HasOption( wxMAC_ALWAYS_USE_GENERIC_LISTCTRL )
221 && (wxSystemOptions::GetOptionInt( wxMAC_ALWAYS_USE_GENERIC_LISTCTRL ) == 1)) ||
222 (style & wxLC_ICON) || (style & wxLC_SMALL_ICON) || (style & wxLC_LIST))
223 {
224 m_macIsUserPane = true;
225
226 if ( !wxWindow::Create(parent, id, pos, size, style, name) )
227 return false;
228 m_genericImpl = new wxGenericListCtrl(this, id, pos, size, style, validator, name);
229 return true;
230 }
231
232 else
233 {
234 m_macIsUserPane = false;
235
236 if ( !wxWindow::Create(parent, id, pos, size, style, name) )
237 return false;
238 m_dbImpl = new wxMacDataBrowserListCtrlControl( this, pos, size, style );
239 m_peer = m_dbImpl;
240
241 MacPostControlCreate( pos, size );
242 }
243
244 return true;
245 }
246
247 wxListCtrl::~wxListCtrl()
248 {
249 if (m_ownsImageListNormal)
250 delete m_imageListNormal;
251 if (m_ownsImageListSmall)
252 delete m_imageListSmall;
253 if (m_ownsImageListState)
254 delete m_imageListState;
255 }
256
257 // ----------------------------------------------------------------------------
258 // set/get/change style
259 // ----------------------------------------------------------------------------
260
261 // Add or remove a single window style
262 void wxListCtrl::SetSingleStyle(long style, bool add)
263 {
264 long flag = GetWindowStyleFlag();
265
266 // Get rid of conflicting styles
267 if ( add )
268 {
269 if ( style & wxLC_MASK_TYPE)
270 flag = flag & ~wxLC_MASK_TYPE;
271 if ( style & wxLC_MASK_ALIGN )
272 flag = flag & ~wxLC_MASK_ALIGN;
273 if ( style & wxLC_MASK_SORT )
274 flag = flag & ~wxLC_MASK_SORT;
275 }
276
277 if ( add )
278 flag |= style;
279 else
280 flag &= ~style;
281
282 SetWindowStyleFlag(flag);
283 }
284
285 // Set the whole window style
286 void wxListCtrl::SetWindowStyleFlag(long flag)
287 {
288 if ( flag != m_windowStyle )
289 {
290 m_windowStyle = flag;
291
292 if (m_genericImpl){
293 m_genericImpl->SetWindowStyleFlag(flag);
294 }
295
296 Refresh();
297 }
298 }
299
300 void wxListCtrl::DoSetSize( int x, int y, int width, int height, int sizeFlags ){
301 wxControl::DoSetSize(x, y, width, height, sizeFlags);
302
303 if (m_genericImpl)
304 m_genericImpl->SetSize(x, y, width, height, sizeFlags);
305 }
306
307 // ----------------------------------------------------------------------------
308 // accessors
309 // ----------------------------------------------------------------------------
310
311 // Gets information about this column
312 bool wxListCtrl::GetColumn(int col, wxListItem& item) const
313 {
314 if (m_genericImpl)
315 return m_genericImpl->GetColumn(col, item);
316
317 bool success = true;
318
319 if ( item.m_mask & wxLIST_MASK_TEXT )
320 {
321 }
322
323 if ( item.m_mask & wxLIST_MASK_FORMAT )
324 {
325 }
326
327 if ( item.m_mask & wxLIST_MASK_IMAGE )
328 {
329 }
330
331 if ( (item.m_mask & wxLIST_MASK_TEXT) )
332 {
333 }
334
335
336 return success;
337 }
338
339 // Sets information about this column
340 bool wxListCtrl::SetColumn(int col, wxListItem& item)
341 {
342 if (m_genericImpl)
343 return m_genericImpl->SetColumn(col, item);
344
345 return false;
346 }
347
348 int wxListCtrl::GetColumnCount() const
349 {
350 if (m_genericImpl)
351 return m_genericImpl->GetColumnCount();
352
353 if (m_dbImpl){
354 UInt32 count;
355 m_dbImpl->GetColumnCount(&count);
356 return count;
357 }
358
359 return m_colCount;
360 }
361
362 // Gets the column width
363 int wxListCtrl::GetColumnWidth(int col) const
364 {
365 if (m_genericImpl)
366 return m_genericImpl->GetColumnWidth(col);
367
368 if (m_dbImpl){
369 return m_dbImpl->GetColumnWidth(col);
370 }
371
372 return 0;
373 }
374
375 // Sets the column width
376 bool wxListCtrl::SetColumnWidth(int col, int width)
377 {
378 if (m_genericImpl)
379 return m_genericImpl->SetColumnWidth(col, width);
380
381 // TODO: This is setting the width of the first column
382 // to the entire window width; investigate why
383 // this is.
384
385 if (m_dbImpl){
386 int mywidth = width;
387 if (width == wxLIST_AUTOSIZE || width == wxLIST_AUTOSIZE_USEHEADER)
388 mywidth = 150;
389
390 if (col == -1){
391 for (int column = 0; column < GetColumnCount(); column++){
392 m_dbImpl->SetColumnWidth(col, mywidth);
393 }
394 }
395 else{
396 m_dbImpl->SetColumnWidth(col, mywidth);
397 }
398 return true;
399 }
400
401 return false;
402 }
403
404 // Gets the number of items that can fit vertically in the
405 // visible area of the list control (list or report view)
406 // or the total number of items in the list control (icon
407 // or small icon view)
408 int wxListCtrl::GetCountPerPage() const
409 {
410 if (m_genericImpl)
411 return m_genericImpl->GetCountPerPage();
412
413 if (m_dbImpl){
414 }
415
416 return 1;
417 }
418
419 // Gets the edit control for editing labels.
420 wxTextCtrl* wxListCtrl::GetEditControl() const
421 {
422 if (m_genericImpl)
423 return m_genericImpl->GetEditControl();
424
425 return NULL;
426 }
427
428 // Gets information about the item
429 bool wxListCtrl::GetItem(wxListItem& info) const
430 {
431 if (m_genericImpl)
432 return m_genericImpl->GetItem(info);
433
434 if (m_dbImpl)
435 m_dbImpl->MacGetColumnInfo(info.m_itemId, info.m_col, info);
436 bool success = true;
437 return success;
438 }
439
440 // Sets information about the item
441 bool wxListCtrl::SetItem(wxListItem& info)
442 {
443 if (m_genericImpl)
444 return m_genericImpl->SetItem(info);
445
446 if (m_dbImpl)
447 m_dbImpl->MacSetColumnInfo( info.m_itemId, info.m_col, &info );
448
449 return true;
450 }
451
452 long wxListCtrl::SetItem(long index, int col, const wxString& label, int imageId)
453 {
454 if (m_genericImpl)
455 return m_genericImpl->SetItem(index, col, label, imageId);
456
457 wxListItem info;
458 info.m_text = label;
459 info.m_mask = wxLIST_MASK_TEXT;
460 info.m_itemId = index;
461 info.m_col = col;
462 if ( imageId > -1 )
463 {
464 info.m_image = imageId;
465 info.m_mask |= wxLIST_MASK_IMAGE;
466 }
467 return SetItem(info);
468 }
469
470
471 // Gets the item state
472 int wxListCtrl::GetItemState(long item, long stateMask) const
473 {
474 if (m_genericImpl)
475 return m_genericImpl->GetItemState(item, stateMask);
476
477 wxListItem info;
478
479 info.m_mask = wxLIST_MASK_STATE;
480 info.m_stateMask = stateMask;
481 info.m_itemId = item;
482
483 if (!GetItem(info))
484 return 0;
485
486 return info.m_state;
487 }
488
489 // Sets the item state
490 bool wxListCtrl::SetItemState(long item, long state, long stateMask)
491 {
492 if (m_genericImpl)
493 return m_genericImpl->SetItemState(item, state, stateMask);
494
495 wxListItem info;
496 info.m_mask = wxLIST_MASK_STATE;
497 info.m_stateMask = stateMask;
498 info.m_state = state;
499 info.m_itemId = item;
500 return SetItem(info);
501 }
502
503 // Sets the item image
504 bool wxListCtrl::SetItemImage(long item, int image, int WXUNUSED(selImage))
505 {
506 return SetItemColumnImage(item, 0, image);
507 }
508
509 // Sets the item image
510 bool wxListCtrl::SetItemColumnImage(long item, long column, int image)
511 {
512 if (m_genericImpl)
513 return m_genericImpl->SetItemColumnImage(item, column, image);
514
515 wxListItem info;
516
517 info.m_mask = wxLIST_MASK_IMAGE;
518 info.m_image = image;
519 info.m_itemId = item;
520 info.m_col = column;
521
522 return SetItem(info);
523 }
524
525 // Gets the item text
526 wxString wxListCtrl::GetItemText(long item) const
527 {
528 if (m_genericImpl)
529 return m_genericImpl->GetItemText(item);
530
531 wxListItem info;
532
533 info.m_mask = wxLIST_MASK_TEXT;
534 info.m_itemId = item;
535
536 if (!GetItem(info))
537 return wxEmptyString;
538 return info.m_text;
539 }
540
541 // Sets the item text
542 void wxListCtrl::SetItemText(long item, const wxString& str)
543 {
544 if (m_genericImpl)
545 return m_genericImpl->SetItemText(item, str);
546
547 wxListItem info;
548
549 info.m_mask = wxLIST_MASK_TEXT;
550 info.m_itemId = item;
551 info.m_text = str;
552
553 SetItem(info);
554 }
555
556 // Gets the item data
557 long wxListCtrl::GetItemData(long item) const
558 {
559 if (m_genericImpl)
560 return m_genericImpl->GetItemData(item);
561
562 wxListItem info;
563
564 info.m_mask = wxLIST_MASK_DATA;
565 info.m_itemId = item;
566
567 if (!GetItem(info))
568 return 0;
569 return info.m_data;
570 }
571
572 // Sets the item data
573 bool wxListCtrl::SetItemData(long item, long data)
574 {
575 if (m_genericImpl)
576 return m_genericImpl->SetItemData(item, data);
577
578 wxListItem info;
579
580 info.m_mask = wxLIST_MASK_DATA;
581 info.m_itemId = item;
582 info.m_data = data;
583
584 return SetItem(info);
585 }
586
587 wxRect wxListCtrl::GetViewRect() const
588 {
589 wxASSERT_MSG( !HasFlag(wxLC_REPORT | wxLC_LIST),
590 _T("wxListCtrl::GetViewRect() only works in icon mode") );
591
592 if (m_genericImpl)
593 return m_genericImpl->GetViewRect();
594
595 wxRect rect;
596 return rect;
597 }
598
599 // Gets the item rectangle
600 bool wxListCtrl::GetItemRect(long item, wxRect& rect, int code) const
601 {
602 if (m_genericImpl)
603 return m_genericImpl->GetItemRect(item, rect, code);
604
605 return true;
606 }
607
608 // Gets the item position
609 bool wxListCtrl::GetItemPosition(long item, wxPoint& pos) const
610 {
611 if (m_genericImpl)
612 return m_genericImpl->GetItemPosition(item, pos);
613
614 bool success = false;
615
616 return success;
617 }
618
619 // Sets the item position.
620 bool wxListCtrl::SetItemPosition(long item, const wxPoint& pos)
621 {
622 if (m_genericImpl)
623 return m_genericImpl->SetItemPosition(item, pos);
624
625 return false;
626 }
627
628 // Gets the number of items in the list control
629 int wxListCtrl::GetItemCount() const
630 {
631 if (m_genericImpl)
632 return m_genericImpl->GetItemCount();
633
634 if (m_dbImpl)
635 return m_dbImpl->MacGetCount();
636
637 return m_count;
638 }
639
640 void wxListCtrl::SetItemSpacing( int spacing, bool isSmall )
641 {
642 if (m_genericImpl)
643 m_genericImpl->SetItemSpacing(spacing, isSmall);
644 }
645
646 wxSize wxListCtrl::GetItemSpacing() const
647 {
648 if (m_genericImpl)
649 return m_genericImpl->GetItemSpacing();
650
651 return wxSize(0, 0);
652 }
653
654 void wxListCtrl::SetItemTextColour( long item, const wxColour &col )
655 {
656 if (m_genericImpl){
657 m_genericImpl->SetItemTextColour(item, col);
658 }
659
660 wxListItem info;
661 info.m_itemId = item;
662 info.SetTextColour( col );
663 SetItem( info );
664 }
665
666 wxColour wxListCtrl::GetItemTextColour( long item ) const
667 {
668 if (m_genericImpl)
669 return m_genericImpl->GetItemTextColour(item);
670
671 if (m_dbImpl){
672 wxListItem info;
673 if (GetItem(info))
674 return info.GetTextColour();
675 }
676 return wxNullColour;
677 }
678
679 void wxListCtrl::SetItemBackgroundColour( long item, const wxColour &col )
680 {
681 if (m_genericImpl){
682 m_genericImpl->SetItemBackgroundColour(item, col);
683 return;
684 }
685
686 wxListItem info;
687 info.m_itemId = item;
688 info.SetBackgroundColour( col );
689 SetItem( info );
690 }
691
692 wxColour wxListCtrl::GetItemBackgroundColour( long item ) const
693 {
694 if (m_genericImpl)
695 return m_genericImpl->GetItemBackgroundColour(item);
696
697 if (m_dbImpl){
698 wxListItem info;
699 if (GetItem(info))
700 return info.GetBackgroundColour();
701 }
702 return wxNullColour;
703 }
704
705 void wxListCtrl::SetItemFont( long item, const wxFont &f )
706 {
707 if (m_genericImpl){
708 m_genericImpl->SetItemFont(item, f);
709 return;
710 }
711
712 wxListItem info;
713 info.m_itemId = item;
714 info.SetFont( f );
715 SetItem( info );
716 }
717
718 wxFont wxListCtrl::GetItemFont( long item ) const
719 {
720 if (m_genericImpl)
721 return m_genericImpl->GetItemFont(item);
722
723 if (m_dbImpl){
724 wxListItem info;
725 if (GetItem(info))
726 return info.GetFont();
727 }
728
729 return wxNullFont;
730 }
731
732 // Gets the number of selected items in the list control
733 int wxListCtrl::GetSelectedItemCount() const
734 {
735 if (m_genericImpl)
736 return m_genericImpl->GetSelectedItemCount();
737
738 if (m_dbImpl)
739 return m_dbImpl->GetSelectedItemCount(NULL, true);
740
741 return 0;
742 }
743
744 // Gets the text colour of the listview
745 wxColour wxListCtrl::GetTextColour() const
746 {
747 if (m_genericImpl)
748 return m_genericImpl->GetTextColour();
749
750 // TODO: we need owner drawn list items to customize text color.
751 if (m_dbImpl)
752 return *wxBLACK;
753 }
754
755 // Sets the text colour of the listview
756 void wxListCtrl::SetTextColour(const wxColour& col)
757 {
758 if (m_genericImpl){
759 m_genericImpl->SetTextColour(col);
760 return;
761 }
762
763 // TODO: if we add owner-drawn item support for DataBrowser,
764 // consider supporting this property
765 }
766
767 // Gets the index of the topmost visible item when in
768 // list or report view
769 long wxListCtrl::GetTopItem() const
770 {
771 if (m_genericImpl)
772 return m_genericImpl->GetTopItem();
773
774 return 0;
775 }
776
777 // Searches for an item, starting from 'item'.
778 // 'geometry' is one of
779 // wxLIST_NEXT_ABOVE/ALL/BELOW/LEFT/RIGHT.
780 // 'state' is a state bit flag, one or more of
781 // wxLIST_STATE_DROPHILITED/FOCUSED/SELECTED/CUT.
782 // item can be -1 to find the first item that matches the
783 // specified flags.
784 // Returns the item or -1 if unsuccessful.
785 long wxListCtrl::GetNextItem(long item, int geom, int state) const
786 {
787 if (m_genericImpl)
788 return m_genericImpl->GetNextItem(item, geom, state);
789
790 return 0;
791 }
792
793
794 wxImageList *wxListCtrl::GetImageList(int which) const
795 {
796 if (m_genericImpl)
797 return m_genericImpl->GetImageList(which);
798
799 if ( which == wxIMAGE_LIST_NORMAL )
800 {
801 return m_imageListNormal;
802 }
803 else if ( which == wxIMAGE_LIST_SMALL )
804 {
805 return m_imageListSmall;
806 }
807 else if ( which == wxIMAGE_LIST_STATE )
808 {
809 return m_imageListState;
810 }
811 return NULL;
812 }
813
814 void wxListCtrl::SetImageList(wxImageList *imageList, int which)
815 {
816 if (m_genericImpl){
817 m_genericImpl->SetImageList(imageList, which);
818 return;
819 }
820
821 int flags = 0;
822 if ( which == wxIMAGE_LIST_NORMAL )
823 {
824 if (m_ownsImageListNormal) delete m_imageListNormal;
825 m_imageListNormal = imageList;
826 m_ownsImageListNormal = false;
827 }
828 else if ( which == wxIMAGE_LIST_SMALL )
829 {
830 if (m_ownsImageListSmall) delete m_imageListSmall;
831 m_imageListSmall = imageList;
832 m_ownsImageListSmall = false;
833 }
834 else if ( which == wxIMAGE_LIST_STATE )
835 {
836 if (m_ownsImageListState) delete m_imageListState;
837 m_imageListState = imageList;
838 m_ownsImageListState = false;
839 }
840 }
841
842 void wxListCtrl::AssignImageList(wxImageList *imageList, int which)
843 {
844 if (m_genericImpl){
845 m_genericImpl->AssignImageList(imageList, which);
846 return;
847 }
848
849 SetImageList(imageList, which);
850 if ( which == wxIMAGE_LIST_NORMAL )
851 m_ownsImageListNormal = true;
852 else if ( which == wxIMAGE_LIST_SMALL )
853 m_ownsImageListSmall = true;
854 else if ( which == wxIMAGE_LIST_STATE )
855 m_ownsImageListState = true;
856 }
857
858 // ----------------------------------------------------------------------------
859 // Operations
860 // ----------------------------------------------------------------------------
861
862 // Arranges the items
863 bool wxListCtrl::Arrange(int flag)
864 {
865 if (m_genericImpl)
866 return m_genericImpl->Arrange(flag);
867 return false;
868 }
869
870 // Deletes an item
871 bool wxListCtrl::DeleteItem(long item)
872 {
873 if (m_genericImpl)
874 return m_genericImpl->DeleteItem(item);
875
876 if (m_dbImpl){
877 m_dbImpl->MacDelete(item);
878 wxListEvent event( wxEVT_COMMAND_LIST_DELETE_ITEM, GetId() );
879 event.SetEventObject( this );
880 event.m_itemIndex = item;
881 GetEventHandler()->ProcessEvent( event );
882
883 }
884 return true;
885 }
886
887 // Deletes all items
888 bool wxListCtrl::DeleteAllItems()
889 {
890 if (m_genericImpl)
891 return m_genericImpl->DeleteAllItems();
892
893 if (m_dbImpl){
894 m_dbImpl->MacClear();
895 wxListEvent event( wxEVT_COMMAND_LIST_DELETE_ALL_ITEMS, GetId() );
896 event.SetEventObject( this );
897 GetEventHandler()->ProcessEvent( event );
898 }
899 return true;
900 }
901
902 // Deletes all items
903 bool wxListCtrl::DeleteAllColumns()
904 {
905 if (m_genericImpl)
906 return m_genericImpl->DeleteAllColumns();
907
908 if (m_dbImpl){
909 UInt32 cols;
910 m_dbImpl->GetColumnCount(&cols);
911 for (UInt32 col = 0; col < cols; col++){
912 DeleteColumn(col);
913 }
914 }
915
916 return true;
917 }
918
919 // Deletes a column
920 bool wxListCtrl::DeleteColumn(int col)
921 {
922 if (m_genericImpl)
923 return m_genericImpl->DeleteColumn(col);
924
925 if (m_dbImpl){
926 OSStatus err = m_dbImpl->RemoveColumn(col);
927 return err == noErr;
928 }
929
930 return true;
931 }
932
933 // Clears items, and columns if there are any.
934 void wxListCtrl::ClearAll()
935 {
936 if (m_genericImpl){
937 m_genericImpl->ClearAll();
938 return;
939 }
940
941 if (m_dbImpl){
942 DeleteAllItems();
943 DeleteAllColumns();
944 }
945 }
946
947 wxTextCtrl* wxListCtrl::EditLabel(long item, wxClassInfo* textControlClass)
948 {
949 if (m_genericImpl)
950 return m_genericImpl->EditLabel(item, textControlClass);
951
952 if (m_dbImpl){
953 wxMacDataItem* id = m_dbImpl->GetItemFromLine(item);
954 verify_noerr( SetDataBrowserEditItem(m_dbImpl->GetControlRef(), (DataBrowserItemID)id, kMinColumnId) );
955 }
956 return NULL;
957 }
958
959 // End label editing, optionally cancelling the edit
960 bool wxListCtrl::EndEditLabel(bool cancel)
961 {
962 // TODO: generic impl. doesn't have this method - is it needed for us?
963 if (m_genericImpl)
964 return true; // m_genericImpl->EndEditLabel(cancel);
965
966 if (m_dbImpl)
967 verify_noerr( SetDataBrowserEditItem(m_dbImpl->GetControlRef(), kDataBrowserNoItem, kMinColumnId) );
968 return true;
969 }
970
971 // Ensures this item is visible
972 bool wxListCtrl::EnsureVisible(long item)
973 {
974 if (m_genericImpl)
975 return m_genericImpl->EnsureVisible(item);
976
977 if (m_dbImpl){
978 wxMacDataItem* dataItem = m_dbImpl->GetItemFromLine(item);
979 m_dbImpl->RevealItem(dataItem, kDataBrowserRevealWithoutSelecting);
980 }
981 }
982
983 // Find an item whose label matches this string, starting from the item after 'start'
984 // or the beginning if 'start' is -1.
985 long wxListCtrl::FindItem(long start, const wxString& str, bool partial)
986 {
987 if (m_genericImpl)
988 return m_genericImpl->FindItem(start, str, partial);
989
990 return -1;
991 }
992
993 // Find an item whose data matches this data, starting from the item after 'start'
994 // or the beginning if 'start' is -1.
995 long wxListCtrl::FindItem(long start, long data)
996 {
997 if (m_genericImpl)
998 return m_genericImpl->FindItem(start, data);
999
1000 long idx = start + 1;
1001 long count = GetItemCount();
1002
1003 while (idx < count)
1004 {
1005 if (GetItemData(idx) == data)
1006 return idx;
1007 idx++;
1008 };
1009
1010 return -1;
1011 }
1012
1013 // Find an item nearest this position in the specified direction, starting from
1014 // the item after 'start' or the beginning if 'start' is -1.
1015 long wxListCtrl::FindItem(long start, const wxPoint& pt, int direction)
1016 {
1017 if (m_genericImpl)
1018 return m_genericImpl->FindItem(start, pt, direction);
1019 return -1;
1020 }
1021
1022 // Determines which item (if any) is at the specified point,
1023 // giving details in 'flags' (see wxLIST_HITTEST_... flags above)
1024 long
1025 wxListCtrl::HitTest(const wxPoint& point, int& flags, long *ptrSubItem) const
1026 {
1027 if (m_genericImpl)
1028 return m_genericImpl->HitTest(point, flags, ptrSubItem);
1029
1030 return -1;
1031 }
1032
1033
1034 // Inserts an item, returning the index of the new item if successful,
1035 // -1 otherwise.
1036 long wxListCtrl::InsertItem(wxListItem& info)
1037 {
1038 wxASSERT_MSG( !IsVirtual(), _T("can't be used with virtual controls") );
1039
1040 if (m_genericImpl)
1041 return m_genericImpl->InsertItem(info);
1042
1043 if (m_dbImpl){
1044 int count = GetItemCount();
1045
1046 if (info.m_itemId > count)
1047 info.m_itemId = count;
1048
1049 m_dbImpl->MacInsertItem(info.m_itemId, &info );
1050 wxListEvent event( wxEVT_COMMAND_LIST_INSERT_ITEM, GetId() );
1051 event.SetEventObject( this );
1052 event.m_itemIndex = info.m_itemId;
1053 GetEventHandler()->ProcessEvent( event );
1054 }
1055
1056 return info.m_itemId;
1057 }
1058
1059 long wxListCtrl::InsertItem(long index, const wxString& label)
1060 {
1061 if (m_genericImpl)
1062 return m_genericImpl->InsertItem(index, label);
1063
1064 wxListItem info;
1065 info.m_text = label;
1066 info.m_mask = wxLIST_MASK_TEXT;
1067 info.m_itemId = index;
1068 return InsertItem(info);
1069 }
1070
1071 // Inserts an image item
1072 long wxListCtrl::InsertItem(long index, int imageIndex)
1073 {
1074 if (m_genericImpl)
1075 return m_genericImpl->InsertItem(index, imageIndex);
1076
1077 wxListItem info;
1078 info.m_image = imageIndex;
1079 info.m_mask = wxLIST_MASK_IMAGE;
1080 info.m_itemId = index;
1081 return InsertItem(info);
1082 }
1083
1084 // Inserts an image/string item
1085 long wxListCtrl::InsertItem(long index, const wxString& label, int imageIndex)
1086 {
1087 if (m_genericImpl)
1088 return m_genericImpl->InsertItem(index, label, imageIndex);
1089
1090 wxListItem info;
1091 info.m_image = imageIndex;
1092 info.m_text = label;
1093 info.m_mask = wxLIST_MASK_IMAGE | wxLIST_MASK_TEXT;
1094 info.m_itemId = index;
1095 return InsertItem(info);
1096 }
1097
1098 // For list view mode (only), inserts a column.
1099 long wxListCtrl::InsertColumn(long col, wxListItem& item)
1100 {
1101 if (m_genericImpl)
1102 return m_genericImpl->InsertColumn(col, item);
1103
1104 if (m_dbImpl){
1105 if ( !(item.GetMask() & wxLIST_MASK_WIDTH) )
1106 item.SetWidth(150);
1107
1108 DataBrowserPropertyType type = kDataBrowserTextType;
1109 wxImageList* imageList = GetImageList(wxIMAGE_LIST_SMALL);
1110 if (imageList && imageList->GetImageCount() > 0){
1111 wxBitmap bmp = imageList->GetBitmap(0);
1112 if (bmp.Ok())
1113 type = kDataBrowserIconAndTextType;
1114 }
1115
1116 fprintf(stderr, "Flush is %d\n", item.GetAlign());
1117 SInt16 just = teFlushDefault;
1118 if (item.GetMask() & wxLIST_MASK_FORMAT){
1119 if (item.GetAlign() == wxLIST_FORMAT_LEFT)
1120 just = teFlushLeft;
1121 else if (item.GetAlign() == wxLIST_FORMAT_CENTER)
1122 just = teCenter;
1123 else if (item.GetAlign() == wxLIST_FORMAT_RIGHT)
1124 just = teFlushRight;
1125 }
1126 m_dbImpl->InsertColumn(col, type, item.GetText(), just, item.GetWidth());
1127
1128 if (GetWindowStyleFlag() & wxLC_EDIT_LABELS)
1129 {
1130 DataBrowserTableViewColumnID id;
1131 m_dbImpl->GetColumnIDFromIndex(col, &id);
1132 DataBrowserPropertyFlags flags;
1133 verify_noerr(m_dbImpl->GetPropertyFlags(id, &flags));
1134 flags |= kDataBrowserPropertyIsEditable;
1135 verify_noerr(m_dbImpl->SetPropertyFlags(id, flags));
1136 }
1137 }
1138
1139 return col;
1140 }
1141
1142 long wxListCtrl::InsertColumn(long col,
1143 const wxString& heading,
1144 int format,
1145 int width)
1146 {
1147 if (m_genericImpl)
1148 return m_genericImpl->InsertColumn(col, heading, format, width);
1149
1150 wxListItem item;
1151 item.m_mask = wxLIST_MASK_TEXT | wxLIST_MASK_FORMAT;
1152 item.m_text = heading;
1153 if ( width > -1 )
1154 {
1155 item.m_mask |= wxLIST_MASK_WIDTH;
1156 item.m_width = width;
1157 }
1158 item.m_format = format;
1159
1160 return InsertColumn(col, item);
1161 }
1162
1163 // scroll the control by the given number of pixels (exception: in list view,
1164 // dx is interpreted as number of columns)
1165 bool wxListCtrl::ScrollList(int dx, int dy)
1166 {
1167 if (m_genericImpl)
1168 return m_genericImpl->ScrollList(dx, dy);
1169
1170 if (m_dbImpl){
1171 m_dbImpl->SetScrollPosition(dx, dy);
1172 }
1173 return true;
1174 }
1175
1176
1177 bool wxListCtrl::SortItems(wxListCtrlCompare fn, long data)
1178 {
1179 if (m_genericImpl)
1180 return m_genericImpl->SortItems(fn, data);
1181
1182 return true;
1183 }
1184
1185 // ----------------------------------------------------------------------------
1186 // virtual list controls
1187 // ----------------------------------------------------------------------------
1188
1189 wxString wxListCtrl::OnGetItemText(long WXUNUSED(item), long WXUNUSED(col)) const
1190 {
1191 // this is a pure virtual function, in fact - which is not really pure
1192 // because the controls which are not virtual don't need to implement it
1193 wxFAIL_MSG( _T("wxListCtrl::OnGetItemText not supposed to be called") );
1194
1195 return wxEmptyString;
1196 }
1197
1198 int wxListCtrl::OnGetItemImage(long WXUNUSED(item)) const
1199 {
1200 wxCHECK_MSG(!GetImageList(wxIMAGE_LIST_SMALL),
1201 -1,
1202 wxT("List control has an image list, OnGetItemImage or OnGetItemColumnImage should be overridden."));
1203 return -1;
1204 }
1205
1206 int wxListCtrl::OnGetItemColumnImage(long item, long column) const
1207 {
1208 if (!column)
1209 return OnGetItemImage(item);
1210
1211 return -1;
1212 }
1213
1214 wxListItemAttr *wxListCtrl::OnGetItemAttr(long WXUNUSED_UNLESS_DEBUG(item)) const
1215 {
1216 wxASSERT_MSG( item >= 0 && item < GetItemCount(),
1217 _T("invalid item index in OnGetItemAttr()") );
1218
1219 // no attributes by default
1220 return NULL;
1221 }
1222
1223 void wxListCtrl::SetItemCount(long count)
1224 {
1225 wxASSERT_MSG( IsVirtual(), _T("this is for virtual controls only") );
1226
1227 if (m_genericImpl){
1228 m_genericImpl->SetItemCount(count);
1229 return;
1230 }
1231
1232 m_count = count;
1233 }
1234
1235 void wxListCtrl::RefreshItem(long item)
1236 {
1237 if (m_genericImpl){
1238 m_genericImpl->RefreshItem(item);
1239 return;
1240 }
1241
1242 wxRect rect;
1243 GetItemRect(item, rect);
1244 RefreshRect(rect);
1245 }
1246
1247 void wxListCtrl::RefreshItems(long itemFrom, long itemTo)
1248 {
1249 if (m_genericImpl){
1250 m_genericImpl->RefreshItems(itemFrom, itemTo);
1251 return;
1252 }
1253
1254 wxRect rect1, rect2;
1255 GetItemRect(itemFrom, rect1);
1256 GetItemRect(itemTo, rect2);
1257
1258 wxRect rect = rect1;
1259 rect.height = rect2.GetBottom() - rect1.GetTop();
1260
1261 RefreshRect(rect);
1262 }
1263
1264
1265 // wxMac internal data structures
1266
1267 wxMacListCtrlItem::~wxMacListCtrlItem()
1268 {
1269 }
1270
1271 void wxMacListCtrlItem::Notification(wxMacDataItemBrowserControl *owner ,
1272 DataBrowserItemNotification message,
1273 DataBrowserItemDataRef itemData ) const
1274 {
1275
1276 wxMacDataBrowserListCtrlControl *lb = dynamic_cast<wxMacDataBrowserListCtrlControl*>(owner);
1277
1278 // we want to depend on as little as possible to make sure tear-down of controls is safe
1279 if ( message == kDataBrowserItemRemoved)
1280 {
1281 if ( lb != NULL && lb->GetClientDataType() == wxClientData_Object )
1282 {
1283 delete (wxClientData*) (m_data);
1284 }
1285
1286 delete this;
1287 return;
1288 }
1289 else if ( message == kDataBrowserItemAdded )
1290 {
1291 // we don't issue events on adding, the item is not really stored in the list yet, so we
1292 // avoid asserts by gettting out now
1293 return ;
1294 }
1295
1296 wxListCtrl *list = wxDynamicCast( owner->GetPeer() , wxListCtrl );
1297 if ( list ){
1298 bool trigger = false;
1299
1300 wxListEvent event( wxEVT_COMMAND_LIST_ITEM_SELECTED, list->GetId() );
1301 bool isSingle = list->GetWindowStyle() | wxLC_SINGLE_SEL;
1302
1303 event.SetEventObject( list );
1304 event.m_itemIndex = owner->GetLineFromItem( this ) ;
1305 if ( !list->IsVirtual() )
1306 {
1307 lb->MacGetColumnInfo(event.m_itemIndex,0,event.m_item);
1308 }
1309
1310 switch (message)
1311 {
1312 case kDataBrowserItemDeselected:
1313 event.SetEventType(wxEVT_COMMAND_LIST_ITEM_DESELECTED);
1314 if ( !isSingle )
1315 trigger = !lb->IsSelectionSuppressed();
1316 break;
1317
1318 case kDataBrowserItemSelected:
1319 trigger = !lb->IsSelectionSuppressed();
1320 break;
1321
1322 case kDataBrowserItemDoubleClicked:
1323 event.SetEventType( wxEVT_LEFT_DCLICK );
1324 trigger = true;
1325 break;
1326
1327 case kDataBrowserEditStarted :
1328 // TODO : how to veto ?
1329 event.SetEventType( wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT ) ;
1330 trigger = true ;
1331 break ;
1332
1333 case kDataBrowserEditStopped :
1334 // TODO probably trigger only upon the value store callback, because
1335 // here IIRC we cannot veto
1336 event.SetEventType( wxEVT_COMMAND_LIST_END_LABEL_EDIT ) ;
1337 trigger = true ;
1338 break ;
1339
1340 default:
1341 break;
1342 }
1343
1344 if ( trigger )
1345 {
1346 // direct notification is not always having the listbox GetSelection() having in synch with event
1347 wxPostEvent( list->GetEventHandler(), event );
1348 }
1349 }
1350
1351 }
1352
1353 wxMacDataBrowserListCtrlControl::wxMacDataBrowserListCtrlControl( wxWindow *peer, const wxPoint& pos, const wxSize& size, long style)
1354 : wxMacDataItemBrowserControl( peer, pos, size, style )
1355 {
1356 OSStatus err = noErr;
1357 m_clientDataItemsType = wxClientData_None;
1358
1359 DataBrowserSelectionFlags options = kDataBrowserDragSelect;
1360 if ( style & wxLC_SINGLE_SEL )
1361 {
1362 options |= kDataBrowserSelectOnlyOne;
1363 }
1364 else
1365 {
1366 options |= kDataBrowserCmdTogglesSelection;
1367 }
1368
1369 err = SetSelectionFlags( options );
1370 verify_noerr( err );
1371
1372 if ( style & wxLC_LIST ){
1373 InsertColumn(0, kDataBrowserIconAndTextType, wxEmptyString, -1, -1);
1374 verify_noerr( AutoSizeColumns() );
1375 }
1376
1377 if ( style & wxLC_LIST || style & wxLC_NO_HEADER )
1378 verify_noerr( SetHeaderButtonHeight( 0 ) );
1379
1380 SetDataBrowserSortProperty( m_controlRef , kMinColumnId );
1381 if ( style & wxLC_SORT_ASCENDING )
1382 {
1383 m_sortOrder = SortOrder_Text_Ascending;
1384 SetDataBrowserSortProperty( m_controlRef , kMinColumnId );
1385 SetDataBrowserSortOrder( m_controlRef , kDataBrowserOrderIncreasing);
1386 }
1387 else if ( style & wxLC_SORT_DESCENDING )
1388 {
1389 m_sortOrder = SortOrder_Text_Descending;
1390 SetDataBrowserSortProperty( m_controlRef , kMinColumnId );
1391 SetDataBrowserSortOrder( m_controlRef , kDataBrowserOrderDecreasing);
1392 }
1393 else
1394 {
1395 m_sortOrder = SortOrder_None;
1396 SetDataBrowserSortProperty( m_controlRef , kMinColumnId);
1397 SetDataBrowserSortOrder( m_controlRef , kDataBrowserOrderIncreasing);
1398 }
1399
1400 if ( style & wxLC_VRULES ){
1401 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
1402 verify_noerr( DataBrowserChangeAttributes(m_controlRef, kDataBrowserAttributeListViewDrawColumnDividers, kDataBrowserAttributeNone) );
1403 #endif
1404 }
1405
1406 verify_noerr( AutoSizeColumns() );
1407 verify_noerr( SetHiliteStyle(kDataBrowserTableViewFillHilite ) );
1408 err = SetHasScrollBars( (style & wxHSCROLL) != 0 , true );
1409 }
1410
1411 wxMacDataBrowserListCtrlControl::~wxMacDataBrowserListCtrlControl()
1412 {
1413 }
1414
1415 void wxMacDataBrowserListCtrlControl::MacSetColumnInfo( unsigned int row, unsigned int column, wxListItem* item )
1416 {
1417 wxMacDataItem* dataItem = GetItemFromLine(row);
1418 if (item){
1419 wxMacListCtrlItem* listItem = dynamic_cast<wxMacListCtrlItem*>(dataItem);
1420 listItem->SetColumnInfo( column, item );
1421 UpdateState(dataItem, item);
1422 }
1423 }
1424
1425 // apply changes that need to happen immediately, rather than when the
1426 // databrowser control fires a callback.
1427 void wxMacDataBrowserListCtrlControl::UpdateState(wxMacDataItem* dataItem, wxListItem* listItem)
1428 {
1429 bool isSelected = IsItemSelected( dataItem );
1430 bool isSelectedState = (listItem->GetState() == wxLIST_STATE_SELECTED);
1431
1432 // toggle the selection state if wxListInfo state and actual state don't match.
1433 if ( isSelected != isSelectedState ){
1434 DataBrowserSetOption options = kDataBrowserItemsAdd;
1435 if (!isSelectedState)
1436 options = kDataBrowserItemsRemove;
1437 fprintf(stderr, "state = %d, db options = %d\n", isSelectedState, options);
1438 SetSelectedItem(dataItem, options);
1439 }
1440 // TODO: Set column width if item width > than current column width
1441 }
1442
1443 void wxMacDataBrowserListCtrlControl::MacGetColumnInfo( unsigned int row, unsigned int column, wxListItem& item )
1444 {
1445 wxMacDataItem* dataItem = GetItemFromLine(row);
1446 // CS should this guard against dataItem = 0 ? , as item is not a pointer if (item) is not appropriate
1447 //if (item)
1448 {
1449 wxMacListCtrlItem* listItem = dynamic_cast<wxMacListCtrlItem*>(dataItem);
1450 wxListItem* oldItem = listItem->GetColumnInfo( column );
1451
1452 long mask = item.GetMask();
1453 if ( !mask )
1454 // by default, get everything for backwards compatibility
1455 mask = -1;
1456
1457 if ( mask & wxLIST_MASK_TEXT )
1458 item.SetText(oldItem->GetText());
1459 if ( mask & wxLIST_MASK_IMAGE )
1460 item.SetImage(oldItem->GetImage());
1461 if ( mask & wxLIST_MASK_DATA )
1462 item.SetData(oldItem->GetData());
1463 if ( mask & wxLIST_MASK_STATE )
1464 item.SetState(oldItem->GetState());
1465 if ( mask & wxLIST_MASK_WIDTH )
1466 item.SetWidth(oldItem->GetWidth());
1467 if ( mask & wxLIST_MASK_FORMAT )
1468 item.SetAlign(oldItem->GetAlign());
1469
1470 item.SetTextColour(oldItem->GetTextColour());
1471 item.SetBackgroundColour(oldItem->GetBackgroundColour());
1472 item.SetFont(oldItem->GetFont());
1473 }
1474 }
1475
1476 void wxMacDataBrowserListCtrlControl::MacInsertItem( unsigned int n, wxListItem* item )
1477 {
1478 wxMacDataItemBrowserControl::MacInsert(n, item->GetText());
1479 MacSetColumnInfo(n, 0, item);
1480 }
1481
1482 wxMacListCtrlItem* wxMacDataBrowserListCtrlControl::CreateItem()
1483 {
1484 return new wxMacListCtrlItem();
1485 }
1486
1487 wxMacListCtrlItem::wxMacListCtrlItem()
1488 {
1489 m_rowItems = wxListItemList();
1490 }
1491
1492 int wxMacListCtrlItem::GetColumnImageValue( unsigned int column )
1493 {
1494 return GetColumnInfo(column)->GetImage();
1495 }
1496
1497 void wxMacListCtrlItem::SetColumnImageValue( unsigned int column, int imageIndex )
1498 {
1499 GetColumnInfo(column)->SetImage(imageIndex);
1500 }
1501
1502 const wxString& wxMacListCtrlItem::GetColumnTextValue( unsigned int column )
1503 {
1504 if ( column == 0 )
1505 return GetLabel();
1506
1507 return GetColumnInfo(column)->GetText();
1508 }
1509
1510 void wxMacListCtrlItem::SetColumnTextValue( unsigned int column, const wxString& text )
1511 {
1512 GetColumnInfo(column)->SetText(text);
1513
1514 // for compatibility with superclass APIs
1515 if ( column == 0 )
1516 SetLabel(text);
1517 }
1518
1519 wxListItem* wxMacListCtrlItem::GetColumnInfo( unsigned int column )
1520 {
1521 wxListItemList::compatibility_iterator node = m_rowItems.Item( column );
1522 wxASSERT_MSG( node, _T("invalid column index in wxMacListCtrlItem") );
1523
1524 return node->GetData();
1525 }
1526
1527 bool wxMacListCtrlItem::HasColumnInfo( unsigned int column )
1528 {
1529 return m_rowItems.GetCount() > column;
1530 }
1531
1532 void wxMacListCtrlItem::SetColumnInfo( unsigned int column, wxListItem* item )
1533 {
1534
1535 if ( column >= m_rowItems.GetCount() ){
1536 wxListItem* listItem = new wxListItem(*item);
1537 //listItem->SetAlign(item->GetAlign());
1538 //listItem->SetBackgroundColour(item->GetBackgroundColour());
1539 //listItem->SetColumn(item->GetColumn());
1540 //listItem->SetData(item->GetData());
1541 //listItem->SetFont(item->GetFont());
1542 //listItem->SetId(GetOrder());
1543 //listItem->SetImage(item->GetImage());
1544 //listItem->SetMask(item->GetMask());
1545
1546 //listItem->SetText(item->GetText());
1547 m_rowItems.Append( listItem );
1548 }
1549 else{
1550 wxListItem* listItem = GetColumnInfo( column );
1551 long mask = item->GetMask();
1552 if (mask & wxLIST_MASK_TEXT)
1553 listItem->SetText(item->GetText());
1554 if (mask & wxLIST_MASK_DATA)
1555 listItem->SetData(item->GetData());
1556 if (mask & wxLIST_MASK_IMAGE)
1557 listItem->SetImage(item->GetImage());
1558 if (mask & wxLIST_MASK_STATE)
1559 listItem->SetState(item->GetState());
1560 if (mask & wxLIST_MASK_FORMAT)
1561 listItem->SetAlign(item->GetAlign());
1562 if (mask & wxLIST_MASK_WIDTH)
1563 listItem->SetWidth(item->GetWidth());
1564 }
1565 }
1566
1567 OSStatus wxMacListCtrlItem::GetSetData( wxMacDataItemBrowserControl *owner ,
1568 DataBrowserPropertyID property,
1569 DataBrowserItemDataRef itemData,
1570 bool changeValue )
1571 {
1572
1573 OSStatus err = errDataBrowserPropertyNotSupported;
1574 wxListCtrl* list = wxDynamicCast( owner->GetPeer() , wxListCtrl );
1575 if ( !changeValue )
1576 {
1577 switch (property)
1578 {
1579 case kDataBrowserItemIsEditableProperty :
1580 if ( list && list->HasFlag( wxLC_EDIT_LABELS ) )
1581 {
1582 verify_noerr(SetDataBrowserItemDataBooleanValue( itemData, true ));
1583 err = noErr ;
1584 }
1585 break ;
1586 default :
1587 if ( property >= kMinColumnId ){
1588 short listColumn = property - kMinColumnId;
1589
1590 if (HasColumnInfo(listColumn)){
1591 wxListItem* item = GetColumnInfo(listColumn);
1592 wxMacCFStringHolder cfStr;
1593
1594 if (item->GetText()){
1595 cfStr.Assign( item->GetText(), wxLocale::GetSystemEncoding() );
1596 err = ::SetDataBrowserItemDataText( itemData, cfStr );
1597 err = noErr;
1598 }
1599
1600 int imgIndex = item->GetImage();
1601 if ( (item->GetMask() & wxLIST_MASK_IMAGE) ){
1602 wxImageList* imageList = list->GetImageList(wxIMAGE_LIST_SMALL);
1603 if (imageList && imageList->GetImageCount() > 0){
1604 wxBitmap bmp = imageList->GetBitmap(imgIndex);
1605 IconRef icon = bmp.GetBitmapData()->GetIconRef();
1606 ::SetDataBrowserItemDataIcon(itemData, icon);
1607 }
1608 }
1609
1610 }
1611 }
1612 break ;
1613 }
1614 }
1615 else
1616 {
1617 switch (property)
1618 {
1619 default:
1620 if ( property >= kMinColumnId ){
1621 short listColumn = property - kMinColumnId;
1622
1623 if (HasColumnInfo(listColumn)){
1624 // TODO probably send the 'end edit' from here, as we
1625 // can then deal with the veto
1626 CFStringRef sr ;
1627 verify_noerr( GetDataBrowserItemDataText( itemData , &sr ) ) ;
1628 wxMacCFStringHolder cfStr(sr) ;;
1629 list->SetItem( owner->GetLineFromItem(this) , listColumn, cfStr.AsString() ) ;
1630 err = noErr ;
1631 }
1632 }
1633 break;
1634 }
1635 }
1636
1637 // don't duplicate the numeric order column handling
1638 if (err == errDataBrowserPropertyNotSupported)
1639 err = wxMacDataItem::GetSetData(owner, property, itemData, changeValue);
1640
1641 return err;
1642 }
1643
1644 #endif // wxUSE_LISTCTRL