]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/dataview.cpp
2f993637e205556f22d2fcd1629781a58a5457ec
[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, wxCFStringRef 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, wxCFStringRef 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) ? *wxWHITE : 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 wxWindowDC(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 wxCFStringRef 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 wxCFStringRef 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 wxCFStringRef 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 ::SetDataBrowserTableViewHiliteStyle( this->m_peer->GetControlRef(), kDataBrowserTableViewFillHilite );
937
938 return true;
939 } /* wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator) */
940
941 bool wxDataViewCtrl::AssociateModel(wxDataViewModel* model)
942 {
943 if (!wxDataViewCtrlBase::AssociateModel(model))
944 return false;
945
946 model->AddNotifier(new wxMacDataViewModelNotifier(dynamic_cast<wxMacDataViewDataBrowserListViewControl*>(this->m_peer)));
947
948 return true;
949 } /* wxDataViewCtrl::AssociateModel(wxDataViewModel*) */
950
951 bool wxDataViewCtrl::AppendColumn(wxDataViewColumn* columnPtr)
952 {
953 DataBrowserListViewColumnDesc columnDescription;
954
955 DataBrowserPropertyID NewPropertyID;
956
957 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
958
959 wxCFStringRef title(columnPtr->GetTitle(),this->m_font.Ok() ? this->m_font.GetEncoding() : wxLocale::GetSystemEncoding());
960
961
962 // first, some error checking:
963 wxCHECK_MSG(MacDataViewListCtrlPtr != NULL, false,_("m_peer is not or incorrectly initialized"));
964 wxCHECK_MSG(columnPtr != NULL, false,_("Column pointer must not be NULL."));
965 wxCHECK_MSG(columnPtr->GetRenderer() != NULL, false,_("Column does not have a renderer."));
966 wxCHECK_MSG(this->GetModel() != NULL, false,_("No model associated with control."));
967 wxCHECK_MSG((columnPtr->GetModelColumn() >= 0) &&
968 (columnPtr->GetModelColumn() < this->GetModel()->GetColumnCount()),false,_("Column's model column has no equivalent in the associated model."));
969
970 // try to get new ID for the column:
971 wxCHECK_MSG(MacDataViewListCtrlPtr->GetFreePropertyID(&NewPropertyID) == noErr,false,_("Cannot create new column's ID. Probably max. number of columns reached."));
972 // full column variable initialization:
973 columnPtr->SetPropertyID(NewPropertyID);
974 // add column to wxWidget's internal structure:
975 wxCHECK_MSG(this->wxDataViewCtrlBase::AppendColumn(columnPtr) &&
976 this->m_ColumnPointers.insert(ColumnPointerHashMapType::value_type(NewPropertyID,columnPtr)).second,false,_("Could not add column to internal structures."));
977 // create a column description and add column to the native control:
978 wxCHECK_MSG(::InitializeColumnDescription(columnDescription,columnPtr,NewPropertyID,title), false,_("Column description could not be initialized."));
979 wxCHECK_MSG(MacDataViewListCtrlPtr->AddColumn(&columnDescription,kDataBrowserListViewAppendColumn) == noErr,false,_("Column could not be added."));
980
981 // final adjustments for the layout:
982 wxCHECK_MSG(MacDataViewListCtrlPtr->SetColumnWidth(NewPropertyID,columnPtr->GetWidth()) == noErr,false,_("Column width could not be set."));
983
984 // make sure that the data is up-to-date...
985 // if the newly appended column is the first column add the initial data to the control and mark the column as an expander column,
986 // otherwise ask the control to 'update' the data in the newly appended column:
987 if (this->GetColumnCount() == 1)
988 {
989 this->SetExpanderColumn(columnPtr);
990 this->AddChildrenLevel(wxDataViewItem());
991 } /* if */
992 else
993 MacDataViewListCtrlPtr->UpdateItems(kDataBrowserNoItem,0,NULL,kDataBrowserItemNoProperty,NewPropertyID);
994 // done:
995 return true;
996 } /* wxDataViewCtrl::AppendColumn(wxDataViewColumn*) */
997
998 bool wxDataViewCtrl::ClearColumns(void)
999 {
1000 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1001
1002
1003 while (this->m_ColumnPointers.begin() != this->m_ColumnPointers.end())
1004 {
1005 wxCHECK_MSG(MacDataViewListCtrlPtr->RemoveColumnByProperty(this->m_ColumnPointers.begin()->first) == noErr,false,_("Could not remove column."));
1006 delete this->m_ColumnPointers.begin()->second;
1007 this->m_ColumnPointers.erase(this->m_ColumnPointers.begin());
1008 } /* while */
1009 return true;
1010 } /* wxDataViewCtrl::ClearColumns(void) */
1011
1012 bool wxDataViewCtrl::DeleteColumn(wxDataViewColumn* columnPtr)
1013 {
1014 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1015
1016
1017 if ((MacDataViewListCtrlPtr->RemoveColumnByProperty(columnPtr->GetPropertyID()) == noErr) && (this->m_ColumnPointers.erase(columnPtr->GetPropertyID()) > 0))
1018 {
1019 delete columnPtr;
1020 return true;
1021 } /* if */
1022 else
1023 return false;
1024 } /* wxDataViewCtrl::DeleteColumn(wxDataViewColumn*) */
1025
1026 wxDataViewColumn* wxDataViewCtrl::GetColumn(unsigned int pos) const
1027 {
1028 DataBrowserPropertyID propertyID;
1029
1030 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1031
1032
1033 if (MacDataViewListCtrlPtr->GetPropertyID(pos,&propertyID) == noErr)
1034 {
1035 // variable definition:
1036 ColumnPointerHashMapType::const_iterator Result(this->m_ColumnPointers.find(propertyID));
1037
1038 if (Result != this->m_ColumnPointers.end())
1039 return Result->second;
1040 else
1041 return NULL;
1042 } /* if */
1043 else
1044 return NULL;
1045 } /* wxDataViewCtrl::GetColumn(unsigned int pos) const */
1046
1047 unsigned int wxDataViewCtrl::GetColumnCount(void) const
1048 {
1049 return this->m_ColumnPointers.size();
1050 } /* wxDataViewCtrl::GetColumnCount(void) const */
1051
1052 int wxDataViewCtrl::GetColumnPosition(wxDataViewColumn const* columnPtr) const
1053 {
1054 if (columnPtr != NULL)
1055 {
1056 // variable definition and initialization:
1057 DataBrowserTableViewColumnIndex Position;
1058 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1059
1060 wxCHECK_MSG(MacDataViewListCtrlPtr->GetColumnIndex(columnPtr->GetPropertyID(),&Position) == noErr,-1,_("Could not determine column's position"));
1061 return static_cast<int>(Position);
1062 } /* if */
1063 else
1064 return wxNOT_FOUND;
1065 } /* wxDataViewCtrl::GetColumnPosition(wxDataViewColumn const*) const */
1066
1067 bool wxDataViewCtrl::PrependColumn(wxDataViewColumn* columnPtr)
1068 {
1069 DataBrowserListViewColumnDesc columnDescription;
1070
1071 DataBrowserPropertyID NewPropertyID;
1072
1073 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1074
1075 wxCFStringRef title(columnPtr->GetTitle(),this->m_font.Ok() ? this->m_font.GetEncoding() : wxLocale::GetSystemEncoding());
1076
1077
1078 // first, some error checking:
1079 wxCHECK_MSG(MacDataViewListCtrlPtr != NULL, false,_("m_peer is not or incorrectly initialized"));
1080 wxCHECK_MSG(columnPtr != NULL, false,_("Column pointer must not be NULL."));
1081 wxCHECK_MSG(columnPtr->GetRenderer() != NULL, false,_("Column does not have a renderer."));
1082 wxCHECK_MSG(this->GetModel() != NULL, false,_("No model associated with control."));
1083 wxCHECK_MSG((columnPtr->GetModelColumn() >= 0) &&
1084 (columnPtr->GetModelColumn() < this->GetModel()->GetColumnCount()),false,_("Column's model column has no equivalent in the associated model."));
1085
1086 // try to get new ID for the column:
1087 wxCHECK_MSG(MacDataViewListCtrlPtr->GetFreePropertyID(&NewPropertyID) == noErr,false,_("Cannot create new column's ID. Probably max. number of columns reached."));
1088 // full column variable initialization:
1089 columnPtr->SetPropertyID(NewPropertyID);
1090 // add column to wxWidget's internal structure:
1091 wxCHECK_MSG(this->wxDataViewCtrlBase::AppendColumn(columnPtr) &&
1092 this->m_ColumnPointers.insert(ColumnPointerHashMapType::value_type(NewPropertyID,columnPtr)).second,false,_("Could not add column to internal structures."));
1093 // create a column description and add column to the native control:
1094 wxCHECK_MSG(::InitializeColumnDescription(columnDescription,columnPtr,NewPropertyID,title),false,_("Column description could not be initialized."));
1095 wxCHECK_MSG(MacDataViewListCtrlPtr->AddColumn(&columnDescription,0) == noErr, false,_("Column could not be added."));
1096
1097 // final adjustments for the layout:
1098 wxCHECK_MSG(MacDataViewListCtrlPtr->SetColumnWidth(NewPropertyID,columnPtr->GetWidth()) == noErr,false,_("Column width could not be set."));
1099
1100 // make sure that the data is up-to-date...
1101 // if the newly appended column is the first column add the initial data to the control and mark the column as an expander column,
1102 // otherwise ask the control to 'update' the data in the newly appended column:
1103 if (this->GetColumnCount() == 1)
1104 {
1105 this->SetExpanderColumn(columnPtr);
1106 this->AddChildrenLevel(wxDataViewItem());
1107 } /* if */
1108 else
1109 MacDataViewListCtrlPtr->UpdateItems(kDataBrowserNoItem,0,NULL,kDataBrowserItemNoProperty,NewPropertyID);
1110 // done:
1111 return true;
1112 } /* wxDataViewCtrl::PrependColumn(wxDataViewColumn*) */
1113
1114 void wxDataViewCtrl::Collapse(wxDataViewItem const& item)
1115 {
1116 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1117
1118
1119 MacDataViewListCtrlPtr->CloseContainer(reinterpret_cast<DataBrowserItemID>(item.GetID()));
1120 } /* wxDataViewCtrl::Collapse(wxDataViewItem const&) */
1121
1122 void wxDataViewCtrl::EnsureVisible(wxDataViewItem const& item, wxDataViewColumn const* columnPtr)
1123 {
1124 if (item.IsOk())
1125 {
1126 // variable definition and initialization:
1127 DataBrowserPropertyID propertyID;
1128 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1129
1130 if (columnPtr != NULL)
1131 propertyID = columnPtr->GetPropertyID();
1132 else
1133 propertyID = kDataBrowserNoItem;
1134 MacDataViewListCtrlPtr->RevealItem(reinterpret_cast<DataBrowserItemID>(item.GetID()),propertyID,kDataBrowserRevealOnly);
1135 } /* if */
1136 } /* wxDataViewCtrl::EnsureVisible(wxDataViewItem const&, wxDataViewColumn const*) */
1137
1138 void wxDataViewCtrl::Expand(wxDataViewItem const& item)
1139 {
1140 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1141
1142
1143 MacDataViewListCtrlPtr->OpenContainer(reinterpret_cast<DataBrowserItemID>(item.GetID()));
1144 } /* wxDataViewCtrl::Expand(wxDataViewItem const&) */
1145
1146 wxDataViewColumn* wxDataViewCtrl::GetSortingColumn(void) const
1147 {
1148 DataBrowserPropertyID propertyID;
1149
1150 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1151
1152
1153 if (MacDataViewListCtrlPtr->GetSortProperty(&propertyID) == noErr)
1154 return this->GetColumnPtr(propertyID);
1155 else
1156 return NULL;
1157 } /* wxDataViewCtrl::GetSortingColumn(void) const */
1158
1159 unsigned int wxDataViewCtrl::GetCount(void) const
1160 {
1161 ItemCount noOfItems;
1162
1163
1164 wxCHECK_MSG(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer)->GetItemCount(&noOfItems) == noErr,0,_("Could not determine number of items"));
1165 return noOfItems;
1166 } /* wxDataViewCtrl::GetCount(void) const */
1167
1168 wxRect wxDataViewCtrl::GetItemRect(wxDataViewItem const& item, wxDataViewColumn const* columnPtr) const
1169 {
1170 if (item.IsOk() && (columnPtr != NULL))
1171 {
1172 // variable definition:
1173 Rect MacRectangle;
1174 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1175
1176 if (MacDataViewListCtrlPtr->GetPartBounds(reinterpret_cast<DataBrowserItemID>(item.GetID()),columnPtr->GetPropertyID(),kDataBrowserPropertyContentPart,&MacRectangle) == noErr)
1177 {
1178 // variable definition:
1179 wxRect rectangle;
1180
1181 ::wxMacNativeToRect(&MacRectangle,&rectangle);
1182 return rectangle;
1183 } /* if */
1184 else
1185 return wxRect();
1186 } /* if */
1187 else
1188 return wxRect();
1189 } /* wxDataViewCtrl::GetItemRect(wxDataViewItem const&, unsigned int) const */
1190
1191 wxDataViewItem wxDataViewCtrl::GetSelection(void) const
1192 {
1193 wxArrayDataBrowserItemID itemIDs;
1194
1195 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1196
1197
1198 if (MacDataViewListCtrlPtr->GetSelectedItemIDs(itemIDs) > 0)
1199 return wxDataViewItem(reinterpret_cast<void*>(itemIDs[0]));
1200 else
1201 return wxDataViewItem();
1202 } /* wxDataViewCtrl::GetSelection(void) const */
1203
1204 int wxDataViewCtrl::GetSelections(wxDataViewItemArray& sel) const
1205 {
1206 size_t NoOfSelectedItems;
1207
1208 wxArrayDataBrowserItemID itemIDs;
1209
1210 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1211
1212
1213 NoOfSelectedItems = MacDataViewListCtrlPtr->GetSelectedItemIDs(itemIDs);
1214 sel.Empty();
1215 sel.SetCount(NoOfSelectedItems);
1216 for (size_t i=0; i<NoOfSelectedItems; ++i)
1217 sel[i] = wxDataViewItem(reinterpret_cast<void*>(itemIDs[i]));
1218 return static_cast<int>(NoOfSelectedItems);
1219 } /* wxDataViewCtrl::GetSelections(wxDataViewItemArray&) const */
1220
1221 void wxDataViewCtrl::HitTest(wxPoint const& point, wxDataViewItem& item, wxDataViewColumn*& columnPtr) const
1222 {
1223 item = wxDataViewItem();
1224 columnPtr = NULL;
1225 } /* wxDataViewCtrl::HitTest(wxPoint const&, wxDataViewItem&, wxDataViewColumn*&) const */
1226
1227 bool wxDataViewCtrl::IsSelected(wxDataViewItem const& item) const
1228 {
1229 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1230
1231
1232 return MacDataViewListCtrlPtr->IsItemSelected(reinterpret_cast<DataBrowserItemID>(item.GetID()));
1233 } /* wxDataViewCtrl::IsSelected(wxDataViewItem const&) const */
1234
1235 void wxDataViewCtrl::SelectAll(void)
1236 {
1237 DataBrowserItemID* itemIDPtr;
1238
1239 Handle handle(::NewHandle(0));
1240
1241 size_t NoOfItems;
1242
1243 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1244
1245
1246 wxCHECK_RET(MacDataViewListCtrlPtr->GetItems(kDataBrowserNoItem,true,kDataBrowserItemAnyState,handle) == noErr,_("Could not get items."));
1247 NoOfItems = static_cast<size_t>(::GetHandleSize(handle)/sizeof(DataBrowserItemID));
1248 HLock(handle);
1249 itemIDPtr = (DataBrowserItemID*) (*handle);
1250 MacDataViewListCtrlPtr->SetSelectedItems(NoOfItems,itemIDPtr,kDataBrowserItemsAssign);
1251 HUnlock(handle);
1252 DisposeHandle(handle);
1253 } /* wxDataViewCtrl::SelectAll(void) */
1254
1255 void wxDataViewCtrl::Select(wxDataViewItem const& item)
1256 {
1257 if (item.IsOk())
1258 {
1259 // variable definition and initialization:
1260 DataBrowserItemID itemID(reinterpret_cast<DataBrowserItemID>(item.GetID()));
1261 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1262
1263 MacDataViewListCtrlPtr->SetSelectedItems(1,&itemID,kDataBrowserItemsAdd);
1264 } /* if */
1265 } /* wxDataViewCtrl::Select(wxDataViewItem const&) */
1266
1267 void wxDataViewCtrl::SetSelections(wxDataViewItemArray const& sel)
1268 {
1269 size_t const NoOfSelections = sel.GetCount();
1270
1271 DataBrowserItemID* itemIDs;
1272
1273 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1274
1275
1276 itemIDs = new DataBrowserItemID[NoOfSelections];
1277 for (size_t i=0; i<NoOfSelections; ++i)
1278 itemIDs[i] = reinterpret_cast<DataBrowserItemID>(sel[i].GetID());
1279 MacDataViewListCtrlPtr->SetSelectedItems(NoOfSelections,itemIDs,kDataBrowserItemsAssign);
1280 delete[] itemIDs;
1281 } /* wxDataViewCtrl::SetSelections(wxDataViewItemArray const&) */
1282
1283 void wxDataViewCtrl::Unselect(wxDataViewItem const& item)
1284 {
1285 if (item.IsOk())
1286 {
1287 // variable definition and initialization:
1288 DataBrowserItemID itemID(reinterpret_cast<DataBrowserItemID>(item.GetID()));
1289 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1290
1291 MacDataViewListCtrlPtr->SetSelectedItems(1,&itemID,kDataBrowserItemsRemove);
1292 } /* if */
1293 } /* wxDataViewCtrl::Unselect(wxDataViewItem const&) */
1294
1295 void wxDataViewCtrl::UnselectAll(void)
1296 {
1297 DataBrowserItemID* itemIDPtr;
1298
1299 Handle handle(::NewHandle(0));
1300
1301 size_t NoOfItems;
1302
1303 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1304
1305
1306 wxCHECK_RET(MacDataViewListCtrlPtr->GetItems(kDataBrowserNoItem,true,kDataBrowserItemAnyState,handle) == noErr,_("Could not get items."));
1307 NoOfItems = static_cast<size_t>(::GetHandleSize(handle)/sizeof(DataBrowserItemID));
1308 HLock(handle);
1309 itemIDPtr = (DataBrowserItemID*) (*handle);
1310 MacDataViewListCtrlPtr->SetSelectedItems(NoOfItems,itemIDPtr,kDataBrowserItemsRemove);
1311 HUnlock(handle);
1312 DisposeHandle(handle);
1313 } /* wxDataViewCtrl::UnselectAll(void) */
1314
1315 // data handling:
1316 void wxDataViewCtrl::AddChildrenLevel(wxDataViewItem const& parentItem)
1317 {
1318 int NoOfChildren;
1319
1320 wxDataViewItemArray items;
1321
1322
1323 wxCHECK_RET(this->GetModel() != NULL,_("Model pointer not initialized."));
1324 NoOfChildren = this->GetModel()->GetChildren(parentItem,items);
1325 #if 0
1326 for (int i=0; i<NoOfChildren; ++i)
1327 (void) this->GetModel()->ItemAdded(parentItem,items[i]);
1328 #else
1329 (void) this->GetModel()->ItemsAdded(parentItem,items);
1330 #endif
1331 } /* wxDataViewCtrl::AddChildrenLevel(wxDataViewItem const&) */
1332
1333 wxDataViewColumn* wxDataViewCtrl::GetColumnPtr(WXDataBrowserPropertyID propertyID) const
1334 {
1335 // variable definition:
1336 ColumnPointerHashMapType::const_iterator Result(this->m_ColumnPointers.find(propertyID));
1337
1338 if (Result != this->m_ColumnPointers.end())
1339 return Result->second;
1340 else
1341 return NULL;
1342 } /* wxDataViewCtrl::GetColumnPtr(DataBrowserPropertyID) const */
1343
1344 // inherited methods from wxDataViewCtrlBase
1345 void wxDataViewCtrl::DoSetExpanderColumn(void)
1346 {
1347 if (this->GetExpanderColumn() != NULL)
1348 {
1349 // variable definition and initialization:
1350 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1351
1352 (void) MacDataViewListCtrlPtr->SetDisclosureColumn(this->GetExpanderColumn()->GetPropertyID());
1353 } /* if */
1354 } /* wxDataViewCtrl::DoSetExpanderColumn(void) */
1355
1356 void wxDataViewCtrl::DoSetIndent(void)
1357 {
1358 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(this->m_peer));
1359
1360
1361 (void) MacDataViewListCtrlPtr->SetIndent(static_cast<float>(this->GetIndent()));
1362 } /* wxDataViewCtrl::DoSetIndent(void) */
1363
1364 // event handling:
1365 void wxDataViewCtrl::OnSize(wxSizeEvent& event)
1366 {
1367 unsigned int const NoOfColumns = this->GetColumnCount();
1368
1369
1370 for (unsigned int i=0; i<NoOfColumns; ++i)
1371 {
1372 // variable definition and initialization:
1373 wxDataViewColumn* dataViewColumnPtr(this->GetColumn(i));
1374
1375 if (dataViewColumnPtr != NULL)
1376 {
1377 // variable definition and initialization:
1378 wxDataViewCustomRenderer* dataViewCustomRendererPtr(dynamic_cast<wxDataViewCustomRenderer*>(dataViewColumnPtr->GetRenderer()));
1379
1380 if (dataViewCustomRendererPtr != NULL)
1381 dataViewCustomRendererPtr->SetDC(NULL); // reset DC because DC has changed
1382 } /* if */
1383 } /* for */
1384 event.Skip();
1385 } /* wxDataViewCtrl::OnSize(wxSizeEvent&) */
1386
1387 IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl,wxDataViewCtrlBase)
1388
1389 BEGIN_EVENT_TABLE(wxDataViewCtrl,wxDataViewCtrlBase)
1390 EVT_SIZE(wxDataViewCtrl::OnSize)
1391 END_EVENT_TABLE()
1392
1393 #endif
1394 // !wxUSE_GENERICDATAVIEWCTRL
1395
1396 #endif
1397 // wxUSE_DATAVIEWCTRL
1398