]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/dataview.cpp
a640caffe703bfed86d9e2a86857f7df6c12bcc9
[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->HandleWindowEvent(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().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->HandleWindowEvent(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->HandleWindowEvent(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->HandleWindowEvent(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.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 if (iconText.GetIcon().IsOk())
576 {
577 if (::SetDataBrowserItemDataIcon(this->GetDataReference(),MAC_WXHICON(iconText.GetIcon().GetHICON())) != noErr)
578 return false;
579 }
580
581 return (::SetDataBrowserItemDataText(this->GetDataReference(),cfString) == noErr);
582 } /* if */
583 else
584 return false;
585 } /* wxDataViewIconTextRenderer::Render(void) */
586
587 WXDataBrowserPropertyType wxDataViewIconTextRenderer::GetPropertyType(void) const
588 {
589 return kDataBrowserIconAndTextType;
590 } /* wxDataViewIconTextRenderer::GetPropertyType(void) const */
591
592 IMPLEMENT_ABSTRACT_CLASS(wxDataViewIconTextRenderer,wxDataViewRenderer)
593
594
595 // ---------------------------------------------------------
596 // wxDataViewToggleRenderer
597 // ---------------------------------------------------------
598 #pragma mark -
599 wxDataViewToggleRenderer::wxDataViewToggleRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align)
600 :wxDataViewRenderer(varianttype,mode)
601 {
602 }
603
604 bool wxDataViewToggleRenderer::Render(void)
605 {
606 if (this->GetValue().GetType() == this->GetVariantType())
607 return (::SetDataBrowserItemDataButtonValue(this->GetDataReference(),this->GetValue().GetBool()) == noErr);
608 else
609 return false;
610 } /* wxDataViewToggleRenderer::Render(void) */
611
612 WXDataBrowserPropertyType wxDataViewToggleRenderer::GetPropertyType(void) const
613 {
614 return kDataBrowserCheckboxType;
615 } /* wxDataViewToggleRenderer::GetPropertyType(void) const */
616
617 IMPLEMENT_ABSTRACT_CLASS(wxDataViewToggleRenderer,wxDataViewRenderer)
618
619 // ---------------------------------------------------------
620 // wxDataViewProgressRenderer
621 // ---------------------------------------------------------
622 #pragma mark -
623 wxDataViewProgressRenderer::wxDataViewProgressRenderer(wxString const& label, wxString const& varianttype, wxDataViewCellMode mode, int align)
624 :wxDataViewRenderer(varianttype,mode,align)
625 {
626 }
627
628 bool wxDataViewProgressRenderer::Render(void)
629 {
630 if (this->GetValue().GetType() == this->GetVariantType())
631 return ((::SetDataBrowserItemDataMinimum(this->GetDataReference(), 0) == noErr) &&
632 (::SetDataBrowserItemDataMaximum(this->GetDataReference(),100) == noErr) &&
633 (::SetDataBrowserItemDataValue (this->GetDataReference(),this->GetValue().GetLong()) == noErr));
634 else
635 return false;
636 } /* wxDataViewProgressRenderer::Render(void) */
637
638 WXDataBrowserPropertyType wxDataViewProgressRenderer::GetPropertyType(void) const
639 {
640 return kDataBrowserProgressBarType;
641 } /* wxDataViewProgressRenderer::GetPropertyType(void) const */
642
643 IMPLEMENT_ABSTRACT_CLASS(wxDataViewProgressRenderer,wxDataViewRenderer)
644
645 // ---------------------------------------------------------
646 // wxDataViewDateRenderer
647 // ---------------------------------------------------------
648 #pragma mark -
649 wxDataViewDateRenderer::wxDataViewDateRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align)
650 :wxDataViewRenderer(varianttype,mode,align)
651 {
652 }
653
654 bool wxDataViewDateRenderer::Render(void)
655 {
656 if (this->GetValue().GetType() == this->GetVariantType())
657 return (::SetDataBrowserItemDataDateTime(this->GetDataReference(),this->GetValue().GetDateTime().Subtract(wxDateTime(1,wxDateTime::Jan,1904)).GetSeconds().GetLo()) == noErr);
658 else
659 return false;
660 } /* wxDataViewDateRenderer::Render(void) */
661
662 WXDataBrowserPropertyType wxDataViewDateRenderer::GetPropertyType(void) const
663 {
664 return kDataBrowserDateTimeType;
665 } /* wxDataViewDateRenderer::GetPropertyType(void) const */
666
667 IMPLEMENT_ABSTRACT_CLASS(wxDataViewDateRenderer,wxDataViewRenderer)
668
669 // ---------------------------------------------------------
670 // wxDataViewColumn
671 // ---------------------------------------------------------
672 #pragma mark -
673 wxDataViewColumn::wxDataViewColumn(wxString const &title, wxDataViewRenderer *cell, unsigned int model_column, int width, wxAlignment align, int flags)
674 :wxDataViewColumnBase(title,cell,model_column,width,wxALIGN_CENTER,flags), m_ascending(true),
675 m_flags(flags & ~(wxDATAVIEW_COL_HIDDEN)), m_maxWidth(30000), m_minWidth(0), m_width(width >= 0 ? width : wxDVC_DEFAULT_WIDTH),
676 m_alignment(align), m_title(title)
677 {
678 } /* wxDataViewColumn::wxDataViewColumn(wxString const &title, wxDataViewRenderer*, unsigned int, int, wxAlignment, int) */
679
680 wxDataViewColumn::wxDataViewColumn(wxBitmap const& bitmap, wxDataViewRenderer *cell, unsigned int model_column, int width, wxAlignment align, int flags)
681 :wxDataViewColumnBase(bitmap,cell,model_column,width,wxALIGN_CENTER,flags), m_ascending(true),
682 m_flags(flags & ~(wxDATAVIEW_COL_HIDDEN)), m_maxWidth(30000), m_minWidth(0), m_width(width >= 0 ? width : wxDVC_DEFAULT_WIDTH),
683 m_alignment(align)
684 {
685 } /* wxDataViewColumn::wxDataViewColumn(wxBitmap const&, wxDataViewRenderer*, unsigned int, int, wxAlignment, int) */
686
687 void wxDataViewColumn::SetAlignment(wxAlignment align)
688 {
689 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
690
691
692 this->m_alignment = align;
693 if (dataViewCtrlPtr != NULL)
694 {
695 // variable definition and initialization:
696 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
697
698 if (macDataViewListCtrlPtr != NULL)
699 {
700 // variable definition and initialization:
701 DataBrowserListViewHeaderDesc headerDescription;
702
703 wxCHECK_RET(macDataViewListCtrlPtr->GetHeaderDesc(this->GetPropertyID(),&headerDescription) == noErr,_("Could not get header description."));
704 switch (align)
705 {
706 case wxALIGN_CENTER:
707 case wxALIGN_CENTER_HORIZONTAL:
708 headerDescription.btnFontStyle.just = teCenter;
709 break;
710 case wxALIGN_LEFT:
711 headerDescription.btnFontStyle.just = teFlushLeft;
712 break;
713 case wxALIGN_RIGHT:
714 headerDescription.btnFontStyle.just = teFlushRight;
715 break;
716 default:
717 headerDescription.btnFontStyle.just = teFlushDefault;
718 } /* switch */
719 wxCHECK_RET(macDataViewListCtrlPtr->SetHeaderDesc(this->GetPropertyID(),&headerDescription) == noErr,_("Could not set alignment."));
720 } /* if */
721 } /* if */
722 } /* wxDataViewColumn::SetAlignment(wxAlignment) */
723
724 void wxDataViewColumn::SetBitmap(wxBitmap const& bitmap)
725 {
726 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
727
728
729 wxDataViewColumnBase::SetBitmap(bitmap);
730 if (dataViewCtrlPtr != NULL)
731 {
732 // variable definition and initialization:
733 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
734
735 if (macDataViewListCtrlPtr != NULL)
736 {
737 // variable definition and initialization:
738 DataBrowserListViewHeaderDesc headerDescription;
739
740 wxCHECK_RET(macDataViewListCtrlPtr->GetHeaderDesc(this->GetPropertyID(),&headerDescription) == noErr,_("Could not get header description."));
741 if (this->GetBitmap().Ok())
742 headerDescription.btnContentInfo.u.iconRef = this->GetBitmap().GetIconRef();
743 else
744 headerDescription.btnContentInfo.u.iconRef = NULL;
745 wxCHECK_RET(macDataViewListCtrlPtr->SetHeaderDesc(this->GetPropertyID(),&headerDescription) == noErr,_("Could not set icon."));
746 } /* if */
747 } /* if */
748 } /* wxDataViewColumn::SetBitmap(wxBitmap const&) */
749
750 void wxDataViewColumn::SetFlags(int flags)
751 {
752 this->SetHidden ((flags & wxDATAVIEW_COL_HIDDEN) != 0);
753 this->SetResizeable((flags & wxDATAVIEW_COL_RESIZABLE) != 0);
754 this->SetSortable ((flags & wxDATAVIEW_COL_SORTABLE) != 0);
755 } /* wxDataViewColumn::SetFlags(int) */
756
757 void wxDataViewColumn::SetMaxWidth(int maxWidth)
758 {
759 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
760
761
762 this->m_maxWidth = maxWidth;
763 if (dataViewCtrlPtr != NULL)
764 {
765 // variable definition and initialization:
766 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
767
768 if (macDataViewListCtrlPtr != NULL)
769 {
770 // variable definition and initialization:
771 DataBrowserListViewHeaderDesc headerDescription;
772
773 wxCHECK_RET(macDataViewListCtrlPtr->GetHeaderDesc(this->GetPropertyID(),&headerDescription) == noErr,_("Could not get header description."));
774 headerDescription.maximumWidth = static_cast<UInt16>(maxWidth);
775 wxCHECK_RET(macDataViewListCtrlPtr->SetHeaderDesc(this->GetPropertyID(),&headerDescription) == noErr,_("Could not set maximum width."));
776 } /* if */
777 } /* if */
778 } /* wxDataViewColumn::SetMaxWidth(int) */
779
780 void wxDataViewColumn::SetMinWidth(int minWidth)
781 {
782 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
783
784
785 this->m_minWidth = minWidth;
786 if (dataViewCtrlPtr != NULL)
787 {
788 // variable definition and initialization:
789 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
790
791 if (macDataViewListCtrlPtr != NULL)
792 {
793 // variable definition and initialization:
794 DataBrowserListViewHeaderDesc headerDescription;
795
796 wxCHECK_RET(macDataViewListCtrlPtr->GetHeaderDesc(this->GetPropertyID(),&headerDescription) == noErr,_("Could not get header description."));
797 headerDescription.minimumWidth = static_cast<UInt16>(minWidth);
798 wxCHECK_RET(macDataViewListCtrlPtr->SetHeaderDesc(this->GetPropertyID(),&headerDescription) == noErr,_("Could not set minimum width."));
799 } /* if */
800 } /* if */
801 } /* wxDataViewColumn::SetMaxWidth(int) */
802
803 void wxDataViewColumn::SetResizeable(bool WXUNUSED(resizeable))
804 {
805 } /* wxDataViewColumn::SetResizeable(bool) */
806
807 void wxDataViewColumn::SetSortable(bool sortable)
808 {
809 // variable definition and initialization:
810 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
811
812 if (dataViewCtrlPtr != NULL)
813 {
814 // variable definition and initialization:
815 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
816
817 if (macDataViewListCtrlPtr != NULL)
818 {
819 // variable definition and initialization:
820 DataBrowserPropertyFlags flags;
821
822 wxCHECK_RET(macDataViewListCtrlPtr->GetPropertyFlags(this->GetPropertyID(),&flags) == noErr,_("Could not get property flags."));
823 if (sortable)
824 {
825 this->m_flags |= wxDATAVIEW_COL_SORTABLE;
826 flags |= kDataBrowserListViewSortableColumn;
827 } /* if */
828 else
829 {
830 this->m_flags &= ~wxDATAVIEW_COL_SORTABLE;
831 flags &= ~kDataBrowserPropertyIsEditable;
832 } /* if */
833 wxCHECK_RET(macDataViewListCtrlPtr->SetPropertyFlags(this->GetPropertyID(),flags) == noErr,_("Could not set property flags."));
834 } /* if */
835 } /* if */
836 } /* wxDataViewColumn::SetSortable(bool) */
837
838 void wxDataViewColumn::SetSortOrder(bool ascending)
839 {
840 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
841
842
843 this->m_ascending = ascending;
844 if (dataViewCtrlPtr != NULL)
845 {
846 // variable definition and initialization:
847 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
848
849 if (macDataViewListCtrlPtr != NULL)
850 {
851 // variable definition and initialization:
852 DataBrowserListViewHeaderDesc headerDescription;
853
854 verify_noerr(macDataViewListCtrlPtr->GetHeaderDesc(this->GetPropertyID(),&headerDescription));
855 if (ascending)
856 headerDescription.initialOrder = kDataBrowserOrderIncreasing;
857 else
858 headerDescription.initialOrder = kDataBrowserOrderDecreasing;
859 verify_noerr(macDataViewListCtrlPtr->SetHeaderDesc(this->GetPropertyID(),&headerDescription));
860 macDataViewListCtrlPtr->SetSortProperty(this->GetPropertyID());
861 } /* if */
862 } /* if */
863 } /* wxDataViewColumn::SetSortOrder(bool) */
864
865 void wxDataViewColumn::SetTitle(wxString const& title)
866 {
867 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
868
869
870 this->m_title = title;
871 if (dataViewCtrlPtr != NULL)
872 {
873 // variable definition and initialization:
874 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
875
876 if (macDataViewListCtrlPtr != NULL)
877 {
878 // variable definition and initialization:
879 DataBrowserListViewHeaderDesc headerDescription;
880 wxMacCFStringHolder cfTitle(title,(dataViewCtrlPtr->GetFont().Ok() ? dataViewCtrlPtr->GetFont().GetEncoding() : wxLocale::GetSystemEncoding()));
881
882 wxCHECK_RET(macDataViewListCtrlPtr->GetHeaderDesc(this->GetPropertyID(),&headerDescription) == noErr,_("Could not get header description."));
883 headerDescription.titleString = cfTitle;
884 wxCHECK_RET(macDataViewListCtrlPtr->SetHeaderDesc(this->GetPropertyID(),&headerDescription) == noErr,_("Could not set header description."));
885 } /* if */
886 } /* if */
887 } /* wxDataViewColumn::SetTitle(wxString const&) */
888
889 void wxDataViewColumn::SetWidth(int width)
890 {
891 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
892
893
894 if ((width >= this->m_minWidth) && (width <= this->m_maxWidth))
895 {
896 this->m_width = width;
897 if (dataViewCtrlPtr != NULL)
898 {
899 // variable definition and initialization:
900 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
901
902 if (macDataViewListCtrlPtr != NULL)
903 wxCHECK_RET(macDataViewListCtrlPtr->SetColumnWidth(this->GetPropertyID(),static_cast<UInt16>(width)) == noErr,_("Could not set column width."));
904 } /* if */
905 } /* if */
906 } /* wxDataViewColumn::SetWidth(int) */
907
908 IMPLEMENT_ABSTRACT_CLASS(wxDataViewColumn,wxDataViewColumnBase)
909
910 //-----------------------------------------------------------------------------
911 // wxDataViewCtrl
912 //-----------------------------------------------------------------------------
913 #pragma mark -
914 void wxDataViewCtrl::Init(void)
915 {
916 this->m_Deleting = false;
917 this->m_macIsUserPane = false;
918 this->m_cgContext = NULL;
919 } /* wxDataViewCtrl::Init(void) */
920
921 bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator )
922 {
923 if (!(this->wxControl::Create(parent,id,pos,size,(style | wxSUNKEN_BORDER) & ~(wxHSCROLL | wxVSCROLL),validator)))
924 return false;
925
926 #ifdef __WXMAC__
927 MacSetClipChildren(true) ;
928 #endif
929
930 this->m_peer = new wxMacDataViewDataBrowserListViewControl(this,pos,size,style);
931 this->MacPostControlCreate(pos,size);
932 ::SetAutomaticControlDragTrackingEnabledForWindow(::GetControlOwner(this->m_peer->GetControlRef()),true);
933
934 InstallControlEventHandler(this->m_peer->GetControlRef(),GetwxMacDataViewCtrlEventHandlerUPP(),GetEventTypeCount(eventList),eventList,this,NULL);
935
936 return true;
937 } /* wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator) */
938
939 bool wxDataViewCtrl::AssociateModel(wxDataViewModel* model)
940 {
941 if (!wxDataViewCtrlBase::AssociateModel(model))
942 return false;
943
944 model->AddNotifier(new wxMacDataViewModelNotifier(dynamic_cast<wxMacDataViewDataBrowserListViewControl*>(this->m_peer)));
945
946 return true;
947 } /* wxDataViewCtrl::AssociateModel(wxDataViewModel*) */
948
949 bool wxDataViewCtrl::AppendColumn(wxDataViewColumn* columnPtr)
950 {
951 DataBrowserListViewColumnDesc columnDescription;
952
953 DataBrowserPropertyID NewPropertyID;
954
955 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
956
957 wxMacCFStringHolder title(columnPtr->GetTitle(),this->m_font.Ok() ? this->m_font.GetEncoding() : wxLocale::GetSystemEncoding());
958
959
960 // first, some error checking:
961 wxCHECK_MSG(MacDataViewListCtrlPtr != NULL, false,_("m_peer is not or incorrectly initialized"));
962 wxCHECK_MSG(columnPtr != NULL, false,_("Column pointer must not be NULL."));
963 wxCHECK_MSG(columnPtr->GetRenderer() != NULL, false,_("Column does not have a renderer."));
964 wxCHECK_MSG(this->GetModel() != NULL, false,_("No model associated with control."));
965 wxCHECK_MSG((columnPtr->GetModelColumn() >= 0) &&
966 (columnPtr->GetModelColumn() < this->GetModel()->GetColumnCount()),false,_("Column's model column has no equivalent in the associated model."));
967
968 // try to get new ID for the column:
969 wxCHECK_MSG(MacDataViewListCtrlPtr->GetFreePropertyID(&NewPropertyID) == noErr,false,_("Cannot create new column's ID. Probably max. number of columns reached."));
970 // full column variable initialization:
971 columnPtr->SetPropertyID(NewPropertyID);
972 // add column to wxWidget's internal structure:
973 wxCHECK_MSG(this->wxDataViewCtrlBase::AppendColumn(columnPtr) &&
974 this->m_ColumnPointers.insert(ColumnPointerHashMapType::value_type(NewPropertyID,columnPtr)).second,false,_("Could not add column to internal structures."));
975 // create a column description and add column to the native control:
976 wxCHECK_MSG(::InitializeColumnDescription(columnDescription,columnPtr,NewPropertyID,title), false,_("Column description could not be initialized."));
977 wxCHECK_MSG(MacDataViewListCtrlPtr->AddColumn(&columnDescription,kDataBrowserListViewAppendColumn) == noErr,false,_("Column could not be added."));
978
979 // final adjustments for the layout:
980 wxCHECK_MSG(MacDataViewListCtrlPtr->SetColumnWidth(NewPropertyID,columnPtr->GetWidth()) == noErr,false,_("Column width could not be set."));
981
982 // make sure that the data is up-to-date...
983 // if the newly appended column is the first column add the initial data to the control and mark the column as an expander column,
984 // otherwise ask the control to 'update' the data in the newly appended column:
985 if (this->GetColumnCount() == 1)
986 {
987 this->SetExpanderColumn(columnPtr);
988 this->AddChildrenLevel(wxDataViewItem());
989 } /* if */
990 else
991 MacDataViewListCtrlPtr->UpdateItems(kDataBrowserNoItem,0,NULL,kDataBrowserItemNoProperty,NewPropertyID);
992 // done:
993 return true;
994 } /* wxDataViewCtrl::AppendColumn(wxDataViewColumn*) */
995
996 bool wxDataViewCtrl::ClearColumns(void)
997 {
998 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
999
1000
1001 while (this->m_ColumnPointers.begin() != this->m_ColumnPointers.end())
1002 {
1003 wxCHECK_MSG(MacDataViewListCtrlPtr->RemoveColumnByProperty(this->m_ColumnPointers.begin()->first) == noErr,false,_("Could not remove column."));
1004 delete this->m_ColumnPointers.begin()->second;
1005 this->m_ColumnPointers.erase(this->m_ColumnPointers.begin());
1006 } /* while */
1007 return true;
1008 } /* wxDataViewCtrl::ClearColumns(void) */
1009
1010 bool wxDataViewCtrl::DeleteColumn(wxDataViewColumn* columnPtr)
1011 {
1012 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1013
1014
1015 if ((MacDataViewListCtrlPtr->RemoveColumnByProperty(columnPtr->GetPropertyID()) == noErr) && (this->m_ColumnPointers.erase(columnPtr->GetPropertyID()) > 0))
1016 {
1017 delete columnPtr;
1018 return true;
1019 } /* if */
1020 else
1021 return false;
1022 } /* wxDataViewCtrl::DeleteColumn(wxDataViewColumn*) */
1023
1024 wxDataViewColumn* wxDataViewCtrl::GetColumn(unsigned int pos) const
1025 {
1026 DataBrowserPropertyID propertyID;
1027
1028 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1029
1030
1031 if (MacDataViewListCtrlPtr->GetPropertyID(pos,&propertyID) == noErr)
1032 {
1033 // variable definition:
1034 ColumnPointerHashMapType::const_iterator Result(this->m_ColumnPointers.find(propertyID));
1035
1036 if (Result != this->m_ColumnPointers.end())
1037 return Result->second;
1038 else
1039 return NULL;
1040 } /* if */
1041 else
1042 return NULL;
1043 } /* wxDataViewCtrl::GetColumn(unsigned int pos) const */
1044
1045 unsigned int wxDataViewCtrl::GetColumnCount(void) const
1046 {
1047 return this->m_ColumnPointers.size();
1048 } /* wxDataViewCtrl::GetColumnCount(void) const */
1049
1050 int wxDataViewCtrl::GetColumnPosition(wxDataViewColumn const* columnPtr) const
1051 {
1052 if (columnPtr != NULL)
1053 {
1054 // variable definition and initialization:
1055 DataBrowserTableViewColumnIndex Position;
1056 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1057
1058 wxCHECK_MSG(MacDataViewListCtrlPtr->GetColumnIndex(columnPtr->GetPropertyID(),&Position) == noErr,-1,_("Could not determine column's position"));
1059 return static_cast<int>(Position);
1060 } /* if */
1061 else
1062 return wxNOT_FOUND;
1063 } /* wxDataViewCtrl::GetColumnPosition(wxDataViewColumn const*) const */
1064
1065 bool wxDataViewCtrl::PrependColumn(wxDataViewColumn* columnPtr)
1066 {
1067 DataBrowserListViewColumnDesc columnDescription;
1068
1069 DataBrowserPropertyID NewPropertyID;
1070
1071 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1072
1073 wxMacCFStringHolder title(columnPtr->GetTitle(),this->m_font.Ok() ? this->m_font.GetEncoding() : wxLocale::GetSystemEncoding());
1074
1075
1076 // first, some error checking:
1077 wxCHECK_MSG(MacDataViewListCtrlPtr != NULL, false,_("m_peer is not or incorrectly initialized"));
1078 wxCHECK_MSG(columnPtr != NULL, false,_("Column pointer must not be NULL."));
1079 wxCHECK_MSG(columnPtr->GetRenderer() != NULL, false,_("Column does not have a renderer."));
1080 wxCHECK_MSG(this->GetModel() != NULL, false,_("No model associated with control."));
1081 wxCHECK_MSG((columnPtr->GetModelColumn() >= 0) &&
1082 (columnPtr->GetModelColumn() < this->GetModel()->GetColumnCount()),false,_("Column's model column has no equivalent in the associated model."));
1083
1084 // try to get new ID for the column:
1085 wxCHECK_MSG(MacDataViewListCtrlPtr->GetFreePropertyID(&NewPropertyID) == noErr,false,_("Cannot create new column's ID. Probably max. number of columns reached."));
1086 // full column variable initialization:
1087 columnPtr->SetPropertyID(NewPropertyID);
1088 // add column to wxWidget's internal structure:
1089 wxCHECK_MSG(this->wxDataViewCtrlBase::AppendColumn(columnPtr) &&
1090 this->m_ColumnPointers.insert(ColumnPointerHashMapType::value_type(NewPropertyID,columnPtr)).second,false,_("Could not add column to internal structures."));
1091 // create a column description and add column to the native control:
1092 wxCHECK_MSG(::InitializeColumnDescription(columnDescription,columnPtr,NewPropertyID,title),false,_("Column description could not be initialized."));
1093 wxCHECK_MSG(MacDataViewListCtrlPtr->AddColumn(&columnDescription,0) == noErr, false,_("Column could not be added."));
1094
1095 // final adjustments for the layout:
1096 wxCHECK_MSG(MacDataViewListCtrlPtr->SetColumnWidth(NewPropertyID,columnPtr->GetWidth()) == noErr,false,_("Column width could not be set."));
1097
1098 // make sure that the data is up-to-date...
1099 // if the newly appended column is the first column add the initial data to the control and mark the column as an expander column,
1100 // otherwise ask the control to 'update' the data in the newly appended column:
1101 if (this->GetColumnCount() == 1)
1102 {
1103 this->SetExpanderColumn(columnPtr);
1104 this->AddChildrenLevel(wxDataViewItem());
1105 } /* if */
1106 else
1107 MacDataViewListCtrlPtr->UpdateItems(kDataBrowserNoItem,0,NULL,kDataBrowserItemNoProperty,NewPropertyID);
1108 // done:
1109 return true;
1110 } /* wxDataViewCtrl::PrependColumn(wxDataViewColumn*) */
1111
1112 void wxDataViewCtrl::Collapse(wxDataViewItem const& item)
1113 {
1114 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1115
1116
1117 MacDataViewListCtrlPtr->CloseContainer(reinterpret_cast<DataBrowserItemID>(item.GetID()));
1118 } /* wxDataViewCtrl::Collapse(wxDataViewItem const&) */
1119
1120 void wxDataViewCtrl::EnsureVisible(wxDataViewItem const& item, wxDataViewColumn const* columnPtr)
1121 {
1122 if (item.IsOk())
1123 {
1124 // variable definition and initialization:
1125 DataBrowserPropertyID propertyID;
1126 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1127
1128 if (columnPtr != NULL)
1129 propertyID = columnPtr->GetPropertyID();
1130 else
1131 propertyID = kDataBrowserNoItem;
1132 MacDataViewListCtrlPtr->RevealItem(reinterpret_cast<DataBrowserItemID>(item.GetID()),propertyID,kDataBrowserRevealOnly);
1133 } /* if */
1134 } /* wxDataViewCtrl::EnsureVisible(wxDataViewItem const&, wxDataViewColumn const*) */
1135
1136 void wxDataViewCtrl::Expand(wxDataViewItem const& item)
1137 {
1138 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1139
1140
1141 MacDataViewListCtrlPtr->OpenContainer(reinterpret_cast<DataBrowserItemID>(item.GetID()));
1142 } /* wxDataViewCtrl::Expand(wxDataViewItem const&) */
1143
1144 wxDataViewColumn* wxDataViewCtrl::GetSortingColumn(void) const
1145 {
1146 DataBrowserPropertyID propertyID;
1147
1148 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1149
1150
1151 if (MacDataViewListCtrlPtr->GetSortProperty(&propertyID) == noErr)
1152 return this->GetColumnPtr(propertyID);
1153 else
1154 return NULL;
1155 } /* wxDataViewCtrl::GetSortingColumn(void) const */
1156
1157 unsigned int wxDataViewCtrl::GetCount(void) const
1158 {
1159 ItemCount noOfItems;
1160
1161
1162 wxCHECK_MSG(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer)->GetItemCount(&noOfItems) == noErr,0,_("Could not determine number of items"));
1163 return noOfItems;
1164 } /* wxDataViewCtrl::GetCount(void) const */
1165
1166 wxRect wxDataViewCtrl::GetItemRect(wxDataViewItem const& item, wxDataViewColumn const* columnPtr) const
1167 {
1168 if (item.IsOk() && (columnPtr != NULL))
1169 {
1170 // variable definition:
1171 Rect MacRectangle;
1172 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1173
1174 if (MacDataViewListCtrlPtr->GetPartBounds(reinterpret_cast<DataBrowserItemID>(item.GetID()),columnPtr->GetPropertyID(),kDataBrowserPropertyContentPart,&MacRectangle) == noErr)
1175 {
1176 // variable definition:
1177 wxRect rectangle;
1178
1179 ::wxMacNativeToRect(&MacRectangle,&rectangle);
1180 return rectangle;
1181 } /* if */
1182 else
1183 return wxRect();
1184 } /* if */
1185 else
1186 return wxRect();
1187 } /* wxDataViewCtrl::GetItemRect(wxDataViewItem const&, unsigned int) const */
1188
1189 wxDataViewItem wxDataViewCtrl::GetSelection(void) const
1190 {
1191 wxArrayDataBrowserItemID itemIDs;
1192
1193 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1194
1195
1196 if (MacDataViewListCtrlPtr->GetSelectedItemIDs(itemIDs) > 0)
1197 return wxDataViewItem(reinterpret_cast<void*>(itemIDs[0]));
1198 else
1199 return wxDataViewItem();
1200 } /* wxDataViewCtrl::GetSelection(void) const */
1201
1202 int wxDataViewCtrl::GetSelections(wxDataViewItemArray& sel) const
1203 {
1204 size_t NoOfSelectedItems;
1205
1206 wxArrayDataBrowserItemID itemIDs;
1207
1208 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1209
1210
1211 NoOfSelectedItems = MacDataViewListCtrlPtr->GetSelectedItemIDs(itemIDs);
1212 sel.Empty();
1213 sel.SetCount(NoOfSelectedItems);
1214 for (size_t i=0; i<NoOfSelectedItems; ++i)
1215 sel[i] = wxDataViewItem(reinterpret_cast<void*>(itemIDs[i]));
1216 return static_cast<int>(NoOfSelectedItems);
1217 } /* wxDataViewCtrl::GetSelections(wxDataViewItemArray&) const */
1218
1219 void wxDataViewCtrl::HitTest(wxPoint const& point, wxDataViewItem& item, wxDataViewColumn*& columnPtr) const
1220 {
1221 item = wxDataViewItem();
1222 columnPtr = NULL;
1223 } /* wxDataViewCtrl::HitTest(wxPoint const&, wxDataViewItem&, wxDataViewColumn*&) const */
1224
1225 bool wxDataViewCtrl::IsSelected(wxDataViewItem const& item) const
1226 {
1227 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1228
1229
1230 return MacDataViewListCtrlPtr->IsItemSelected(reinterpret_cast<DataBrowserItemID>(item.GetID()));
1231 } /* wxDataViewCtrl::IsSelected(wxDataViewItem const&) const */
1232
1233 void wxDataViewCtrl::SelectAll(void)
1234 {
1235 DataBrowserItemID* itemIDPtr;
1236
1237 Handle handle(::NewHandle(0));
1238
1239 size_t NoOfItems;
1240
1241 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1242
1243
1244 wxCHECK_RET(MacDataViewListCtrlPtr->GetItems(kDataBrowserNoItem,true,kDataBrowserItemAnyState,handle) == noErr,_("Could not get items."));
1245 NoOfItems = static_cast<size_t>(::GetHandleSize(handle)/sizeof(DataBrowserItemID));
1246 HLock(handle);
1247 itemIDPtr = (DataBrowserItemID*) (*handle);
1248 MacDataViewListCtrlPtr->SetSelectedItems(NoOfItems,itemIDPtr,kDataBrowserItemsAssign);
1249 HUnlock(handle);
1250 DisposeHandle(handle);
1251 } /* wxDataViewCtrl::SelectAll(void) */
1252
1253 void wxDataViewCtrl::Select(wxDataViewItem const& item)
1254 {
1255 if (item.IsOk())
1256 {
1257 // variable definition and initialization:
1258 DataBrowserItemID itemID(reinterpret_cast<DataBrowserItemID>(item.GetID()));
1259 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1260
1261 MacDataViewListCtrlPtr->SetSelectedItems(1,&itemID,kDataBrowserItemsAdd);
1262 } /* if */
1263 } /* wxDataViewCtrl::Select(wxDataViewItem const&) */
1264
1265 void wxDataViewCtrl::SetSelections(wxDataViewItemArray const& sel)
1266 {
1267 size_t const NoOfSelections = sel.GetCount();
1268
1269 DataBrowserItemID* itemIDs;
1270
1271 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1272
1273
1274 itemIDs = new DataBrowserItemID[NoOfSelections];
1275 for (size_t i=0; i<NoOfSelections; ++i)
1276 itemIDs[i] = reinterpret_cast<DataBrowserItemID>(sel[i].GetID());
1277 MacDataViewListCtrlPtr->SetSelectedItems(NoOfSelections,itemIDs,kDataBrowserItemsAssign);
1278 delete[] itemIDs;
1279 } /* wxDataViewCtrl::SetSelections(wxDataViewItemArray const&) */
1280
1281 void wxDataViewCtrl::Unselect(wxDataViewItem const& item)
1282 {
1283 if (item.IsOk())
1284 {
1285 // variable definition and initialization:
1286 DataBrowserItemID itemID(reinterpret_cast<DataBrowserItemID>(item.GetID()));
1287 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1288
1289 MacDataViewListCtrlPtr->SetSelectedItems(1,&itemID,kDataBrowserItemsRemove);
1290 } /* if */
1291 } /* wxDataViewCtrl::Unselect(wxDataViewItem const&) */
1292
1293 void wxDataViewCtrl::UnselectAll(void)
1294 {
1295 DataBrowserItemID* itemIDPtr;
1296
1297 Handle handle(::NewHandle(0));
1298
1299 size_t NoOfItems;
1300
1301 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1302
1303
1304 wxCHECK_RET(MacDataViewListCtrlPtr->GetItems(kDataBrowserNoItem,true,kDataBrowserItemAnyState,handle) == noErr,_("Could not get items."));
1305 NoOfItems = static_cast<size_t>(::GetHandleSize(handle)/sizeof(DataBrowserItemID));
1306 HLock(handle);
1307 itemIDPtr = (DataBrowserItemID*) (*handle);
1308 MacDataViewListCtrlPtr->SetSelectedItems(NoOfItems,itemIDPtr,kDataBrowserItemsRemove);
1309 HUnlock(handle);
1310 DisposeHandle(handle);
1311 } /* wxDataViewCtrl::UnselectAll(void) */
1312
1313 // data handling:
1314 void wxDataViewCtrl::AddChildrenLevel(wxDataViewItem const& parentItem)
1315 {
1316 int NoOfChildren;
1317
1318 wxDataViewItemArray items;
1319
1320
1321 wxCHECK_RET(this->GetModel() != NULL,_("Model pointer not initialized."));
1322 NoOfChildren = this->GetModel()->GetChildren(parentItem,items);
1323 #if 0
1324 for (int i=0; i<NoOfChildren; ++i)
1325 (void) this->GetModel()->ItemAdded(parentItem,items[i]);
1326 #else
1327 (void) this->GetModel()->ItemsAdded(parentItem,items);
1328 #endif
1329 } /* wxDataViewCtrl::AddChildrenLevel(wxDataViewItem const&) */
1330
1331 wxDataViewColumn* wxDataViewCtrl::GetColumnPtr(WXDataBrowserPropertyID propertyID) const
1332 {
1333 // variable definition:
1334 ColumnPointerHashMapType::const_iterator Result(this->m_ColumnPointers.find(propertyID));
1335
1336 if (Result != this->m_ColumnPointers.end())
1337 return Result->second;
1338 else
1339 return NULL;
1340 } /* wxDataViewCtrl::GetColumnPtr(DataBrowserPropertyID) const */
1341
1342 // inherited methods from wxDataViewCtrlBase
1343 void wxDataViewCtrl::DoSetExpanderColumn(void)
1344 {
1345 if (this->GetExpanderColumn() != NULL)
1346 {
1347 // variable definition and initialization:
1348 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1349
1350 (void) MacDataViewListCtrlPtr->SetDisclosureColumn(this->GetExpanderColumn()->GetPropertyID());
1351 } /* if */
1352 } /* wxDataViewCtrl::DoSetExpanderColumn(void) */
1353
1354 void wxDataViewCtrl::DoSetIndent(void)
1355 {
1356 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1357
1358
1359 (void) MacDataViewListCtrlPtr->SetIndent(static_cast<float>(this->GetIndent()));
1360 } /* wxDataViewCtrl::DoSetIndent(void) */
1361
1362 // event handling:
1363 void wxDataViewCtrl::OnSize(wxSizeEvent& event)
1364 {
1365 unsigned int const NoOfColumns = this->GetColumnCount();
1366
1367
1368 for (unsigned int i=0; i<NoOfColumns; ++i)
1369 {
1370 // variable definition and initialization:
1371 wxDataViewColumn* dataViewColumnPtr(this->GetColumn(i));
1372
1373 if (dataViewColumnPtr != NULL)
1374 {
1375 // variable definition and initialization:
1376 wxDataViewCustomRenderer* dataViewCustomRendererPtr(dynamic_cast<wxDataViewCustomRenderer*>(dataViewColumnPtr->GetRenderer()));
1377
1378 if (dataViewCustomRendererPtr != NULL)
1379 dataViewCustomRendererPtr->SetDC(NULL); // reset DC because DC has changed
1380 } /* if */
1381 } /* for */
1382 event.Skip();
1383 } /* wxDataViewCtrl::OnSize(wxSizeEvent&) */
1384
1385 IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl,wxDataViewCtrlBase)
1386
1387 BEGIN_EVENT_TABLE(wxDataViewCtrl,wxDataViewCtrlBase)
1388 EVT_SIZE(wxDataViewCtrl::OnSize)
1389 END_EVENT_TABLE()
1390
1391 #endif
1392 // !wxUSE_GENERICDATAVIEWCTRL
1393
1394 #endif
1395 // wxUSE_DATAVIEWCTRL
1396