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