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