]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/dataview.cpp
mac cgcolor changes & cleanup
[wxWidgets.git] / src / mac / carbon / dataview.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/mac/carbon/datavgen.cpp
3 // Purpose: wxDataViewCtrl native mac implementation
4 // Author:
5 // Id: $Id$
6 // Copyright: (c) 2007
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9
10 // For compilers that support precompilation, includes "wx.h".
11 #include "wx/wxprec.h"
12
13 #if wxUSE_DATAVIEWCTRL
14
15 #include "wx/dataview.h"
16
17 #if !defined(wxUSE_GENERICDATAVIEWCTRL) || (wxUSE_GENERICDATAVIEWCTRL == 0)
18
19 #include <limits>
20
21 #include "wx/mac/carbon/databrow.h"
22
23 #ifndef WX_PRECOMP
24 #include "wx/timer.h"
25 #include "wx/settings.h"
26 #include "wx/dcclient.h"
27 #include "wx/icon.h"
28 #endif
29
30 #include "wx/renderer.h"
31
32 //-----------------------------------------------------------------------------
33 // local constants
34 //-----------------------------------------------------------------------------
35
36 // a list of all catchable events:
37 static EventTypeSpec const eventList[] =
38 {
39 {kEventClassControl, kEventControlDraw},
40 {kEventClassControl, kEventControlHit}
41 };
42
43 //-----------------------------------------------------------------------------
44 // local functions
45 //-----------------------------------------------------------------------------
46
47 static pascal OSStatus wxMacDataViewCtrlEventHandler(EventHandlerCallRef handler, EventRef EventReference, void* Data)
48 {
49 wxDataViewCtrl* DataViewCtrlPtr((wxDataViewCtrl*) Data); // the 'Data' variable always contains a pointer to the data view control that installed the handler
50
51 wxMacCarbonEvent CarbonEvent(EventReference) ;
52
53
54 switch (GetEventKind(EventReference))
55 {
56 case kEventControlDraw:
57 {
58 OSStatus status;
59
60 DataViewCtrlPtr->MacSetDrawingContext(CarbonEvent.GetParameter<CGContextRef>(kEventParamCGContextRef,typeCGContextRef));
61 status = ::CallNextEventHandler(handler,EventReference);
62 DataViewCtrlPtr->MacSetDrawingContext(NULL);
63 return status;
64 } /* block */
65 case kEventControlHit :
66 if (CarbonEvent.GetParameter<ControlPartCode>(kEventParamControlPart,typeControlPartCode) == kControlButtonPart) // we only care about the header
67 {
68 ControlRef controlReference;
69 DataBrowserPropertyID columnPropertyID;
70 unsigned long columnIndex;
71 OSStatus status;
72 wxDataViewEvent DataViewEvent(wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK,DataViewCtrlPtr->GetId());
73
74 CarbonEvent.GetParameter(kEventParamDirectObject,&controlReference);
75 // determine the column that triggered the event (this is the column that is responsible for sorting the data view):
76 status = ::GetDataBrowserSortProperty(controlReference,&columnPropertyID);
77 wxCHECK(status == noErr,status);
78 status = ::GetDataBrowserTableViewColumnPosition(controlReference,columnPropertyID,&columnIndex);
79 if (status == errDataBrowserPropertyNotFound) // user clicked into part of the header that does not have a property
80 return ::CallNextEventHandler(handler,EventReference);
81 wxCHECK(status == noErr,status);
82 // initialize wxWidget event handler:
83 DataViewEvent.SetEventObject(DataViewCtrlPtr);
84 DataViewEvent.SetColumn(columnIndex);
85 DataViewEvent.SetDataViewColumn(DataViewCtrlPtr->GetColumn(columnIndex));
86 // finally sent the equivalent wxWidget event:
87 DataViewCtrlPtr->GetEventHandler()->ProcessEvent(DataViewEvent);
88 return ::CallNextEventHandler(handler,EventReference);
89 } /* if */
90 else
91 return eventNotHandledErr;
92 } /* switch */
93
94 return eventNotHandledErr;
95 } /* wxMacDataViewCtrlEventHandler(EventHandlerCallRef, EventRef, void*) */
96
97 static DataBrowserItemID* CreateDataBrowserItemIDArray(size_t& noOfEntries, wxDataViewItemArray const& items) // returns a newly allocated pointer to valid data browser item IDs
98 {
99 size_t const noOfItems = items.GetCount();
100
101 DataBrowserItemID* itemIDs(new DataBrowserItemID[noOfItems]);
102
103
104 // convert all valid data view items to data browser items
105 noOfEntries = 0;
106 for (size_t i=0; i<noOfItems; ++i)
107 if (items[i].IsOk())
108 {
109 itemIDs[noOfEntries] = reinterpret_cast<DataBrowserItemID>(items[i].GetID());
110 ++noOfEntries;
111 } /* if */
112 // done:
113 return itemIDs;
114 } /* CreateDataBrowserItemIDArray(size_t&, wxDataViewItemArray const&) */
115
116 static bool InitializeColumnDescription(DataBrowserListViewColumnDesc& columnDescription, wxDataViewColumn const* columnPtr, DataBrowserPropertyID columnPropertyID, wxMacCFStringHolder const& title)
117 {
118 // set properties for the column:
119 columnDescription.propertyDesc.propertyID = columnPropertyID;
120 columnDescription.propertyDesc.propertyType = columnPtr->GetRenderer()->GetPropertyType();
121 columnDescription.propertyDesc.propertyFlags = kDataBrowserListViewSelectionColumn; // make the column selectable
122 if (columnPtr->IsSortable())
123 columnDescription.propertyDesc.propertyFlags |= kDataBrowserListViewSortableColumn;
124 #if 0
125 if (columnPtr->IsMovable())
126 columnDescription.propertyDesc.propertyFlags |= kDataBrowserListViewMovableColumn;
127 #endif
128 if (columnPtr->GetRenderer()->GetMode() == wxDATAVIEW_CELL_EDITABLE)
129 columnDescription.propertyDesc.propertyFlags |= kDataBrowserPropertyIsEditable;
130 if ((columnDescription.propertyDesc.propertyType == kDataBrowserTextType) ||
131 (columnDescription.propertyDesc.propertyType == kDataBrowserIconAndTextType) ||
132 (columnDescription.propertyDesc.propertyType == kDataBrowserDateTimeType))
133 columnDescription.propertyDesc.propertyFlags |= kDataBrowserListViewTypeSelectColumn; // enables generally the possibility to have user input for the mentioned types
134 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
135 columnDescription.propertyDesc.propertyFlags |= kDataBrowserListViewNoGapForIconInHeaderButton;
136 #endif
137 // set header's properties:
138 columnDescription.headerBtnDesc.version = kDataBrowserListViewLatestHeaderDesc;
139 if (columnPtr->IsResizeable())
140 {
141 columnDescription.headerBtnDesc.minimumWidth = 0;
142 columnDescription.headerBtnDesc.maximumWidth = 30000; // 32767 is the theoretical maximum though but 30000 looks nicer
143 } /* if */
144 else
145 {
146 columnDescription.headerBtnDesc.minimumWidth = columnPtr->GetWidth();
147 columnDescription.headerBtnDesc.maximumWidth = columnPtr->GetWidth();
148 } /* if */
149 columnDescription.headerBtnDesc.titleOffset = 0;
150 columnDescription.headerBtnDesc.titleString = ::CFStringCreateCopy(kCFAllocatorDefault,title);
151 columnDescription.headerBtnDesc.initialOrder = kDataBrowserOrderIncreasing; // choose one of the orders as "undefined" is not supported anyway (s. ControlDefs.h in the HIToolbox framework)
152 columnDescription.headerBtnDesc.btnFontStyle.flags = kControlUseFontMask | kControlUseJustMask;
153 switch (columnPtr->GetAlignment())
154 {
155 case wxALIGN_CENTER:
156 case wxALIGN_CENTER_HORIZONTAL:
157 columnDescription.headerBtnDesc.btnFontStyle.just = teCenter;
158 break;
159 case wxALIGN_LEFT:
160 columnDescription.headerBtnDesc.btnFontStyle.just = teFlushLeft;
161 break;
162 case wxALIGN_RIGHT:
163 columnDescription.headerBtnDesc.btnFontStyle.just = teFlushRight;
164 break;
165 default:
166 columnDescription.headerBtnDesc.btnFontStyle.just = teFlushDefault;
167 } /* switch */
168 columnDescription.headerBtnDesc.btnFontStyle.font = kControlFontViewSystemFont;
169 columnDescription.headerBtnDesc.btnFontStyle.style = normal;
170 columnDescription.headerBtnDesc.btnContentInfo.contentType = kControlContentIconRef;
171 if (columnPtr->GetBitmap().Ok())
172 columnDescription.headerBtnDesc.btnContentInfo.u.iconRef = columnPtr->GetBitmap().GetBitmapData()->GetIconRef();
173 // done:
174 return true;
175 } /* InitializeColumnDescription(DataBrowserListViewColumnDesc&, wxDataViewColumn const*, DataBrowserPropertyID, wxMacCFStringHolder const&) */
176
177 //-----------------------------------------------------------------------------
178 // local function pointers
179 //-----------------------------------------------------------------------------
180
181 DEFINE_ONE_SHOT_HANDLER_GETTER(wxMacDataViewCtrlEventHandler)
182
183 // ---------------------------------------------------------
184 // wxMacDataViewModelNotifier
185 // ---------------------------------------------------------
186 #pragma mark -
187 class wxMacDataViewModelNotifier : public wxDataViewModelNotifier
188 {
189 public:
190 wxMacDataViewModelNotifier(wxMacDataViewDataBrowserListViewControl* initDataViewControlPtr) : m_dataViewControlPtr(initDataViewControlPtr)
191 {
192 }
193
194 virtual bool ItemAdded(const wxDataViewItem &parent, const wxDataViewItem &item)
195 {
196 DataBrowserItemID itemID(reinterpret_cast<DataBrowserItemID>(item.GetID()));
197
198
199 wxCHECK_MSG(item.IsOk(),false,_("Added item is invalid."));
200 return (!(parent.IsOk()) && (this->m_dataViewControlPtr->AddItem(kDataBrowserNoItem,&itemID) == noErr) ||
201 parent.IsOk() && (this->m_dataViewControlPtr->AddItem(reinterpret_cast<DataBrowserItemID>(parent.GetID()),&itemID) == noErr));
202 } /* ItemAdded(wxDataViewItem const&, wxDataViewItem const&) */
203
204 virtual bool ItemsAdded(wxDataViewItem const& parent, wxDataViewItemArray const& items)
205 {
206 bool noFailureFlag;
207
208 DataBrowserItemID* itemIDs;
209
210 size_t noOfEntries;
211
212
213 // convert all valid data view items to data browser items:
214 itemIDs = ::CreateDataBrowserItemIDArray(noOfEntries,items);
215 // insert all valid items into control:
216 noFailureFlag = ((noOfEntries == 0) ||
217 !(parent.IsOk()) && (this->m_dataViewControlPtr->AddItems(kDataBrowserNoItem,noOfEntries,itemIDs,kDataBrowserItemNoProperty) == noErr) ||
218 parent.IsOk() && (this->m_dataViewControlPtr->AddItems(reinterpret_cast<DataBrowserItemID>(parent.GetID()),noOfEntries,itemIDs,kDataBrowserItemNoProperty) == noErr));
219 // give allocated array space free again:
220 delete[] itemIDs;
221 // done:
222 return noFailureFlag;
223 } /* ItemsAdded(wxDataViewItem const&, wxDataViewItemArray const&) */
224
225 virtual bool ItemChanged(wxDataViewItem const& item)
226 {
227 DataBrowserItemID itemID(reinterpret_cast<DataBrowserItemID>(item.GetID()));
228
229
230 wxCHECK_MSG(item.IsOk(),false,_("Changed item is invalid."));
231 if (this->m_dataViewControlPtr->UpdateItems(&itemID) == noErr)
232 {
233 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->m_dataViewControlPtr->GetPeer()));
234
235 // sent the equivalent wxWidget event:
236 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_VALUE_CHANGED,dataViewCtrlPtr->GetId()); // variable defintion
237
238 dataViewEvent.SetEventObject(dataViewCtrlPtr);
239 dataViewEvent.SetItem(item);
240 // sent the equivalent wxWidget event:
241 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
242 // done
243 return true;
244 } /* if */
245 else
246 return false;
247 } /* ItemChanged(wxDataViewItem const&) */
248
249 virtual bool ItemsChanged(wxDataViewItemArray const& items)
250 {
251 bool noFailureFlag;
252
253 DataBrowserItemID* itemIDs;
254
255 size_t noOfEntries;
256
257
258 // convert all valid data view items to data browser items:
259 itemIDs = ::CreateDataBrowserItemIDArray(noOfEntries,items);
260 // change items (ATTENTION: ONLY ITEMS OF THE ROOT ARE CHANGED BECAUSE THE PARENT PARAMETER IS MISSING):
261 noFailureFlag = (this->m_dataViewControlPtr->UpdateItems(kDataBrowserNoItem,noOfEntries,itemIDs,kDataBrowserItemNoProperty,kDataBrowserItemNoProperty) == noErr);
262 if (noFailureFlag)
263 {
264 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->m_dataViewControlPtr->GetPeer()));
265
266 // send for all changed items a wxWidget event:
267 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_VALUE_CHANGED,dataViewCtrlPtr->GetId()); // variable defintion
268
269 dataViewEvent.SetEventObject(dataViewCtrlPtr);
270 for (size_t i=0; i<noOfEntries; ++i)
271 {
272 dataViewEvent.SetItem(reinterpret_cast<void*>(itemIDs[i]));
273 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
274 } /* for */
275 } /* if */
276 // release allocated array space:
277 delete[] itemIDs;
278 // done:
279 return noFailureFlag;
280 } /* ItemsChanged(wxDataViewItem const&) */
281
282 virtual bool ItemDeleted(wxDataViewItem const& parent, wxDataViewItem const& item)
283 {
284 if (item.IsOk())
285 {
286 // variable definition and initialization:
287 DataBrowserItemID itemID(reinterpret_cast<DataBrowserItemID>(item.GetID()));
288 OSStatus errorStatus;
289 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->m_dataViewControlPtr->GetPeer()));
290
291 // when this method is called and currently an item is being edited this item may have already been deleted in the model (the passed item and the being edited item have
292 // not to be identical because the being edited item might be below the passed item in the hierarchy);
293 // to prevent the control trying to ask the model to update an already deleted item the control is informed that currently a deleting process
294 // has been started and that variables can currently not be updated even when requested by the system:
295 dataViewCtrlPtr->SetDeleting(true);
296 errorStatus = this->m_dataViewControlPtr->RemoveItem(reinterpret_cast<DataBrowserItemID>(parent.GetID()),&itemID);
297 // enable automatic updating again:
298 dataViewCtrlPtr->SetDeleting(false);
299 return (errorStatus == noErr);
300 } /* if */
301 else
302 return false;
303 } /* ItemDeleted(wxDataViewItem const&, wxDataViewItem const&) */
304
305 virtual bool ItemsDeleted(wxDataViewItem const& parent, wxDataViewItemArray const& items)
306 {
307 bool noFailureFlag;
308
309 DataBrowserItemID* itemIDs;
310
311 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->m_dataViewControlPtr->GetPeer()));
312
313 size_t noOfEntries;
314
315
316 wxCHECK_MSG(dataViewCtrlPtr != NULL,false,_("Data view control is not correctly initialized"));
317 // convert all valid data view items to data browser items:
318 itemIDs = ::CreateDataBrowserItemIDArray(noOfEntries,items);
319 // when this method is called and currently an item is being edited this item may have already been deleted in the model (the passed item and the being edited item have
320 // not to be identical because the being edited item might be below the passed item in the hierarchy);
321 // to prevent the control trying to ask the model to update an already deleted item the control is informed that currently a deleting process
322 // has been started and that variables can currently not be updated even when requested by the system:
323 dataViewCtrlPtr->SetDeleting(true);
324 // insert all valid items into control:
325 noFailureFlag = ((noOfEntries == 0) ||
326 !(parent.IsOk()) && (this->m_dataViewControlPtr->RemoveItems(kDataBrowserNoItem,noOfEntries,itemIDs,kDataBrowserItemNoProperty) == noErr) ||
327 parent.IsOk() && (this->m_dataViewControlPtr->RemoveItems(reinterpret_cast<DataBrowserItemID>(parent.GetID()),noOfEntries,itemIDs,kDataBrowserItemNoProperty) == noErr));
328 // enable automatic updating again:
329 dataViewCtrlPtr->SetDeleting(false);
330 // give allocated array space free again:
331 delete[] itemIDs;
332 // done:
333 return noFailureFlag;
334 } /* ItemsDeleted(wxDataViewItem const&, wxDataViewItemArray const&) */
335
336 virtual bool ValueChanged(wxDataViewItem const& item, unsigned int col)
337 {
338 DataBrowserItemID itemID(reinterpret_cast<DataBrowserItemID>(item.GetID()));
339 DataBrowserItemID parentID;
340
341 DataBrowserPropertyID propertyID;
342
343 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->m_dataViewControlPtr->GetPeer()));
344
345
346 wxCHECK_MSG(item.IsOk(), false,_("Passed item is invalid."));
347 wxCHECK_MSG(this->GetOwner() != NULL,false,_("Owner not initialized."));
348 wxCHECK_MSG(dataViewCtrlPtr != NULL, false,_("Control is wrongly initialized."));
349 parentID = reinterpret_cast<DataBrowserItemID>(this->GetOwner()->GetParent(item).GetID());
350 if ((this->m_dataViewControlPtr->GetPropertyID(col,&propertyID) == noErr) &&
351 (this->m_dataViewControlPtr->UpdateItems(parentID,1,&itemID,dataViewCtrlPtr->GetColumn(col)->GetPropertyID(),propertyID) == noErr))
352 {
353 // variable definition and initialization:
354 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_VALUE_CHANGED,dataViewCtrlPtr->GetId());
355
356 dataViewEvent.SetEventObject(dataViewCtrlPtr);
357 dataViewEvent.SetColumn(col);
358 dataViewEvent.SetItem(item);
359 // send the equivalent wxWidget event:
360 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
361 // done
362 return true;
363 } /* if */
364 else
365 return false;
366 } /* ValueChanged(wxDataViewItem const&, unsigned int) */
367
368 virtual bool Cleared(void)
369 {
370 return (this->m_dataViewControlPtr->RemoveItems() == noErr);
371 } /* Cleared(void) */
372
373 virtual void Resort(void)
374 {
375 this->m_dataViewControlPtr->Resort();
376 }
377
378 protected:
379 private:
380 //
381 // variables
382 //
383 wxMacDataViewDataBrowserListViewControl* m_dataViewControlPtr;
384 };
385
386 // ---------------------------------------------------------
387 // wxDataViewRenderer
388 // ---------------------------------------------------------
389 #pragma mark -
390 wxDataViewRenderer::wxDataViewRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align)
391 :wxDataViewRendererBase(varianttype,mode,align), m_alignment(align), m_mode(mode)
392 {
393 } /* wxDataViewRenderer::wxDataViewRenderer(wxString const&, wxDataViewCellMode) */
394
395 void wxDataViewRenderer::SetMode(wxDataViewCellMode mode)
396 {
397 wxDataViewColumn* dataViewColumnPtr;
398
399
400 this->m_mode = mode;
401 dataViewColumnPtr = this->GetOwner();
402 if (dataViewColumnPtr != NULL)
403 {
404 // variable definition and initialization:
405 wxDataViewCtrl* dataViewCtrlPtr(dataViewColumnPtr->GetOwner());
406
407 if (dataViewCtrlPtr != NULL)
408 {
409 // variable definition and initialization:
410 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
411
412 if (macDataViewListCtrlPtr != NULL)
413 {
414 // variable definition and initialization:
415 DataBrowserPropertyFlags flags;
416
417 verify_noerr(macDataViewListCtrlPtr->GetPropertyFlags(dataViewColumnPtr->GetPropertyID(),&flags));
418 if (mode == wxDATAVIEW_CELL_EDITABLE)
419 flags |= kDataBrowserPropertyIsEditable;
420 else
421 flags &= ~kDataBrowserPropertyIsEditable;
422 verify_noerr(macDataViewListCtrlPtr->SetPropertyFlags(dataViewColumnPtr->GetPropertyID(),flags));
423 } /* if */
424 } /* if */
425 } /* if */
426 } /* wxDataViewRenderer::SetMode(wxDataViewCellMode) */
427
428 IMPLEMENT_ABSTRACT_CLASS(wxDataViewRenderer,wxDataViewRendererBase)
429
430 // ---------------------------------------------------------
431 // wxDataViewCustomRenderer
432 // ---------------------------------------------------------
433 #pragma mark -
434 wxDataViewCustomRenderer::wxDataViewCustomRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align)
435 :wxDataViewRenderer(varianttype,mode,align), m_editorCtrlPtr(NULL), m_DCPtr(NULL)
436 {
437 } /* wxDataViewCustomRenderer::wxDataViewCustomRenderer(wxString const&, wxDataViewCellMode) */
438
439 wxDataViewCustomRenderer::~wxDataViewCustomRenderer(void)
440 {
441 if (this->m_DCPtr != NULL)
442 delete this->m_DCPtr;
443 } /* wxDataViewCustomRenderer::~wxDataViewCustomRenderer(void) */
444
445 void wxDataViewCustomRenderer::RenderText( const wxString &text, int xoffset, wxRect cell, wxDC *dc, int state )
446 {
447 wxDataViewCtrl *view = GetOwner()->GetOwner();
448 wxColour col = (state & wxDATAVIEW_CELL_SELECTED) ? wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT) : view->GetForegroundColour();
449 dc->SetTextForeground(col);
450 dc->DrawText( text, cell.x + xoffset, cell.y + ((cell.height - dc->GetCharHeight()) / 2));
451 }
452
453 wxDC* wxDataViewCustomRenderer::GetDC(void)
454 {
455 if (this->m_DCPtr == NULL)
456 {
457 if ((GetOwner() == NULL) || (GetOwner()->GetOwner() == NULL))
458 return NULL;
459 this->m_DCPtr = new wxClientDC(this->GetOwner()->GetOwner());
460 } /* if */
461 return this->m_DCPtr;
462 } /* wxDataViewCustomRenderer::GetDC(void) */
463
464 bool wxDataViewCustomRenderer::Render(void)
465 {
466 return true;
467 } /* wxDataViewCustomRenderer::Render(void) */
468
469 void wxDataViewCustomRenderer::SetDC(wxDC* newDCPtr)
470 {
471 delete this->m_DCPtr;
472 this->m_DCPtr = newDCPtr;
473 } /* wxDataViewCustomRenderer::SetDC(wxDC*) */
474
475 WXDataBrowserPropertyType wxDataViewCustomRenderer::GetPropertyType(void) const
476 {
477 return kDataBrowserCustomType;
478 } /* wxDataViewCustomRenderer::GetPropertyType(void) const */
479
480 IMPLEMENT_ABSTRACT_CLASS(wxDataViewCustomRenderer, wxDataViewRenderer)
481
482 // ---------------------------------------------------------
483 // wxDataViewTextRenderer
484 // ---------------------------------------------------------
485 #pragma mark -
486 wxDataViewTextRenderer::wxDataViewTextRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align)
487 :wxDataViewRenderer(varianttype,mode,align)
488 {
489 } /* wxDataViewTextRenderer::wxDataViewTextRenderer(wxString const&, wxDataViewCellMode, int) */
490
491 bool wxDataViewTextRenderer::Render(void)
492 {
493 if (this->GetValue().GetType() == this->GetVariantType())
494 {
495 // variable definition:
496 wxMacCFStringHolder cfString(this->GetValue().GetString(),(this->GetView()->GetFont().Ok() ? this->GetView()->GetFont().GetEncoding() : wxLocale::GetSystemEncoding()));
497
498 return (::SetDataBrowserItemDataText(this->GetDataReference(),cfString) == noErr);
499 } /* if */
500 else
501 return false;
502 } /* wxDataViewTextRenderer::Render(void) */
503
504 WXDataBrowserPropertyType wxDataViewTextRenderer::GetPropertyType(void) const
505 {
506 return kDataBrowserTextType;
507 } /* wxDataViewTextRenderer::GetPropertyType(void) const */
508
509 IMPLEMENT_CLASS(wxDataViewTextRenderer,wxDataViewRenderer)
510
511 // ---------------------------------------------------------
512 // wxDataViewTextRendererAttr
513 // ---------------------------------------------------------
514 #pragma mark -
515 wxDataViewTextRendererAttr::wxDataViewTextRendererAttr(wxString const& varianttype, wxDataViewCellMode mode, int align)
516 :wxDataViewTextRenderer(varianttype,mode,align)
517 {
518 } /* wxDataViewTextRendererAttr::wxDataViewTextRendererAttr(wxString const&, wxDataViewCellMode, int) */
519
520 IMPLEMENT_CLASS(wxDataViewTextRendererAttr,wxDataViewTextRenderer)
521
522 // ---------------------------------------------------------
523 // wxDataViewBitmapRenderer
524 // ---------------------------------------------------------
525 #pragma mark -
526 wxDataViewBitmapRenderer::wxDataViewBitmapRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align)
527 :wxDataViewRenderer(varianttype,mode,align)
528 {
529 }
530
531 bool wxDataViewBitmapRenderer::Render(void)
532 {
533 if (this->GetValue().GetType() == this->GetVariantType())
534 {
535 wxBitmap bitmap;
536
537 bitmap << this->GetValue();
538 if (bitmap.Ok())
539 return (::SetDataBrowserItemDataIcon(this->GetDataReference(),bitmap.GetBitmapData()->GetIconRef()) == noErr);
540 else
541 return true;
542 } /* if */
543 else
544 return false;
545 } /* wxDataViewBitmapRenderer::Render(void) */
546
547 WXDataBrowserPropertyType wxDataViewBitmapRenderer::GetPropertyType(void) const
548 {
549 return kDataBrowserIconType;
550 } /* wxDataViewBitmapRenderer::GetPropertyType(void) const */
551
552 IMPLEMENT_CLASS(wxDataViewBitmapRenderer,wxDataViewRenderer)
553
554 // ---------------------------------------------------------
555 // wxDataViewIconTextRenderer
556 // ---------------------------------------------------------
557 #pragma mark -
558 wxDataViewIconTextRenderer::wxDataViewIconTextRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align)
559 :wxDataViewRenderer(varianttype,mode)
560 {
561 }
562
563 bool wxDataViewIconTextRenderer::Render(void)
564 {
565 if (this->GetValue().GetType() == this->GetVariantType())
566 {
567 // variable definition:
568 wxDataViewIconText iconText;
569
570 iconText << this->GetValue();
571
572 // variable definition:
573 wxMacCFStringHolder cfString(iconText.GetText(),(this->GetView()->GetFont().Ok() ? this->GetView()->GetFont().GetEncoding() : wxLocale::GetSystemEncoding()));
574
575 return ((::SetDataBrowserItemDataIcon(this->GetDataReference(),MAC_WXHICON(iconText.GetIcon().GetHICON())) == noErr) &&
576 (::SetDataBrowserItemDataText(this->GetDataReference(),cfString) == noErr));
577 } /* if */
578 else
579 return false;
580 } /* wxDataViewIconTextRenderer::Render(void) */
581
582 WXDataBrowserPropertyType wxDataViewIconTextRenderer::GetPropertyType(void) const
583 {
584 return kDataBrowserIconAndTextType;
585 } /* wxDataViewIconTextRenderer::GetPropertyType(void) const */
586
587 IMPLEMENT_ABSTRACT_CLASS(wxDataViewIconTextRenderer,wxDataViewRenderer)
588
589
590 // ---------------------------------------------------------
591 // wxDataViewToggleRenderer
592 // ---------------------------------------------------------
593 #pragma mark -
594 wxDataViewToggleRenderer::wxDataViewToggleRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align)
595 :wxDataViewRenderer(varianttype,mode)
596 {
597 }
598
599 bool wxDataViewToggleRenderer::Render(void)
600 {
601 if (this->GetValue().GetType() == this->GetVariantType())
602 return (::SetDataBrowserItemDataButtonValue(this->GetDataReference(),this->GetValue().GetBool()) == noErr);
603 else
604 return false;
605 } /* wxDataViewToggleRenderer::Render(void) */
606
607 WXDataBrowserPropertyType wxDataViewToggleRenderer::GetPropertyType(void) const
608 {
609 return kDataBrowserCheckboxType;
610 } /* wxDataViewToggleRenderer::GetPropertyType(void) const */
611
612 IMPLEMENT_ABSTRACT_CLASS(wxDataViewToggleRenderer,wxDataViewRenderer)
613
614 // ---------------------------------------------------------
615 // wxDataViewProgressRenderer
616 // ---------------------------------------------------------
617 #pragma mark -
618 wxDataViewProgressRenderer::wxDataViewProgressRenderer(wxString const& label, wxString const& varianttype, wxDataViewCellMode mode, int align)
619 :wxDataViewRenderer(varianttype,mode,align)
620 {
621 }
622
623 bool wxDataViewProgressRenderer::Render(void)
624 {
625 if (this->GetValue().GetType() == this->GetVariantType())
626 return ((::SetDataBrowserItemDataMinimum(this->GetDataReference(), 0) == noErr) &&
627 (::SetDataBrowserItemDataMaximum(this->GetDataReference(),100) == noErr) &&
628 (::SetDataBrowserItemDataValue (this->GetDataReference(),this->GetValue().GetLong()) == noErr));
629 else
630 return false;
631 } /* wxDataViewProgressRenderer::Render(void) */
632
633 WXDataBrowserPropertyType wxDataViewProgressRenderer::GetPropertyType(void) const
634 {
635 return kDataBrowserProgressBarType;
636 } /* wxDataViewProgressRenderer::GetPropertyType(void) const */
637
638 IMPLEMENT_ABSTRACT_CLASS(wxDataViewProgressRenderer,wxDataViewRenderer)
639
640 // ---------------------------------------------------------
641 // wxDataViewDateRenderer
642 // ---------------------------------------------------------
643 #pragma mark -
644 wxDataViewDateRenderer::wxDataViewDateRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align)
645 :wxDataViewRenderer(varianttype,mode,align)
646 {
647 }
648
649 bool wxDataViewDateRenderer::Render(void)
650 {
651 if (this->GetValue().GetType() == this->GetVariantType())
652 return (::SetDataBrowserItemDataDateTime(this->GetDataReference(),this->GetValue().GetDateTime().Subtract(wxDateTime(1,wxDateTime::Jan,1904)).GetSeconds().GetLo()) == noErr);
653 else
654 return false;
655 } /* wxDataViewDateRenderer::Render(void) */
656
657 WXDataBrowserPropertyType wxDataViewDateRenderer::GetPropertyType(void) const
658 {
659 return kDataBrowserDateTimeType;
660 } /* wxDataViewDateRenderer::GetPropertyType(void) const */
661
662 IMPLEMENT_ABSTRACT_CLASS(wxDataViewDateRenderer,wxDataViewRenderer)
663
664 // ---------------------------------------------------------
665 // wxDataViewColumn
666 // ---------------------------------------------------------
667 #pragma mark -
668 wxDataViewColumn::wxDataViewColumn(wxString const &title, wxDataViewRenderer *cell, unsigned int model_column, int width, wxAlignment align, int flags)
669 :wxDataViewColumnBase(title,cell,model_column,width,wxALIGN_CENTER,flags), m_ascending(true),
670 m_flags(flags & ~(wxDATAVIEW_COL_HIDDEN)), m_maxWidth(30000), m_minWidth(0), m_width(width >= 0 ? width : wxDVC_DEFAULT_WIDTH),
671 m_alignment(align), m_title(title)
672 {
673 } /* wxDataViewColumn::wxDataViewColumn(wxString const &title, wxDataViewRenderer*, unsigned int, int, wxAlignment, int) */
674
675 wxDataViewColumn::wxDataViewColumn(wxBitmap const& bitmap, wxDataViewRenderer *cell, unsigned int model_column, int width, wxAlignment align, int flags)
676 :wxDataViewColumnBase(bitmap,cell,model_column,width,wxALIGN_CENTER,flags), m_ascending(true),
677 m_flags(flags & ~(wxDATAVIEW_COL_HIDDEN)), m_maxWidth(30000), m_minWidth(0), m_width(width >= 0 ? width : wxDVC_DEFAULT_WIDTH),
678 m_alignment(align)
679 {
680 } /* wxDataViewColumn::wxDataViewColumn(wxBitmap const&, wxDataViewRenderer*, unsigned int, int, wxAlignment, int) */
681
682 void wxDataViewColumn::SetAlignment(wxAlignment align)
683 {
684 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
685
686
687 this->m_alignment = align;
688 if (dataViewCtrlPtr != NULL)
689 {
690 // variable definition and initialization:
691 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
692
693 if (macDataViewListCtrlPtr != NULL)
694 {
695 // variable definition and initialization:
696 DataBrowserListViewHeaderDesc headerDescription;
697
698 wxCHECK_RET(macDataViewListCtrlPtr->GetHeaderDesc(this->GetPropertyID(),&headerDescription) == noErr,_("Could not get header description."));
699 switch (align)
700 {
701 case wxALIGN_CENTER:
702 case wxALIGN_CENTER_HORIZONTAL:
703 headerDescription.btnFontStyle.just = teCenter;
704 break;
705 case wxALIGN_LEFT:
706 headerDescription.btnFontStyle.just = teFlushLeft;
707 break;
708 case wxALIGN_RIGHT:
709 headerDescription.btnFontStyle.just = teFlushRight;
710 break;
711 default:
712 headerDescription.btnFontStyle.just = teFlushDefault;
713 } /* switch */
714 wxCHECK_RET(macDataViewListCtrlPtr->SetHeaderDesc(this->GetPropertyID(),&headerDescription) == noErr,_("Could not set alignment."));
715 } /* if */
716 } /* if */
717 } /* wxDataViewColumn::SetAlignment(wxAlignment) */
718
719 void wxDataViewColumn::SetBitmap(wxBitmap const& bitmap)
720 {
721 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
722
723
724 wxDataViewColumnBase::SetBitmap(bitmap);
725 if (dataViewCtrlPtr != NULL)
726 {
727 // variable definition and initialization:
728 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
729
730 if (macDataViewListCtrlPtr != NULL)
731 {
732 // variable definition and initialization:
733 DataBrowserListViewHeaderDesc headerDescription;
734
735 wxCHECK_RET(macDataViewListCtrlPtr->GetHeaderDesc(this->GetPropertyID(),&headerDescription) == noErr,_("Could not get header description."));
736 if (this->GetBitmap().Ok())
737 headerDescription.btnContentInfo.u.iconRef = this->GetBitmap().GetBitmapData()->GetIconRef();
738 else
739 headerDescription.btnContentInfo.u.iconRef = NULL;
740 wxCHECK_RET(macDataViewListCtrlPtr->SetHeaderDesc(this->GetPropertyID(),&headerDescription) == noErr,_("Could not set icon."));
741 } /* if */
742 } /* if */
743 } /* wxDataViewColumn::SetBitmap(wxBitmap const&) */
744
745 void wxDataViewColumn::SetFlags(int flags)
746 {
747 this->SetHidden ((flags & wxDATAVIEW_COL_HIDDEN) != 0);
748 this->SetResizeable((flags & wxDATAVIEW_COL_RESIZABLE) != 0);
749 this->SetSortable ((flags & wxDATAVIEW_COL_SORTABLE) != 0);
750 } /* wxDataViewColumn::SetFlags(int) */
751
752 void wxDataViewColumn::SetMaxWidth(int maxWidth)
753 {
754 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
755
756
757 this->m_maxWidth = maxWidth;
758 if (dataViewCtrlPtr != NULL)
759 {
760 // variable definition and initialization:
761 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
762
763 if (macDataViewListCtrlPtr != NULL)
764 {
765 // variable definition and initialization:
766 DataBrowserListViewHeaderDesc headerDescription;
767
768 wxCHECK_RET(macDataViewListCtrlPtr->GetHeaderDesc(this->GetPropertyID(),&headerDescription) == noErr,_("Could not get header description."));
769 headerDescription.maximumWidth = static_cast<UInt16>(maxWidth);
770 wxCHECK_RET(macDataViewListCtrlPtr->SetHeaderDesc(this->GetPropertyID(),&headerDescription) == noErr,_("Could not set maximum width."));
771 } /* if */
772 } /* if */
773 } /* wxDataViewColumn::SetMaxWidth(int) */
774
775 void wxDataViewColumn::SetMinWidth(int minWidth)
776 {
777 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
778
779
780 this->m_minWidth = minWidth;
781 if (dataViewCtrlPtr != NULL)
782 {
783 // variable definition and initialization:
784 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
785
786 if (macDataViewListCtrlPtr != NULL)
787 {
788 // variable definition and initialization:
789 DataBrowserListViewHeaderDesc headerDescription;
790
791 wxCHECK_RET(macDataViewListCtrlPtr->GetHeaderDesc(this->GetPropertyID(),&headerDescription) == noErr,_("Could not get header description."));
792 headerDescription.minimumWidth = static_cast<UInt16>(minWidth);
793 wxCHECK_RET(macDataViewListCtrlPtr->SetHeaderDesc(this->GetPropertyID(),&headerDescription) == noErr,_("Could not set minimum width."));
794 } /* if */
795 } /* if */
796 } /* wxDataViewColumn::SetMaxWidth(int) */
797
798 void wxDataViewColumn::SetResizeable(bool WXUNUSED(resizeable))
799 {
800 } /* wxDataViewColumn::SetResizeable(bool) */
801
802 void wxDataViewColumn::SetSortable(bool sortable)
803 {
804 // variable definition and initialization:
805 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
806
807 if (dataViewCtrlPtr != NULL)
808 {
809 // variable definition and initialization:
810 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
811
812 if (macDataViewListCtrlPtr != NULL)
813 {
814 // variable definition and initialization:
815 DataBrowserPropertyFlags flags;
816
817 wxCHECK_RET(macDataViewListCtrlPtr->GetPropertyFlags(this->GetPropertyID(),&flags) == noErr,_("Could not get property flags."));
818 if (sortable)
819 {
820 this->m_flags |= wxDATAVIEW_COL_SORTABLE;
821 flags |= kDataBrowserListViewSortableColumn;
822 } /* if */
823 else
824 {
825 this->m_flags &= ~wxDATAVIEW_COL_SORTABLE;
826 flags &= ~kDataBrowserPropertyIsEditable;
827 } /* if */
828 wxCHECK_RET(macDataViewListCtrlPtr->SetPropertyFlags(this->GetPropertyID(),flags) == noErr,_("Could not set property flags."));
829 } /* if */
830 } /* if */
831 } /* wxDataViewColumn::SetSortable(bool) */
832
833 void wxDataViewColumn::SetSortOrder(bool ascending)
834 {
835 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
836
837
838 this->m_ascending = ascending;
839 if (dataViewCtrlPtr != NULL)
840 {
841 // variable definition and initialization:
842 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
843
844 if (macDataViewListCtrlPtr != NULL)
845 {
846 // variable definition and initialization:
847 DataBrowserListViewHeaderDesc headerDescription;
848
849 verify_noerr(macDataViewListCtrlPtr->GetHeaderDesc(this->GetPropertyID(),&headerDescription));
850 if (ascending)
851 headerDescription.initialOrder = kDataBrowserOrderIncreasing;
852 else
853 headerDescription.initialOrder = kDataBrowserOrderDecreasing;
854 verify_noerr(macDataViewListCtrlPtr->SetHeaderDesc(this->GetPropertyID(),&headerDescription));
855 macDataViewListCtrlPtr->SetSortProperty(this->GetPropertyID());
856 } /* if */
857 } /* if */
858 } /* wxDataViewColumn::SetSortOrder(bool) */
859
860 void wxDataViewColumn::SetTitle(wxString const& title)
861 {
862 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
863
864
865 this->m_title = title;
866 if (dataViewCtrlPtr != NULL)
867 {
868 // variable definition and initialization:
869 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
870
871 if (macDataViewListCtrlPtr != NULL)
872 {
873 // variable definition and initialization:
874 DataBrowserListViewHeaderDesc headerDescription;
875 wxMacCFStringHolder cfTitle(title,(dataViewCtrlPtr->GetFont().Ok() ? dataViewCtrlPtr->GetFont().GetEncoding() : wxLocale::GetSystemEncoding()));
876
877 wxCHECK_RET(macDataViewListCtrlPtr->GetHeaderDesc(this->GetPropertyID(),&headerDescription) == noErr,_("Could not get header description."));
878 headerDescription.titleString = cfTitle;
879 wxCHECK_RET(macDataViewListCtrlPtr->SetHeaderDesc(this->GetPropertyID(),&headerDescription) == noErr,_("Could not set header description."));
880 } /* if */
881 } /* if */
882 } /* wxDataViewColumn::SetTitle(wxString const&) */
883
884 void wxDataViewColumn::SetWidth(int width)
885 {
886 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
887
888
889 if ((width >= this->m_minWidth) && (width <= this->m_maxWidth))
890 {
891 this->m_width = width;
892 if (dataViewCtrlPtr != NULL)
893 {
894 // variable definition and initialization:
895 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
896
897 if (macDataViewListCtrlPtr != NULL)
898 wxCHECK_RET(macDataViewListCtrlPtr->SetColumnWidth(this->GetPropertyID(),static_cast<UInt16>(width)) == noErr,_("Could not set column width."));
899 } /* if */
900 } /* if */
901 } /* wxDataViewColumn::SetWidth(int) */
902
903 IMPLEMENT_ABSTRACT_CLASS(wxDataViewColumn,wxDataViewColumnBase)
904
905 //-----------------------------------------------------------------------------
906 // wxDataViewCtrl
907 //-----------------------------------------------------------------------------
908 #pragma mark -
909 void wxDataViewCtrl::Init(void)
910 {
911 this->m_Deleting = false;
912 this->m_macIsUserPane = false;
913 this->m_cgContext = NULL;
914 } /* wxDataViewCtrl::Init(void) */
915
916 bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator )
917 {
918 if (!(this->wxControl::Create(parent,id,pos,size,(style | wxSUNKEN_BORDER) & ~(wxHSCROLL | wxVSCROLL),validator)))
919 return false;
920
921 #ifdef __WXMAC__
922 MacSetClipChildren(true) ;
923 #endif
924
925 this->m_peer = new wxMacDataViewDataBrowserListViewControl(this,pos,size,style);
926 this->MacPostControlCreate(pos,size);
927 ::SetAutomaticControlDragTrackingEnabledForWindow(::GetControlOwner(this->m_peer->GetControlRef()),true);
928
929 InstallControlEventHandler(this->m_peer->GetControlRef(),GetwxMacDataViewCtrlEventHandlerUPP(),GetEventTypeCount(eventList),eventList,this,NULL);
930
931 return true;
932 } /* wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator) */
933
934 bool wxDataViewCtrl::AssociateModel(wxDataViewModel* model)
935 {
936 if (!wxDataViewCtrlBase::AssociateModel(model))
937 return false;
938
939 model->AddNotifier(new wxMacDataViewModelNotifier(dynamic_cast<wxMacDataViewDataBrowserListViewControl*>(this->m_peer)));
940
941 return true;
942 } /* wxDataViewCtrl::AssociateModel(wxDataViewModel*) */
943
944 bool wxDataViewCtrl::AppendColumn(wxDataViewColumn* columnPtr)
945 {
946 DataBrowserListViewColumnDesc columnDescription;
947
948 DataBrowserPropertyID NewPropertyID;
949
950 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
951
952 wxMacCFStringHolder title(columnPtr->GetTitle(),this->m_font.Ok() ? this->m_font.GetEncoding() : wxLocale::GetSystemEncoding());
953
954
955 // first, some error checking:
956 wxCHECK_MSG(MacDataViewListCtrlPtr != NULL, false,_("m_peer is not or incorrectly initialized"));
957 wxCHECK_MSG(columnPtr != NULL, false,_("Column pointer must not be NULL."));
958 wxCHECK_MSG(columnPtr->GetRenderer() != NULL, false,_("Column does not have a renderer."));
959 wxCHECK_MSG(this->GetModel() != NULL, false,_("No model associated with control."));
960 wxCHECK_MSG((columnPtr->GetModelColumn() >= 0) &&
961 (columnPtr->GetModelColumn() < this->GetModel()->GetColumnCount()),false,_("Column's model column has no equivalent in the associated model."));
962
963 // try to get new ID for the column:
964 wxCHECK_MSG(MacDataViewListCtrlPtr->GetFreePropertyID(&NewPropertyID) == noErr,false,_("Cannot create new column's ID. Probably max. number of columns reached."));
965 // full column variable initialization:
966 columnPtr->SetPropertyID(NewPropertyID);
967 // add column to wxWidget's internal structure:
968 wxCHECK_MSG(this->wxDataViewCtrlBase::AppendColumn(columnPtr) &&
969 this->m_ColumnPointers.insert(ColumnPointerHashMapType::value_type(NewPropertyID,columnPtr)).second,false,_("Could not add column to internal structures."));
970 // create a column description and add column to the native control:
971 wxCHECK_MSG(::InitializeColumnDescription(columnDescription,columnPtr,NewPropertyID,title), false,_("Column description could not be initialized."));
972 wxCHECK_MSG(MacDataViewListCtrlPtr->AddColumn(&columnDescription,kDataBrowserListViewAppendColumn) == noErr,false,_("Column could not be added."));
973
974 // final adjustments for the layout:
975 wxCHECK_MSG(MacDataViewListCtrlPtr->SetColumnWidth(NewPropertyID,columnPtr->GetWidth()) == noErr,false,_("Column width could not be set."));
976
977 // make sure that the data is up-to-date...
978 // if the newly appended column is the first column add the initial data to the control and mark the column as an expander column,
979 // otherwise ask the control to 'update' the data in the newly appended column:
980 if (this->GetColumnCount() == 1)
981 {
982 this->SetExpanderColumn(columnPtr);
983 this->AddChildrenLevel(wxDataViewItem());
984 } /* if */
985 else
986 MacDataViewListCtrlPtr->UpdateItems(kDataBrowserNoItem,0,NULL,kDataBrowserItemNoProperty,NewPropertyID);
987 // done:
988 return true;
989 } /* wxDataViewCtrl::AppendColumn(wxDataViewColumn*) */
990
991 bool wxDataViewCtrl::ClearColumns(void)
992 {
993 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
994
995
996 while (this->m_ColumnPointers.begin() != this->m_ColumnPointers.end())
997 {
998 wxCHECK_MSG(MacDataViewListCtrlPtr->RemoveColumnByProperty(this->m_ColumnPointers.begin()->first) == noErr,false,_("Could not remove column."));
999 delete this->m_ColumnPointers.begin()->second;
1000 this->m_ColumnPointers.erase(this->m_ColumnPointers.begin());
1001 } /* while */
1002 return true;
1003 } /* wxDataViewCtrl::ClearColumns(void) */
1004
1005 bool wxDataViewCtrl::DeleteColumn(wxDataViewColumn* columnPtr)
1006 {
1007 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1008
1009
1010 if ((MacDataViewListCtrlPtr->RemoveColumnByProperty(columnPtr->GetPropertyID()) == noErr) && (this->m_ColumnPointers.erase(columnPtr->GetPropertyID()) > 0))
1011 {
1012 delete columnPtr;
1013 return true;
1014 } /* if */
1015 else
1016 return false;
1017 } /* wxDataViewCtrl::DeleteColumn(wxDataViewColumn*) */
1018
1019 wxDataViewColumn* wxDataViewCtrl::GetColumn(unsigned int pos) const
1020 {
1021 DataBrowserPropertyID propertyID;
1022
1023 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1024
1025
1026 if (MacDataViewListCtrlPtr->GetPropertyID(pos,&propertyID) == noErr)
1027 {
1028 // variable definition:
1029 ColumnPointerHashMapType::const_iterator Result(this->m_ColumnPointers.find(propertyID));
1030
1031 if (Result != this->m_ColumnPointers.end())
1032 return Result->second;
1033 else
1034 return NULL;
1035 } /* if */
1036 else
1037 return NULL;
1038 } /* wxDataViewCtrl::GetColumn(unsigned int pos) const */
1039
1040 unsigned int wxDataViewCtrl::GetColumnCount(void) const
1041 {
1042 return this->m_ColumnPointers.size();
1043 } /* wxDataViewCtrl::GetColumnCount(void) const */
1044
1045 int wxDataViewCtrl::GetColumnPosition(wxDataViewColumn const* columnPtr) const
1046 {
1047 if (columnPtr != NULL)
1048 {
1049 // variable definition and initialization:
1050 DataBrowserTableViewColumnIndex Position;
1051 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1052
1053 wxCHECK_MSG(MacDataViewListCtrlPtr->GetColumnIndex(columnPtr->GetPropertyID(),&Position) == noErr,-1,_("Could not determine column's position"));
1054 return static_cast<int>(Position);
1055 } /* if */
1056 else
1057 return wxNOT_FOUND;
1058 } /* wxDataViewCtrl::GetColumnPosition(wxDataViewColumn const*) const */
1059
1060 bool wxDataViewCtrl::PrependColumn(wxDataViewColumn* columnPtr)
1061 {
1062 DataBrowserListViewColumnDesc columnDescription;
1063
1064 DataBrowserPropertyID NewPropertyID;
1065
1066 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1067
1068 wxMacCFStringHolder title(columnPtr->GetTitle(),this->m_font.Ok() ? this->m_font.GetEncoding() : wxLocale::GetSystemEncoding());
1069
1070
1071 // first, some error checking:
1072 wxCHECK_MSG(MacDataViewListCtrlPtr != NULL, false,_("m_peer is not or incorrectly initialized"));
1073 wxCHECK_MSG(columnPtr != NULL, false,_("Column pointer must not be NULL."));
1074 wxCHECK_MSG(columnPtr->GetRenderer() != NULL, false,_("Column does not have a renderer."));
1075 wxCHECK_MSG(this->GetModel() != NULL, false,_("No model associated with control."));
1076 wxCHECK_MSG((columnPtr->GetModelColumn() >= 0) &&
1077 (columnPtr->GetModelColumn() < this->GetModel()->GetColumnCount()),false,_("Column's model column has no equivalent in the associated model."));
1078
1079 // try to get new ID for the column:
1080 wxCHECK_MSG(MacDataViewListCtrlPtr->GetFreePropertyID(&NewPropertyID) == noErr,false,_("Cannot create new column's ID. Probably max. number of columns reached."));
1081 // full column variable initialization:
1082 columnPtr->SetPropertyID(NewPropertyID);
1083 // add column to wxWidget's internal structure:
1084 wxCHECK_MSG(this->wxDataViewCtrlBase::AppendColumn(columnPtr) &&
1085 this->m_ColumnPointers.insert(ColumnPointerHashMapType::value_type(NewPropertyID,columnPtr)).second,false,_("Could not add column to internal structures."));
1086 // create a column description and add column to the native control:
1087 wxCHECK_MSG(::InitializeColumnDescription(columnDescription,columnPtr,NewPropertyID,title),false,_("Column description could not be initialized."));
1088 wxCHECK_MSG(MacDataViewListCtrlPtr->AddColumn(&columnDescription,0) == noErr, false,_("Column could not be added."));
1089
1090 // final adjustments for the layout:
1091 wxCHECK_MSG(MacDataViewListCtrlPtr->SetColumnWidth(NewPropertyID,columnPtr->GetWidth()) == noErr,false,_("Column width could not be set."));
1092
1093 // make sure that the data is up-to-date...
1094 // if the newly appended column is the first column add the initial data to the control and mark the column as an expander column,
1095 // otherwise ask the control to 'update' the data in the newly appended column:
1096 if (this->GetColumnCount() == 1)
1097 {
1098 this->SetExpanderColumn(columnPtr);
1099 this->AddChildrenLevel(wxDataViewItem());
1100 } /* if */
1101 else
1102 MacDataViewListCtrlPtr->UpdateItems(kDataBrowserNoItem,0,NULL,kDataBrowserItemNoProperty,NewPropertyID);
1103 // done:
1104 return true;
1105 } /* wxDataViewCtrl::PrependColumn(wxDataViewColumn*) */
1106
1107 void wxDataViewCtrl::Collapse(wxDataViewItem const& item)
1108 {
1109 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1110
1111
1112 MacDataViewListCtrlPtr->CloseContainer(reinterpret_cast<DataBrowserItemID>(item.GetID()));
1113 } /* wxDataViewCtrl::Collapse(wxDataViewItem const&) */
1114
1115 void wxDataViewCtrl::EnsureVisible(wxDataViewItem const& item, wxDataViewColumn const* columnPtr)
1116 {
1117 if (item.IsOk())
1118 {
1119 // variable definition and initialization:
1120 DataBrowserPropertyID propertyID;
1121 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1122
1123 if (columnPtr != NULL)
1124 propertyID = columnPtr->GetPropertyID();
1125 else
1126 propertyID = kDataBrowserNoItem;
1127 MacDataViewListCtrlPtr->RevealItem(reinterpret_cast<DataBrowserItemID>(item.GetID()),propertyID,kDataBrowserRevealOnly);
1128 } /* if */
1129 } /* wxDataViewCtrl::EnsureVisible(wxDataViewItem const&, wxDataViewColumn const*) */
1130
1131 void wxDataViewCtrl::Expand(wxDataViewItem const& item)
1132 {
1133 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1134
1135
1136 MacDataViewListCtrlPtr->OpenContainer(reinterpret_cast<DataBrowserItemID>(item.GetID()));
1137 } /* wxDataViewCtrl::Expand(wxDataViewItem const&) */
1138
1139 wxDataViewColumn* wxDataViewCtrl::GetSortingColumn(void) const
1140 {
1141 DataBrowserPropertyID propertyID;
1142
1143 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1144
1145
1146 if (MacDataViewListCtrlPtr->GetSortProperty(&propertyID) == noErr)
1147 return this->GetColumnPtr(propertyID);
1148 else
1149 return NULL;
1150 } /* wxDataViewCtrl::GetSortingColumn(void) const */
1151
1152 unsigned int wxDataViewCtrl::GetCount(void) const
1153 {
1154 ItemCount noOfItems;
1155
1156
1157 wxCHECK_MSG(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer)->GetItemCount(&noOfItems) == noErr,0,_("Could not determine number of items"));
1158 return noOfItems;
1159 } /* wxDataViewCtrl::GetCount(void) const */
1160
1161 wxRect wxDataViewCtrl::GetItemRect(wxDataViewItem const& item, wxDataViewColumn const* columnPtr) const
1162 {
1163 if (item.IsOk() && (columnPtr != NULL))
1164 {
1165 // variable definition:
1166 Rect MacRectangle;
1167 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1168
1169 if (MacDataViewListCtrlPtr->GetPartBounds(reinterpret_cast<DataBrowserItemID>(item.GetID()),columnPtr->GetPropertyID(),kDataBrowserPropertyContentPart,&MacRectangle) == noErr)
1170 {
1171 // variable definition:
1172 wxRect rectangle;
1173
1174 ::wxMacNativeToRect(&MacRectangle,&rectangle);
1175 return rectangle;
1176 } /* if */
1177 else
1178 return wxRect();
1179 } /* if */
1180 else
1181 return wxRect();
1182 } /* wxDataViewCtrl::GetItemRect(wxDataViewItem const&, unsigned int) const */
1183
1184 wxDataViewItem wxDataViewCtrl::GetSelection(void) const
1185 {
1186 wxArrayDataBrowserItemID itemIDs;
1187
1188 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1189
1190
1191 if (MacDataViewListCtrlPtr->GetSelectedItemIDs(itemIDs) > 0)
1192 return wxDataViewItem(reinterpret_cast<void*>(itemIDs[0]));
1193 else
1194 return wxDataViewItem();
1195 } /* wxDataViewCtrl::GetSelection(void) const */
1196
1197 int wxDataViewCtrl::GetSelections(wxDataViewItemArray& sel) const
1198 {
1199 size_t NoOfSelectedItems;
1200
1201 wxArrayDataBrowserItemID itemIDs;
1202
1203 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1204
1205
1206 NoOfSelectedItems = MacDataViewListCtrlPtr->GetSelectedItemIDs(itemIDs);
1207 sel.Empty();
1208 sel.SetCount(NoOfSelectedItems);
1209 for (size_t i=0; i<NoOfSelectedItems; ++i)
1210 sel[i] = wxDataViewItem(reinterpret_cast<void*>(itemIDs[i]));
1211 return static_cast<int>(NoOfSelectedItems);
1212 } /* wxDataViewCtrl::GetSelections(wxDataViewItemArray&) const */
1213
1214 void wxDataViewCtrl::HitTest(wxPoint const& point, wxDataViewItem& item, wxDataViewColumn*& columnPtr) const
1215 {
1216 item = wxDataViewItem();
1217 columnPtr = NULL;
1218 } /* wxDataViewCtrl::HitTest(wxPoint const&, wxDataViewItem&, wxDataViewColumn*&) const */
1219
1220 bool wxDataViewCtrl::IsSelected(wxDataViewItem const& item) const
1221 {
1222 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1223
1224
1225 return MacDataViewListCtrlPtr->IsItemSelected(reinterpret_cast<DataBrowserItemID>(item.GetID()));
1226 } /* wxDataViewCtrl::IsSelected(wxDataViewItem const&) const */
1227
1228 void wxDataViewCtrl::SelectAll(void)
1229 {
1230 DataBrowserItemID* itemIDPtr;
1231
1232 Handle handle(::NewHandle(0));
1233
1234 size_t NoOfItems;
1235
1236 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1237
1238
1239 wxCHECK_RET(MacDataViewListCtrlPtr->GetItems(kDataBrowserNoItem,true,kDataBrowserItemAnyState,handle) == noErr,_("Could not get items."));
1240 NoOfItems = static_cast<size_t>(::GetHandleSize(handle)/sizeof(DataBrowserItemID));
1241 HLock(handle);
1242 itemIDPtr = (DataBrowserItemID*) (*handle);
1243 MacDataViewListCtrlPtr->SetSelectedItems(NoOfItems,itemIDPtr,kDataBrowserItemsAssign);
1244 HUnlock(handle);
1245 DisposeHandle(handle);
1246 } /* wxDataViewCtrl::SelectAll(void) */
1247
1248 void wxDataViewCtrl::Select(wxDataViewItem const& item)
1249 {
1250 if (item.IsOk())
1251 {
1252 // variable definition and initialization:
1253 DataBrowserItemID itemID(reinterpret_cast<DataBrowserItemID>(item.GetID()));
1254 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1255
1256 MacDataViewListCtrlPtr->SetSelectedItems(1,&itemID,kDataBrowserItemsAdd);
1257 } /* if */
1258 } /* wxDataViewCtrl::Select(wxDataViewItem const&) */
1259
1260 void wxDataViewCtrl::SetSelections(wxDataViewItemArray const& sel)
1261 {
1262 size_t const NoOfSelections = sel.GetCount();
1263
1264 DataBrowserItemID* itemIDs;
1265
1266 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1267
1268
1269 itemIDs = new DataBrowserItemID[NoOfSelections];
1270 for (size_t i=0; i<NoOfSelections; ++i)
1271 itemIDs[i] = reinterpret_cast<DataBrowserItemID>(sel[i].GetID());
1272 MacDataViewListCtrlPtr->SetSelectedItems(NoOfSelections,itemIDs,kDataBrowserItemsAssign);
1273 delete[] itemIDs;
1274 } /* wxDataViewCtrl::SetSelections(wxDataViewItemArray const&) */
1275
1276 void wxDataViewCtrl::Unselect(wxDataViewItem const& item)
1277 {
1278 if (item.IsOk())
1279 {
1280 // variable definition and initialization:
1281 DataBrowserItemID itemID(reinterpret_cast<DataBrowserItemID>(item.GetID()));
1282 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1283
1284 MacDataViewListCtrlPtr->SetSelectedItems(1,&itemID,kDataBrowserItemsRemove);
1285 } /* if */
1286 } /* wxDataViewCtrl::Unselect(wxDataViewItem const&) */
1287
1288 void wxDataViewCtrl::UnselectAll(void)
1289 {
1290 DataBrowserItemID* itemIDPtr;
1291
1292 Handle handle(::NewHandle(0));
1293
1294 size_t NoOfItems;
1295
1296 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1297
1298
1299 wxCHECK_RET(MacDataViewListCtrlPtr->GetItems(kDataBrowserNoItem,true,kDataBrowserItemAnyState,handle) == noErr,_("Could not get items."));
1300 NoOfItems = static_cast<size_t>(::GetHandleSize(handle)/sizeof(DataBrowserItemID));
1301 HLock(handle);
1302 itemIDPtr = (DataBrowserItemID*) (*handle);
1303 MacDataViewListCtrlPtr->SetSelectedItems(NoOfItems,itemIDPtr,kDataBrowserItemsRemove);
1304 HUnlock(handle);
1305 DisposeHandle(handle);
1306 } /* wxDataViewCtrl::UnselectAll(void) */
1307
1308 // data handling:
1309 void wxDataViewCtrl::AddChildrenLevel(wxDataViewItem const& parentItem)
1310 {
1311 int NoOfChildren;
1312
1313 wxDataViewItemArray items;
1314
1315
1316 wxCHECK_RET(this->GetModel() != NULL,_("Model pointer not initialized."));
1317 NoOfChildren = this->GetModel()->GetChildren(parentItem,items);
1318 #if 0
1319 for (int i=0; i<NoOfChildren; ++i)
1320 (void) this->GetModel()->ItemAdded(parentItem,items[i]);
1321 #else
1322 (void) this->GetModel()->ItemsAdded(parentItem,items);
1323 #endif
1324 } /* wxDataViewCtrl::AddChildrenLevel(wxDataViewItem const&) */
1325
1326 wxDataViewColumn* wxDataViewCtrl::GetColumnPtr(WXDataBrowserPropertyID propertyID) const
1327 {
1328 // variable definition:
1329 ColumnPointerHashMapType::const_iterator Result(this->m_ColumnPointers.find(propertyID));
1330
1331 if (Result != this->m_ColumnPointers.end())
1332 return Result->second;
1333 else
1334 return NULL;
1335 } /* wxDataViewCtrl::GetColumnPtr(DataBrowserPropertyID) const */
1336
1337 // inherited methods from wxDataViewCtrlBase
1338 void wxDataViewCtrl::DoSetExpanderColumn(void)
1339 {
1340 if (this->GetExpanderColumn() != NULL)
1341 {
1342 // variable definition and initialization:
1343 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1344
1345 (void) MacDataViewListCtrlPtr->SetDisclosureColumn(this->GetExpanderColumn()->GetPropertyID());
1346 } /* if */
1347 } /* wxDataViewCtrl::DoSetExpanderColumn(void) */
1348
1349 void wxDataViewCtrl::DoSetIndent(void)
1350 {
1351 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1352
1353
1354 (void) MacDataViewListCtrlPtr->SetIndent(static_cast<float>(this->GetIndent()));
1355 } /* wxDataViewCtrl::DoSetIndent(void) */
1356
1357 // event handling:
1358 void wxDataViewCtrl::OnSize(wxSizeEvent& event)
1359 {
1360 unsigned int const NoOfColumns = this->GetColumnCount();
1361
1362
1363 for (unsigned int i=0; i<NoOfColumns; ++i)
1364 {
1365 // variable definition and initialization:
1366 wxDataViewColumn* dataViewColumnPtr(this->GetColumn(i));
1367
1368 if (dataViewColumnPtr != NULL)
1369 {
1370 // variable definition and initialization:
1371 wxDataViewCustomRenderer* dataViewCustomRendererPtr(dynamic_cast<wxDataViewCustomRenderer*>(dataViewColumnPtr->GetRenderer()));
1372
1373 if (dataViewCustomRendererPtr != NULL)
1374 dataViewCustomRendererPtr->SetDC(NULL); // reset DC because DC has changed
1375 } /* if */
1376 } /* for */
1377 event.Skip();
1378 } /* wxDataViewCtrl::OnSize(wxSizeEvent&) */
1379
1380 IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl,wxDataViewCtrlBase)
1381
1382 BEGIN_EVENT_TABLE(wxDataViewCtrl,wxDataViewCtrlBase)
1383 EVT_SIZE(wxDataViewCtrl::OnSize)
1384 END_EVENT_TABLE()
1385
1386 #endif
1387 // !wxUSE_GENERICDATAVIEWCTRL
1388
1389 #endif
1390 // wxUSE_DATAVIEWCTRL
1391