]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/utils.cpp
e38a3074340e3cf3f4f5c77599d4993f5d9dcbb0
[wxWidgets.git] / src / mac / carbon / utils.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/mac/carbon/utils.cpp
3 // Purpose: Various utilities
4 // Author: Stefan Csomor
5 // Modified by:
6 // Created: 1998-01-01
7 // RCS-ID: $Id$
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #include "wx/wxprec.h"
13
14 #include "wx/utils.h"
15
16 #ifndef WX_PRECOMP
17 #include "wx/intl.h"
18 #include "wx/app.h"
19 #if wxUSE_GUI
20 #include "wx/toplevel.h"
21 #include "wx/font.h"
22 #endif
23 #endif
24
25 #include "wx/apptrait.h"
26
27 #if wxUSE_GUI
28 #include "wx/mac/uma.h"
29 #endif
30
31 #include <ctype.h>
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <stdarg.h>
37
38 #include "MoreFilesX.h"
39
40 #ifndef __DARWIN__
41 #include <Threads.h>
42 #include <Sound.h>
43 #endif
44
45 #if wxUSE_GUI
46 #if TARGET_API_MAC_OSX
47 #include <CoreServices/CoreServices.h>
48 #else
49 #include <DriverServices.h>
50 #include <Multiprocessing.h>
51 #endif
52
53 #ifdef __DARWIN__
54 #include <Carbon/Carbon.h>
55 #else
56 #include <ATSUnicode.h>
57 #include <TextCommon.h>
58 #include <TextEncodingConverter.h>
59 #endif
60
61 #include "wx/mac/private/timer.h"
62 #endif // wxUSE_GUI
63
64 #include "wx/evtloop.h"
65 #include "wx/mac/private.h"
66
67 #if defined(__MWERKS__) && wxUSE_UNICODE
68 #if __MWERKS__ < 0x4100 || !defined(__DARWIN__)
69 #include <wtime.h>
70 #endif
71 #endif
72
73 #if wxUSE_BASE
74
75 // our OS version is the same in non GUI and GUI cases
76 wxOperatingSystemId wxGetOsVersion(int *majorVsn, int *minorVsn)
77 {
78 SInt32 theSystem;
79 Gestalt(gestaltSystemVersion, &theSystem);
80
81 if ( majorVsn != NULL )
82 *majorVsn = (theSystem >> 8);
83
84 if ( minorVsn != NULL )
85 *minorVsn = (theSystem & 0xFF);
86
87 #if defined( __DARWIN__ )
88 return wxOS_MAC_OSX_DARWIN;
89 #else
90 return wxOS_MAC_OS;
91 #endif
92 }
93
94 // ----------------------------------------------------------------------------
95 // debugging support
96 // ----------------------------------------------------------------------------
97
98 #if defined(__WXDEBUG__) && defined(__WXMAC__) && !defined(__DARWIN__) && defined(__MWERKS__) && (__MWERKS__ >= 0x2400)
99
100 // MetroNub stuff doesn't seem to work in CodeWarrior 5.3 Carbon builds...
101
102 #ifndef __MetroNubUtils__
103 #include "MetroNubUtils.h"
104 #endif
105
106 #ifndef __GESTALT__
107 #include <Gestalt.h>
108 #endif
109
110 #if TARGET_API_MAC_CARBON
111
112 #include <CodeFragments.h>
113
114 extern "C" long CallUniversalProc(UniversalProcPtr theProcPtr, ProcInfoType procInfo, ...);
115
116 ProcPtr gCallUniversalProc_Proc = NULL;
117
118 #endif
119
120 static MetroNubUserEntryBlock* gMetroNubEntry = NULL;
121
122 static long fRunOnce = false;
123
124
125 Boolean IsMetroNubInstalled()
126 {
127 if (!fRunOnce)
128 {
129 long result, value;
130
131 fRunOnce = true;
132 gMetroNubEntry = NULL;
133
134 if (Gestalt(gestaltSystemVersion, &value) == noErr && value < 0x1000)
135 {
136 // look for MetroNub's Gestalt selector
137 if (Gestalt(kMetroNubUserSignature, &result) == noErr)
138 {
139 #if TARGET_API_MAC_CARBON
140 if (gCallUniversalProc_Proc == NULL)
141 {
142 CFragConnectionID connectionID;
143 Ptr mainAddress;
144 Str255 errorString;
145 ProcPtr symbolAddress;
146 OSErr err;
147 CFragSymbolClass symbolClass;
148
149 symbolAddress = NULL;
150 err = GetSharedLibrary("\pInterfaceLib", kPowerPCCFragArch, kFindCFrag,
151 &connectionID, &mainAddress, errorString);
152
153 if (err != noErr)
154 {
155 gCallUniversalProc_Proc = NULL;
156 goto end;
157 }
158
159 err = FindSymbol(connectionID, "\pCallUniversalProc",
160 (Ptr *) &gCallUniversalProc_Proc, &symbolClass);
161
162 if (err != noErr)
163 {
164 gCallUniversalProc_Proc = NULL;
165 goto end;
166 }
167 }
168 #endif
169
170 {
171 MetroNubUserEntryBlock* block = (MetroNubUserEntryBlock *)result;
172
173 // make sure the version of the API is compatible
174 if (block->apiLowVersion <= kMetroNubUserAPIVersion &&
175 kMetroNubUserAPIVersion <= block->apiHiVersion)
176 {
177 // success!
178 gMetroNubEntry = block;
179 }
180 }
181 }
182 }
183 }
184
185 end:
186
187 #if TARGET_API_MAC_CARBON
188 return (gMetroNubEntry != NULL && gCallUniversalProc_Proc != NULL);
189 #else
190 return (gMetroNubEntry != NULL);
191 #endif
192 }
193
194 Boolean IsMWDebuggerRunning()
195 {
196 if (IsMetroNubInstalled())
197 return CallIsDebuggerRunningProc(gMetroNubEntry->isDebuggerRunning);
198
199 return false;
200 }
201
202 Boolean AmIBeingMWDebugged()
203 {
204 if (IsMetroNubInstalled())
205 return CallAmIBeingDebuggedProc(gMetroNubEntry->amIBeingDebugged);
206
207 return false;
208 }
209
210 extern bool WXDLLEXPORT wxIsDebuggerRunning()
211 {
212 return IsMWDebuggerRunning() && AmIBeingMWDebugged();
213 }
214
215 #else
216
217 extern bool WXDLLEXPORT wxIsDebuggerRunning()
218 {
219 return false;
220 }
221
222 #endif // defined(__WXMAC__) && !defined(__DARWIN__) && (__MWERKS__ >= 0x2400)
223
224
225 #ifndef __DARWIN__
226 // defined in unix/utilsunx.cpp for Mac OS X
227
228 // get full hostname (with domain name if possible)
229 bool wxGetFullHostName(wxChar *buf, int maxSize)
230 {
231 return wxGetHostName(buf, maxSize);
232 }
233
234 // Get user ID e.g. jacs
235 bool wxGetUserId(wxChar *buf, int maxSize)
236 {
237 return wxGetUserName( buf , maxSize );
238 }
239
240 const wxChar* wxGetHomeDir(wxString *pstr)
241 {
242 *pstr = wxMacFindFolder( (short) kOnSystemDisk, kPreferencesFolderType, kDontCreateFolder );
243 return pstr->c_str();
244 }
245
246 // Get hostname only (without domain name)
247 bool wxGetHostName(wxChar *buf, int maxSize)
248 {
249 // Gets Chooser name of user by examining a System resource.
250 buf[0] = 0;
251
252 const short kComputerNameID = -16413;
253
254 short oldResFile = CurResFile();
255 UseResFile(0);
256 StringHandle chooserName = (StringHandle)::GetString(kComputerNameID);
257 UseResFile(oldResFile);
258
259 if (chooserName && *chooserName)
260 {
261 HLock( (Handle) chooserName );
262 wxString name = wxMacMakeStringFromPascal( *chooserName );
263 HUnlock( (Handle) chooserName );
264 ReleaseResource( (Handle) chooserName );
265 wxStrncpy( buf , name , maxSize - 1 );
266 }
267
268 return true;
269 }
270
271 // Get user name e.g. Stefan Csomor
272 bool wxGetUserName(wxChar *buf, int maxSize)
273 {
274 // Gets Chooser name of user by examining a System resource.
275 buf[0] = 0;
276
277 const short kChooserNameID = -16096;
278
279 short oldResFile = CurResFile();
280 UseResFile(0);
281 StringHandle chooserName = (StringHandle)::GetString(kChooserNameID);
282 UseResFile(oldResFile);
283
284 if (chooserName && *chooserName)
285 {
286 HLock( (Handle) chooserName );
287 wxString name = wxMacMakeStringFromPascal( *chooserName );
288 HUnlock( (Handle) chooserName );
289 ReleaseResource( (Handle) chooserName );
290 wxStrncpy( buf , name , maxSize - 1 );
291 }
292
293 return true;
294 }
295
296 int wxKill(long pid, wxSignal sig , wxKillError *rc, int flags)
297 {
298 // TODO
299 return 0;
300 }
301
302 WXDLLEXPORT bool wxGetEnv(const wxString& var, wxString *value)
303 {
304 // TODO : under classic there is no environement support, under X yes
305 return false;
306 }
307
308 // set the env var name to the given value, return true on success
309 WXDLLEXPORT bool wxSetEnv(const wxString& var, const wxString& value)
310 {
311 // TODO : under classic there is no environement support, under X yes
312 return false;
313 }
314
315 WXDLLEXPORT bool wxUnsetEnv(const wxString& var)
316 {
317 // TODO : under classic there is no environement support, under X yes
318 return false;
319 }
320
321 // Execute a program in an Interactive Shell
322 bool wxShell(const wxString& command)
323 {
324 // TODO
325 return false;
326 }
327
328 // Shutdown or reboot the PC
329 bool wxShutdown(wxShutdownFlags wFlags)
330 {
331 // TODO
332 return false;
333 }
334
335 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
336 wxMemorySize wxGetFreeMemory()
337 {
338 return (wxMemorySize)FreeMem();
339 }
340
341 #ifndef __DARWIN__
342
343 void wxMicroSleep(unsigned long microseconds)
344 {
345 AbsoluteTime wakeup = AddDurationToAbsolute( microseconds * durationMicrosecond , UpTime());
346 MPDelayUntil( & wakeup);
347 }
348
349 void wxMilliSleep(unsigned long milliseconds)
350 {
351 AbsoluteTime wakeup = AddDurationToAbsolute( milliseconds, UpTime());
352 MPDelayUntil( & wakeup);
353 }
354
355 void wxSleep(int nSecs)
356 {
357 wxMilliSleep(1000*nSecs);
358 }
359
360 #endif
361
362 // Consume all events until no more left
363 void wxFlushEvents()
364 {
365 }
366
367 #endif // !__DARWIN__
368
369 // Emit a beeeeeep
370 void wxBell()
371 {
372 #ifndef __LP64__
373 SysBeep(30);
374 #endif
375 }
376
377
378 #endif // wxUSE_BASE
379
380 #if wxUSE_GUI
381
382 wxPortId wxGUIAppTraits::GetToolkitVersion(int *verMaj, int *verMin) const
383 {
384 // We suppose that toolkit version is the same as OS version under Mac
385 wxGetOsVersion(verMaj, verMin);
386
387 return wxPORT_MAC;
388 }
389
390 wxEventLoopBase* wxGUIAppTraits::CreateEventLoop()
391 {
392 return new wxEventLoop;
393 }
394
395 wxTimerImpl* wxGUIAppTraits::CreateTimerImpl(wxTimer *timer)
396 {
397 return new wxCarbonTimerImpl(timer);
398 }
399
400 int gs_wxBusyCursorCount = 0;
401 extern wxCursor gMacCurrentCursor;
402 wxCursor gMacStoredActiveCursor;
403
404 // Set the cursor to the busy cursor for all windows
405 void wxBeginBusyCursor(const wxCursor *cursor)
406 {
407 if (gs_wxBusyCursorCount++ == 0)
408 {
409 gMacStoredActiveCursor = gMacCurrentCursor;
410 cursor->MacInstall();
411 }
412 //else: nothing to do, already set
413 }
414
415 // Restore cursor to normal
416 void wxEndBusyCursor()
417 {
418 wxCHECK_RET( gs_wxBusyCursorCount > 0,
419 wxT("no matching wxBeginBusyCursor() for wxEndBusyCursor()") );
420
421 if (--gs_wxBusyCursorCount == 0)
422 {
423 gMacStoredActiveCursor.MacInstall();
424 gMacStoredActiveCursor = wxNullCursor;
425 }
426 }
427
428 // true if we're between the above two calls
429 bool wxIsBusy()
430 {
431 return (gs_wxBusyCursorCount > 0);
432 }
433
434 #endif // wxUSE_GUI
435
436 #if wxUSE_BASE
437
438 wxString wxMacFindFolderNoSeparator( short vol,
439 OSType folderType,
440 Boolean createFolder)
441 {
442 FSRef fsRef;
443 wxString strDir;
444
445 if ( FSFindFolder( vol, folderType, createFolder, &fsRef) == noErr)
446 {
447 strDir = wxMacFSRefToPath( &fsRef );
448 }
449
450 return strDir;
451 }
452
453 wxString wxMacFindFolder( short vol,
454 OSType folderType,
455 Boolean createFolder)
456 {
457 return wxMacFindFolderNoSeparator(vol, folderType, createFolder) + wxFILE_SEP_PATH;
458 }
459
460 #endif // wxUSE_BASE
461
462 #if wxUSE_GUI
463
464 // Check whether this window wants to process messages, e.g. Stop button
465 // in long calculations.
466 bool wxCheckForInterrupt(wxWindow *WXUNUSED(wnd))
467 {
468 // TODO
469 return false;
470 }
471
472 void wxGetMousePosition( int* x, int* y )
473 {
474 Point pt;
475 #if wxMAC_USE_CORE_GRAPHICS
476 GetGlobalMouse(&pt);
477 #else
478 GetMouse( &pt );
479 LocalToGlobal( &pt );
480 #endif
481 *x = pt.h;
482 *y = pt.v;
483 };
484
485 // Return true if we have a colour display
486 bool wxColourDisplay()
487 {
488 return true;
489 }
490
491 // Returns depth of screen
492 int wxDisplayDepth()
493 {
494 int theDepth = 8;
495 #if wxMAC_USE_CORE_GRAPHICS
496 theDepth = (int) CGDisplayBitsPerPixel(CGMainDisplayID());
497 #else
498 Rect globRect;
499 SetRect(&globRect, -32760, -32760, 32760, 32760);
500 GDHandle theMaxDevice;
501
502 theMaxDevice = GetMaxDevice(&globRect);
503 if (theMaxDevice != NULL)
504 theDepth = (**(**theMaxDevice).gdPMap).pixelSize;
505 #endif
506 return theDepth;
507 }
508
509 // Get size of display
510 void wxDisplaySize(int *width, int *height)
511 {
512 #if wxMAC_USE_CORE_GRAPHICS
513 // TODO adapt for multi-displays
514 CGRect bounds = CGDisplayBounds(CGMainDisplayID());
515 if ( width )
516 *width = (int)bounds.size.width ;
517 if ( height )
518 *height = (int)bounds.size.height;
519 #else
520 BitMap screenBits;
521 GetQDGlobalsScreenBits( &screenBits );
522
523 if (width != NULL)
524 *width = screenBits.bounds.right - screenBits.bounds.left;
525
526 if (height != NULL)
527 *height = screenBits.bounds.bottom - screenBits.bounds.top;
528 #endif
529 }
530
531 void wxDisplaySizeMM(int *width, int *height)
532 {
533 wxDisplaySize(width, height);
534 // on mac 72 is fixed (at least now;-)
535 float cvPt2Mm = 25.4 / 72;
536
537 if (width != NULL)
538 *width = int( *width * cvPt2Mm );
539
540 if (height != NULL)
541 *height = int( *height * cvPt2Mm );
542 }
543
544 void wxClientDisplayRect(int *x, int *y, int *width, int *height)
545 {
546 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
547 HIRect bounds ;
548 HIWindowGetAvailablePositioningBounds(kCGNullDirectDisplay,kHICoordSpace72DPIGlobal,
549 &bounds);
550 if ( x )
551 *x = bounds.origin.x;
552 if ( y )
553 *y = bounds.origin.y;
554 if ( width )
555 *width = bounds.size.width;
556 if ( height )
557 *height = bounds.size.height;
558 #else
559 Rect r;
560 GetAvailableWindowPositioningBounds( GetMainDevice() , &r );
561 if ( x )
562 *x = r.left;
563 if ( y )
564 *y = r.top;
565 if ( width )
566 *width = r.right - r.left;
567 if ( height )
568 *height = r.bottom - r.top;
569 #endif
570 }
571
572 wxWindow* wxFindWindowAtPoint(const wxPoint& pt)
573 {
574 return wxGenericFindWindowAtPoint(pt);
575 }
576
577 #endif // wxUSE_GUI
578
579 #if wxUSE_BASE
580
581 wxString wxGetOsDescription()
582 {
583 #ifdef WXWIN_OS_DESCRIPTION
584 // use configure generated description if available
585 return wxString(wxT("MacOS (")) + wxT(WXWIN_OS_DESCRIPTION) + wxString(wxT(")"));
586 #else
587 return wxT("MacOS"); //TODO:define further
588 #endif
589 }
590
591 #ifndef __DARWIN__
592 wxString wxGetUserHome (const wxString& user)
593 {
594 // TODO
595 return wxString();
596 }
597
598 bool wxGetDiskSpace(const wxString& path, wxDiskspaceSize_t *pTotal, wxDiskspaceSize_t *pFree)
599 {
600 if ( path.empty() )
601 return false;
602
603 wxString p = path;
604 if (p[0u] == ':' )
605 p = wxGetCwd() + p;
606
607 int pos = p.Find(':');
608 if ( pos != wxNOT_FOUND )
609 p = p.Mid(1,pos);
610
611 p = p + wxT(":");
612
613 OSErr err = noErr;
614
615 FSRef fsRef;
616 err = wxMacPathToFSRef( p , &fsRef );
617 if ( noErr == err )
618 {
619 FSVolumeRefNum vRefNum;
620 err = FSGetVRefNum( &fsRef , &vRefNum );
621 if ( noErr == err )
622 {
623 UInt64 freeBytes , totalBytes;
624 err = FSGetVInfo( vRefNum , NULL , &freeBytes , &totalBytes );
625 if ( noErr == err )
626 {
627 if ( pTotal )
628 *pTotal = wxDiskspaceSize_t( totalBytes );
629 if ( pFree )
630 *pFree = wxDiskspaceSize_t( freeBytes );
631 }
632 }
633 }
634
635 return err == noErr;
636 }
637 #endif // !__DARWIN__
638
639 //---------------------------------------------------------------------------
640 // wxMac Specific utility functions
641 //---------------------------------------------------------------------------
642
643 void wxMacStringToPascal( const wxString&from , StringPtr to )
644 {
645 wxCharBuffer buf = from.mb_str( wxConvLocal );
646 int len = strlen(buf);
647
648 if ( len > 255 )
649 len = 255;
650 to[0] = len;
651 memcpy( (char*) &to[1] , buf , len );
652 }
653
654 wxString wxMacMakeStringFromPascal( ConstStringPtr from )
655 {
656 return wxString( (char*) &from[1] , wxConvLocal , from[0] );
657 }
658
659 // ----------------------------------------------------------------------------
660 // Common Event Support
661 // ----------------------------------------------------------------------------
662
663 extern ProcessSerialNumber gAppProcess;
664
665 void wxMacWakeUp()
666 {
667 ProcessSerialNumber psn;
668 Boolean isSame;
669 psn.highLongOfPSN = 0;
670 psn.lowLongOfPSN = kCurrentProcess;
671 SameProcess( &gAppProcess , &psn , &isSame );
672 if ( isSame )
673 {
674 OSStatus err = noErr;
675
676 #if 0
677 // lead sometimes to race conditions, although all calls used should be thread safe ...
678 static wxMacCarbonEvent s_wakeupEvent;
679 if ( !s_wakeupEvent.IsValid() )
680 {
681 err = s_wakeupEvent.Create( 'WXMC', 'WXMC', GetCurrentEventTime(),
682 kEventAttributeNone );
683 }
684 if ( err == noErr )
685 {
686
687 if ( IsEventInQueue( GetMainEventQueue() , s_wakeupEvent ) )
688 return;
689 s_wakeupEvent.SetCurrentTime();
690 err = PostEventToQueue(GetMainEventQueue(), s_wakeupEvent,
691 kEventPriorityHigh );
692 }
693 #else
694 wxMacCarbonEvent wakeupEvent;
695 wakeupEvent.Create( 'WXMC', 'WXMC', GetCurrentEventTime(),
696 kEventAttributeNone );
697 err = PostEventToQueue(GetMainEventQueue(), wakeupEvent,
698 kEventPriorityHigh );
699 #endif
700 }
701 else
702 {
703 WakeUpProcess( &gAppProcess );
704 }
705 }
706
707 #endif // wxUSE_BASE
708
709 #if wxUSE_GUI
710
711 // ----------------------------------------------------------------------------
712 // Native Struct Conversions
713 // ----------------------------------------------------------------------------
714
715 void wxMacRectToNative( const wxRect *wx , Rect *n )
716 {
717 n->left = wx->x;
718 n->top = wx->y;
719 n->right = wx->x + wx->width;
720 n->bottom = wx->y + wx->height;
721 }
722
723 void wxMacNativeToRect( const Rect *n , wxRect* wx )
724 {
725 wx->x = n->left;
726 wx->y = n->top;
727 wx->width = n->right - n->left;
728 wx->height = n->bottom - n->top;
729 }
730
731 void wxMacPointToNative( const wxPoint* wx , Point *n )
732 {
733 n->h = wx->x;
734 n->v = wx->y;
735 }
736
737 void wxMacNativeToPoint( const Point *n , wxPoint* wx )
738 {
739 wx->x = n->h;
740 wx->y = n->v;
741 }
742
743 // ----------------------------------------------------------------------------
744 // Carbon Event Support
745 // ----------------------------------------------------------------------------
746
747 OSStatus wxMacCarbonEvent::GetParameter(EventParamName inName, EventParamType inDesiredType, UInt32 inBufferSize, void * outData)
748 {
749 return ::GetEventParameter( m_eventRef , inName , inDesiredType , NULL , inBufferSize , NULL , outData );
750 }
751
752 OSStatus wxMacCarbonEvent::SetParameter(EventParamName inName, EventParamType inType, UInt32 inBufferSize, const void * inData)
753 {
754 return ::SetEventParameter( m_eventRef , inName , inType , inBufferSize , inData );
755 }
756
757 // ----------------------------------------------------------------------------
758 // Control Access Support
759 // ----------------------------------------------------------------------------
760
761 IMPLEMENT_DYNAMIC_CLASS( wxMacControl , wxObject )
762
763 wxMacControl::wxMacControl()
764 {
765 Init();
766 }
767
768 wxMacControl::wxMacControl(wxWindow* peer , bool isRootControl )
769 {
770 Init();
771 m_peer = peer;
772 m_isRootControl = isRootControl;
773 }
774
775 wxMacControl::wxMacControl( wxWindow* peer , ControlRef control )
776 {
777 Init();
778 m_peer = peer;
779 m_controlRef = control;
780 }
781
782 wxMacControl::wxMacControl( wxWindow* peer , WXWidget control )
783 {
784 Init();
785 m_peer = peer;
786 m_controlRef = (ControlRef) control;
787 }
788
789 wxMacControl::~wxMacControl()
790 {
791 }
792
793 void wxMacControl::Init()
794 {
795 m_peer = NULL;
796 m_controlRef = NULL;
797 m_needsFocusRect = false;
798 m_isRootControl = false;
799 }
800
801 void wxMacControl::Dispose()
802 {
803 wxASSERT_MSG( m_controlRef != NULL , wxT("Control Handle already NULL, Dispose called twice ?") );
804 wxASSERT_MSG( IsValidControlHandle(m_controlRef) , wxT("Invalid Control Handle (maybe already released) in Dispose") );
805
806 // we cannot check the ref count here anymore, as autorelease objects might delete their refs later
807 // we can have situations when being embedded, where the control gets deleted behind our back, so only
808 // CFRelease if we are safe
809 if ( IsValidControlHandle(m_controlRef) )
810 CFRelease(m_controlRef);
811 m_controlRef = NULL;
812 }
813
814 void wxMacControl::SetReference( URefCon data )
815 {
816 SetControlReference( m_controlRef , data );
817 }
818
819 OSStatus wxMacControl::GetData(ControlPartCode inPartCode , ResType inTag , Size inBufferSize , void * inOutBuffer , Size * outActualSize ) const
820 {
821 return ::GetControlData( m_controlRef , inPartCode , inTag , inBufferSize , inOutBuffer , outActualSize );
822 }
823
824 OSStatus wxMacControl::GetDataSize(ControlPartCode inPartCode , ResType inTag , Size * outActualSize ) const
825 {
826 return ::GetControlDataSize( m_controlRef , inPartCode , inTag , outActualSize );
827 }
828
829 OSStatus wxMacControl::SetData(ControlPartCode inPartCode , ResType inTag , Size inSize , const void * inData)
830 {
831 return ::SetControlData( m_controlRef , inPartCode , inTag , inSize , inData );
832 }
833
834 OSStatus wxMacControl::SendEvent( EventRef event , OptionBits inOptions )
835 {
836 #if TARGET_API_MAC_OSX
837 return SendEventToEventTargetWithOptions( event,
838 HIObjectGetEventTarget( (HIObjectRef) m_controlRef ), inOptions );
839 #else
840 #pragma unused(inOptions)
841 return SendEventToEventTarget(event,GetControlEventTarget( m_controlRef ) );
842 #endif
843 }
844
845 OSStatus wxMacControl::SendHICommand( HICommand &command , OptionBits inOptions )
846 {
847 wxMacCarbonEvent event( kEventClassCommand , kEventCommandProcess );
848
849 event.SetParameter<HICommand>(kEventParamDirectObject,command);
850
851 return SendEvent( event , inOptions );
852 }
853
854 OSStatus wxMacControl::SendHICommand( UInt32 commandID , OptionBits inOptions )
855 {
856 HICommand command;
857
858 memset( &command, 0 , sizeof(command) );
859 command.commandID = commandID;
860 return SendHICommand( command , inOptions );
861 }
862
863 void wxMacControl::Flash( ControlPartCode part , UInt32 ticks )
864 {
865 unsigned long finalTicks;
866
867 HiliteControl( m_controlRef , part );
868 Delay( ticks , &finalTicks );
869 HiliteControl( m_controlRef , kControlNoPart );
870 }
871
872 SInt32 wxMacControl::GetValue() const
873 {
874 return ::GetControl32BitValue( m_controlRef );
875 }
876
877 SInt32 wxMacControl::GetMaximum() const
878 {
879 return ::GetControl32BitMaximum( m_controlRef );
880 }
881
882 SInt32 wxMacControl::GetMinimum() const
883 {
884 return ::GetControl32BitMinimum( m_controlRef );
885 }
886
887 void wxMacControl::SetValue( SInt32 v )
888 {
889 ::SetControl32BitValue( m_controlRef , v );
890 }
891
892 void wxMacControl::SetMinimum( SInt32 v )
893 {
894 ::SetControl32BitMinimum( m_controlRef , v );
895 }
896
897 void wxMacControl::SetMaximum( SInt32 v )
898 {
899 ::SetControl32BitMaximum( m_controlRef , v );
900 }
901
902 void wxMacControl::SetValueAndRange( SInt32 value , SInt32 minimum , SInt32 maximum )
903 {
904 ::SetControl32BitMinimum( m_controlRef , minimum );
905 ::SetControl32BitMaximum( m_controlRef , maximum );
906 ::SetControl32BitValue( m_controlRef , value );
907 }
908
909 OSStatus wxMacControl::SetFocus( ControlFocusPart focusPart )
910 {
911 return SetKeyboardFocus( GetControlOwner( m_controlRef ), m_controlRef, focusPart );
912 }
913
914 bool wxMacControl::HasFocus() const
915 {
916 ControlRef control;
917 GetKeyboardFocus( GetUserFocusWindow() , &control );
918 return control == m_controlRef;
919 }
920
921 void wxMacControl::SetNeedsFocusRect( bool needs )
922 {
923 m_needsFocusRect = needs;
924 }
925
926 bool wxMacControl::NeedsFocusRect() const
927 {
928 return m_needsFocusRect;
929 }
930
931 void wxMacControl::VisibilityChanged(bool WXUNUSED(shown))
932 {
933 }
934
935 void wxMacControl::SuperChangedPosition()
936 {
937 }
938
939 void wxMacControl::SetFont( const wxFont & font , const wxColour& foreground , long windowStyle )
940 {
941 m_font = font;
942 #ifndef __LP64__
943 ControlFontStyleRec fontStyle;
944 if ( font.MacGetThemeFontID() != kThemeCurrentPortFont )
945 {
946 switch ( font.MacGetThemeFontID() )
947 {
948 case kThemeSmallSystemFont :
949 fontStyle.font = kControlFontSmallSystemFont;
950 break;
951
952 case 109 : // mini font
953 fontStyle.font = -5;
954 break;
955
956 case kThemeSystemFont :
957 fontStyle.font = kControlFontBigSystemFont;
958 break;
959
960 default :
961 fontStyle.font = kControlFontBigSystemFont;
962 break;
963 }
964
965 fontStyle.flags = kControlUseFontMask;
966 }
967 else
968 {
969 fontStyle.font = font.MacGetFontNum();
970 fontStyle.style = font.MacGetFontStyle();
971 fontStyle.size = font.MacGetFontSize();
972 fontStyle.flags = kControlUseFontMask | kControlUseFaceMask | kControlUseSizeMask;
973 }
974
975 fontStyle.just = teJustLeft;
976 fontStyle.flags |= kControlUseJustMask;
977 if ( ( windowStyle & wxALIGN_MASK ) & wxALIGN_CENTER_HORIZONTAL )
978 fontStyle.just = teJustCenter;
979 else if ( ( windowStyle & wxALIGN_MASK ) & wxALIGN_RIGHT )
980 fontStyle.just = teJustRight;
981
982
983 // we only should do this in case of a non-standard color, as otherwise 'disabled' controls
984 // won't get grayed out by the system anymore
985
986 if ( foreground != *wxBLACK )
987 {
988 fontStyle.foreColor = MAC_WXCOLORREF( foreground.GetPixel() );
989 fontStyle.flags |= kControlUseForeColorMask;
990 }
991
992 ::SetControlFontStyle( m_controlRef , &fontStyle );
993 #endif
994 }
995
996 void wxMacControl::SetBackground( const wxBrush &WXUNUSED(brush) )
997 {
998 // TODO
999 // setting up a color proc is not recommended anymore
1000 }
1001
1002 void wxMacControl::SetRange( SInt32 minimum , SInt32 maximum )
1003 {
1004 ::SetControl32BitMinimum( m_controlRef , minimum );
1005 ::SetControl32BitMaximum( m_controlRef , maximum );
1006 }
1007
1008 short wxMacControl::HandleKey( SInt16 keyCode, SInt16 charCode, EventModifiers modifiers )
1009 {
1010 #ifndef __LP64__
1011 return HandleControlKey( m_controlRef , keyCode , charCode , modifiers );
1012 #else
1013 return 0;
1014 #endif
1015 }
1016
1017 void wxMacControl::SetActionProc( ControlActionUPP actionProc )
1018 {
1019 SetControlAction( m_controlRef , actionProc );
1020 }
1021
1022 void wxMacControl::SetViewSize( SInt32 viewSize )
1023 {
1024 SetControlViewSize(m_controlRef , viewSize );
1025 }
1026
1027 SInt32 wxMacControl::GetViewSize() const
1028 {
1029 return GetControlViewSize( m_controlRef );
1030 }
1031
1032 bool wxMacControl::IsVisible() const
1033 {
1034 return IsControlVisible( m_controlRef );
1035 }
1036
1037 void wxMacControl::SetVisibility( bool visible , bool redraw )
1038 {
1039 SetControlVisibility( m_controlRef , visible , redraw );
1040 }
1041
1042 bool wxMacControl::IsEnabled() const
1043 {
1044 #if TARGET_API_MAC_OSX
1045 return IsControlEnabled( m_controlRef );
1046 #else
1047 return IsControlActive( m_controlRef );
1048 #endif
1049 }
1050
1051 bool wxMacControl::IsActive() const
1052 {
1053 return IsControlActive( m_controlRef );
1054 }
1055
1056 void wxMacControl::Enable( bool enable )
1057 {
1058 if ( enable )
1059 EnableControl( m_controlRef );
1060 else
1061 DisableControl( m_controlRef );
1062 }
1063
1064 void wxMacControl::SetDrawingEnabled( bool enable )
1065 {
1066 HIViewSetDrawingEnabled( m_controlRef , enable );
1067 }
1068
1069 bool wxMacControl::GetNeedsDisplay() const
1070 {
1071 return HIViewGetNeedsDisplay( m_controlRef );
1072 }
1073
1074 void wxMacControl::SetNeedsDisplay( RgnHandle where )
1075 {
1076 if ( !IsVisible() )
1077 return;
1078
1079 HIViewSetNeedsDisplayInRegion( m_controlRef , where , true );
1080 }
1081
1082 void wxMacControl::SetNeedsDisplay( Rect* where )
1083 {
1084 if ( !IsVisible() )
1085 return;
1086
1087 if ( where != NULL )
1088 {
1089 RgnHandle update = NewRgn();
1090 RectRgn( update , where );
1091 HIViewSetNeedsDisplayInRegion( m_controlRef , update , true );
1092 DisposeRgn( update );
1093 }
1094 else
1095 HIViewSetNeedsDisplay( m_controlRef , true );
1096 }
1097
1098 void wxMacControl::Convert( wxPoint *pt , wxMacControl *from , wxMacControl *to )
1099 {
1100 HIPoint hiPoint;
1101
1102 hiPoint.x = pt->x;
1103 hiPoint.y = pt->y;
1104 HIViewConvertPoint( &hiPoint , from->m_controlRef , to->m_controlRef );
1105 pt->x = (int)hiPoint.x;
1106 pt->y = (int)hiPoint.y;
1107 }
1108
1109 void wxMacControl::SetRect( Rect *r )
1110 {
1111 //A HIRect is actually a CGRect on OSX - which consists of two structures -
1112 //CGPoint and CGSize, which have two floats each
1113 HIRect hir = { { r->left , r->top }, { r->right - r->left , r->bottom - r->top } };
1114 HIViewSetFrame ( m_controlRef , &hir );
1115 // eventuall we might have to do a SetVisibility( false , true );
1116 // before and a SetVisibility( true , true ); after
1117 }
1118
1119 void wxMacControl::GetRect( Rect *r )
1120 {
1121 GetControlBounds( m_controlRef , r );
1122 }
1123
1124 void wxMacControl::GetRectInWindowCoords( Rect *r )
1125 {
1126 UMAGetControlBoundsInWindowCoords( m_controlRef , r );
1127 }
1128
1129 void wxMacControl::GetBestRect( Rect *r )
1130 {
1131 short baselineoffset;
1132
1133 GetBestControlRect( m_controlRef , r , &baselineoffset );
1134 }
1135
1136 void wxMacControl::SetLabel( const wxString &title )
1137 {
1138 wxFontEncoding encoding;
1139
1140 if ( m_font.Ok() )
1141 encoding = m_font.GetEncoding();
1142 else
1143 encoding = wxFont::GetDefaultEncoding();
1144
1145 UMASetControlTitle( m_controlRef , title , encoding );
1146 }
1147
1148 void wxMacControl::GetFeatures( UInt32 * features )
1149 {
1150 GetControlFeatures( m_controlRef , features );
1151 }
1152
1153 OSStatus wxMacControl::GetRegion( ControlPartCode partCode , RgnHandle region )
1154 {
1155 OSStatus err = GetControlRegion( m_controlRef , partCode , region );
1156 return err;
1157 }
1158
1159 OSStatus wxMacControl::SetZOrder( bool above , wxMacControl* other )
1160 {
1161 #if TARGET_API_MAC_OSX
1162 return HIViewSetZOrder( m_controlRef,above ? kHIViewZOrderAbove : kHIViewZOrderBelow,
1163 (other != NULL) ? other->m_controlRef : NULL);
1164 #else
1165 return 0;
1166 #endif
1167 }
1168
1169 #if TARGET_API_MAC_OSX
1170 // SetNeedsDisplay would not invalidate the children
1171 static void InvalidateControlAndChildren( HIViewRef control )
1172 {
1173 HIViewSetNeedsDisplay( control , true );
1174 UInt16 childrenCount = 0;
1175 OSStatus err = CountSubControls( control , &childrenCount );
1176 if ( err == errControlIsNotEmbedder )
1177 return;
1178
1179 wxASSERT_MSG( err == noErr , wxT("Unexpected error when accessing subcontrols") );
1180
1181 for ( UInt16 i = childrenCount; i >=1; --i )
1182 {
1183 HIViewRef child;
1184
1185 err = GetIndexedSubControl( control , i , & child );
1186 if ( err == errControlIsNotEmbedder )
1187 return;
1188
1189 InvalidateControlAndChildren( child );
1190 }
1191 }
1192 #endif
1193
1194 void wxMacControl::InvalidateWithChildren()
1195 {
1196 #if TARGET_API_MAC_OSX
1197 InvalidateControlAndChildren( m_controlRef );
1198 #endif
1199 }
1200
1201 void wxMacControl::ScrollRect( wxRect *r , int dx , int dy )
1202 {
1203 wxASSERT( r != NULL );
1204
1205 HIRect scrollarea = CGRectMake( r->x , r->y , r->width , r->height);
1206 HIViewScrollRect ( m_controlRef , &scrollarea , dx ,dy );
1207 }
1208
1209 OSType wxMacCreator = 'WXMC';
1210 OSType wxMacControlProperty = 'MCCT';
1211
1212 void wxMacControl::SetReferenceInNativeControl()
1213 {
1214 void * data = this;
1215 verify_noerr( SetControlProperty ( m_controlRef ,
1216 wxMacCreator,wxMacControlProperty, sizeof(data), &data ) );
1217 }
1218
1219 wxMacControl* wxMacControl::GetReferenceFromNativeControl(ControlRef control)
1220 {
1221 wxMacControl* ctl = NULL;
1222 ByteCount actualSize;
1223 if ( GetControlProperty( control ,wxMacCreator,wxMacControlProperty, sizeof(ctl) ,
1224 &actualSize , &ctl ) == noErr )
1225 {
1226 return ctl;
1227 }
1228 return NULL;
1229 }
1230
1231 // ============================================================================
1232 // DataBrowser Wrapper
1233 // ============================================================================
1234 //
1235 // basing on DataBrowserItemIDs
1236 //
1237
1238 IMPLEMENT_ABSTRACT_CLASS( wxMacDataBrowserControl , wxMacControl )
1239
1240 pascal void wxMacDataBrowserControl::DataBrowserItemNotificationProc(
1241 ControlRef browser,
1242 DataBrowserItemID itemID,
1243 DataBrowserItemNotification message,
1244 DataBrowserItemDataRef itemData )
1245 {
1246 wxMacDataBrowserControl* ctl = wxDynamicCast(wxMacControl::GetReferenceFromNativeControl( browser ), wxMacDataBrowserControl);
1247 if ( ctl != 0 )
1248 {
1249 ctl->ItemNotification(itemID, message, itemData);
1250 }
1251 }
1252
1253 pascal OSStatus wxMacDataBrowserControl::DataBrowserGetSetItemDataProc(
1254 ControlRef browser,
1255 DataBrowserItemID itemID,
1256 DataBrowserPropertyID property,
1257 DataBrowserItemDataRef itemData,
1258 Boolean changeValue )
1259 {
1260 OSStatus err = errDataBrowserPropertyNotSupported;
1261 wxMacDataBrowserControl* ctl = wxDynamicCast(wxMacControl::GetReferenceFromNativeControl( browser ), wxMacDataBrowserControl);
1262 if ( ctl != 0 )
1263 {
1264 err = ctl->GetSetItemData(itemID, property, itemData, changeValue);
1265 }
1266 return err;
1267 }
1268
1269 pascal Boolean wxMacDataBrowserControl::DataBrowserCompareProc(
1270 ControlRef browser,
1271 DataBrowserItemID itemOneID,
1272 DataBrowserItemID itemTwoID,
1273 DataBrowserPropertyID sortProperty)
1274 {
1275 wxMacDataBrowserControl* ctl = wxDynamicCast(wxMacControl::GetReferenceFromNativeControl( browser ), wxMacDataBrowserControl);
1276 if ( ctl != 0 )
1277 {
1278 return ctl->CompareItems(itemOneID, itemTwoID, sortProperty);
1279 }
1280 return false;
1281 }
1282
1283 DataBrowserItemDataUPP gDataBrowserItemDataUPP = NULL;
1284 DataBrowserItemNotificationUPP gDataBrowserItemNotificationUPP = NULL;
1285 DataBrowserItemCompareUPP gDataBrowserItemCompareUPP = NULL;
1286
1287 wxMacDataBrowserControl::wxMacDataBrowserControl( wxWindow* peer,
1288 const wxPoint& pos,
1289 const wxSize& size,
1290 long WXUNUSED(style))
1291 : wxMacControl( peer )
1292 {
1293 Rect bounds = wxMacGetBoundsForControl( peer, pos, size );
1294 OSStatus err = ::CreateDataBrowserControl(
1295 MAC_WXHWND(peer->MacGetTopLevelWindowRef()),
1296 &bounds, kDataBrowserListView, &m_controlRef );
1297 SetReferenceInNativeControl();
1298 verify_noerr( err );
1299 if ( gDataBrowserItemCompareUPP == NULL )
1300 gDataBrowserItemCompareUPP = NewDataBrowserItemCompareUPP(DataBrowserCompareProc);
1301 if ( gDataBrowserItemDataUPP == NULL )
1302 gDataBrowserItemDataUPP = NewDataBrowserItemDataUPP(DataBrowserGetSetItemDataProc);
1303 if ( gDataBrowserItemNotificationUPP == NULL )
1304 {
1305 gDataBrowserItemNotificationUPP =
1306 #if TARGET_API_MAC_OSX
1307 (DataBrowserItemNotificationUPP) NewDataBrowserItemNotificationWithItemUPP(DataBrowserItemNotificationProc);
1308 #else
1309 NewDataBrowserItemNotificationUPP(DataBrowserItemNotificationProc);
1310 #endif
1311 }
1312
1313 DataBrowserCallbacks callbacks;
1314 InitializeDataBrowserCallbacks( &callbacks, kDataBrowserLatestCallbacks );
1315
1316 callbacks.u.v1.itemDataCallback = gDataBrowserItemDataUPP;
1317 callbacks.u.v1.itemCompareCallback = gDataBrowserItemCompareUPP;
1318 callbacks.u.v1.itemNotificationCallback = gDataBrowserItemNotificationUPP;
1319 SetCallbacks( &callbacks );
1320
1321 }
1322
1323 OSStatus wxMacDataBrowserControl::GetItemCount( DataBrowserItemID container,
1324 Boolean recurse,
1325 DataBrowserItemState state,
1326 ItemCount *numItems) const
1327 {
1328 return GetDataBrowserItemCount( m_controlRef, container, recurse, state, numItems );
1329 }
1330
1331 OSStatus wxMacDataBrowserControl::GetItems( DataBrowserItemID container,
1332 Boolean recurse,
1333 DataBrowserItemState state,
1334 Handle items) const
1335 {
1336 return GetDataBrowserItems( m_controlRef, container, recurse, state, items );
1337 }
1338
1339 OSStatus wxMacDataBrowserControl::SetSelectionFlags( DataBrowserSelectionFlags options )
1340 {
1341 return SetDataBrowserSelectionFlags( m_controlRef, options );
1342 }
1343
1344 OSStatus wxMacDataBrowserControl::AddColumn( DataBrowserListViewColumnDesc *columnDesc,
1345 DataBrowserTableViewColumnIndex position )
1346 {
1347 return AddDataBrowserListViewColumn( m_controlRef, columnDesc, position );
1348 }
1349
1350 OSStatus wxMacDataBrowserControl::GetColumnIDFromIndex( DataBrowserTableViewColumnIndex position, DataBrowserTableViewColumnID* id ){
1351 return GetDataBrowserTableViewColumnProperty( m_controlRef, position, id );
1352 }
1353
1354 OSStatus wxMacDataBrowserControl::RemoveColumn( DataBrowserTableViewColumnIndex position )
1355 {
1356 DataBrowserTableViewColumnID id;
1357 GetColumnIDFromIndex( position, &id );
1358 return RemoveDataBrowserTableViewColumn( m_controlRef, id );
1359 }
1360
1361 OSStatus wxMacDataBrowserControl::AutoSizeColumns()
1362 {
1363 return AutoSizeDataBrowserListViewColumns(m_controlRef);
1364 }
1365
1366 OSStatus wxMacDataBrowserControl::SetHasScrollBars( bool horiz, bool vert )
1367 {
1368 return SetDataBrowserHasScrollBars( m_controlRef, horiz, vert );
1369 }
1370
1371 OSStatus wxMacDataBrowserControl::SetHiliteStyle( DataBrowserTableViewHiliteStyle hiliteStyle )
1372 {
1373 return SetDataBrowserTableViewHiliteStyle( m_controlRef, hiliteStyle );
1374 }
1375
1376 OSStatus wxMacDataBrowserControl::SetHeaderButtonHeight(UInt16 height)
1377 {
1378 return SetDataBrowserListViewHeaderBtnHeight( m_controlRef, height );
1379 }
1380
1381 OSStatus wxMacDataBrowserControl::GetHeaderButtonHeight(UInt16 *height)
1382 {
1383 return GetDataBrowserListViewHeaderBtnHeight( m_controlRef, height );
1384 }
1385
1386 OSStatus wxMacDataBrowserControl::SetCallbacks(const DataBrowserCallbacks *callbacks)
1387 {
1388 return SetDataBrowserCallbacks( m_controlRef, callbacks );
1389 }
1390
1391 OSStatus wxMacDataBrowserControl::UpdateItems(
1392 DataBrowserItemID container,
1393 UInt32 numItems,
1394 const DataBrowserItemID *items,
1395 DataBrowserPropertyID preSortProperty,
1396 DataBrowserPropertyID propertyID ) const
1397 {
1398 return UpdateDataBrowserItems( m_controlRef, container, numItems, items, preSortProperty, propertyID );
1399 }
1400
1401 bool wxMacDataBrowserControl::IsItemSelected( DataBrowserItemID item ) const
1402 {
1403 return IsDataBrowserItemSelected( m_controlRef, item );
1404 }
1405
1406 OSStatus wxMacDataBrowserControl::AddItems(
1407 DataBrowserItemID container,
1408 UInt32 numItems,
1409 const DataBrowserItemID *items,
1410 DataBrowserPropertyID preSortProperty )
1411 {
1412 return AddDataBrowserItems( m_controlRef, container, numItems, items, preSortProperty );
1413 }
1414
1415 OSStatus wxMacDataBrowserControl::RemoveItems(
1416 DataBrowserItemID container,
1417 UInt32 numItems,
1418 const DataBrowserItemID *items,
1419 DataBrowserPropertyID preSortProperty )
1420 {
1421 return RemoveDataBrowserItems( m_controlRef, container, numItems, items, preSortProperty );
1422 }
1423
1424 OSStatus wxMacDataBrowserControl::RevealItem(
1425 DataBrowserItemID item,
1426 DataBrowserPropertyID propertyID,
1427 DataBrowserRevealOptions options ) const
1428 {
1429 return RevealDataBrowserItem( m_controlRef, item, propertyID, options );
1430 }
1431
1432 OSStatus wxMacDataBrowserControl::SetSelectedItems(
1433 UInt32 numItems,
1434 const DataBrowserItemID *items,
1435 DataBrowserSetOption operation )
1436 {
1437 return SetDataBrowserSelectedItems( m_controlRef, numItems, items, operation );
1438 }
1439
1440 OSStatus wxMacDataBrowserControl::GetSelectionAnchor( DataBrowserItemID *first, DataBrowserItemID *last ) const
1441 {
1442 return GetDataBrowserSelectionAnchor( m_controlRef, first, last );
1443 }
1444
1445 OSStatus wxMacDataBrowserControl::GetItemID( DataBrowserTableViewRowIndex row, DataBrowserItemID * item ) const
1446 {
1447 return GetDataBrowserTableViewItemID( m_controlRef, row, item );
1448 }
1449
1450 OSStatus wxMacDataBrowserControl::GetItemRow( DataBrowserItemID item, DataBrowserTableViewRowIndex * row ) const
1451 {
1452 return GetDataBrowserTableViewItemRow( m_controlRef, item, row );
1453 }
1454
1455 OSStatus wxMacDataBrowserControl::SetDefaultRowHeight( UInt16 height )
1456 {
1457 return SetDataBrowserTableViewRowHeight( m_controlRef , height );
1458 }
1459
1460 OSStatus wxMacDataBrowserControl::GetDefaultRowHeight( UInt16 * height ) const
1461 {
1462 return GetDataBrowserTableViewRowHeight( m_controlRef, height );
1463 }
1464
1465 OSStatus wxMacDataBrowserControl::SetRowHeight( DataBrowserItemID item , UInt16 height)
1466 {
1467 return SetDataBrowserTableViewItemRowHeight( m_controlRef, item , height );
1468 }
1469
1470 OSStatus wxMacDataBrowserControl::GetRowHeight( DataBrowserItemID item , UInt16 *height) const
1471 {
1472 return GetDataBrowserTableViewItemRowHeight( m_controlRef, item , height);
1473 }
1474
1475 OSStatus wxMacDataBrowserControl::GetColumnWidth( DataBrowserPropertyID column , UInt16 *width ) const
1476 {
1477 return GetDataBrowserTableViewNamedColumnWidth( m_controlRef , column , width );
1478 }
1479
1480 OSStatus wxMacDataBrowserControl::SetColumnWidth( DataBrowserPropertyID column , UInt16 width )
1481 {
1482 return SetDataBrowserTableViewNamedColumnWidth( m_controlRef , column , width );
1483 }
1484
1485 OSStatus wxMacDataBrowserControl::GetDefaultColumnWidth( UInt16 *width ) const
1486 {
1487 return GetDataBrowserTableViewColumnWidth( m_controlRef , width );
1488 }
1489
1490 OSStatus wxMacDataBrowserControl::SetDefaultColumnWidth( UInt16 width )
1491 {
1492 return SetDataBrowserTableViewColumnWidth( m_controlRef , width );
1493 }
1494
1495 OSStatus wxMacDataBrowserControl::GetColumnCount(UInt32* numColumns) const
1496 {
1497 return GetDataBrowserTableViewColumnCount( m_controlRef, numColumns);
1498 }
1499
1500 OSStatus wxMacDataBrowserControl::GetColumnPosition( DataBrowserPropertyID column,
1501 DataBrowserTableViewColumnIndex *position) const
1502 {
1503 return GetDataBrowserTableViewColumnPosition( m_controlRef , column , position);
1504 }
1505
1506 OSStatus wxMacDataBrowserControl::SetColumnPosition( DataBrowserPropertyID column, DataBrowserTableViewColumnIndex position)
1507 {
1508 return SetDataBrowserTableViewColumnPosition( m_controlRef , column , position);
1509 }
1510
1511 OSStatus wxMacDataBrowserControl::GetScrollPosition( UInt32 *top , UInt32 *left ) const
1512 {
1513 return GetDataBrowserScrollPosition( m_controlRef , top , left );
1514 }
1515
1516 OSStatus wxMacDataBrowserControl::SetScrollPosition( UInt32 top , UInt32 left )
1517 {
1518 return SetDataBrowserScrollPosition( m_controlRef , top , left );
1519 }
1520
1521 OSStatus wxMacDataBrowserControl::GetSortProperty( DataBrowserPropertyID *column ) const
1522 {
1523 return GetDataBrowserSortProperty( m_controlRef , column );
1524 }
1525
1526 OSStatus wxMacDataBrowserControl::SetSortProperty( DataBrowserPropertyID column )
1527 {
1528 return SetDataBrowserSortProperty( m_controlRef , column );
1529 }
1530
1531 OSStatus wxMacDataBrowserControl::GetSortOrder( DataBrowserSortOrder *order ) const
1532 {
1533 return GetDataBrowserSortOrder( m_controlRef , order );
1534 }
1535
1536 OSStatus wxMacDataBrowserControl::SetSortOrder( DataBrowserSortOrder order )
1537 {
1538 return SetDataBrowserSortOrder( m_controlRef , order );
1539 }
1540
1541 OSStatus wxMacDataBrowserControl::GetPropertyFlags( DataBrowserPropertyID property,
1542 DataBrowserPropertyFlags *flags ) const
1543 {
1544 return GetDataBrowserPropertyFlags( m_controlRef , property , flags );
1545 }
1546
1547 OSStatus wxMacDataBrowserControl::SetPropertyFlags( DataBrowserPropertyID property,
1548 DataBrowserPropertyFlags flags )
1549 {
1550 return SetDataBrowserPropertyFlags( m_controlRef , property , flags );
1551 }
1552
1553 OSStatus wxMacDataBrowserControl::GetHeaderDesc( DataBrowserPropertyID property,
1554 DataBrowserListViewHeaderDesc *desc ) const
1555 {
1556 return GetDataBrowserListViewHeaderDesc( m_controlRef , property , desc );
1557 }
1558
1559 OSStatus wxMacDataBrowserControl::SetHeaderDesc( DataBrowserPropertyID property,
1560 DataBrowserListViewHeaderDesc *desc )
1561 {
1562 return SetDataBrowserListViewHeaderDesc( m_controlRef , property , desc );
1563 }
1564
1565 OSStatus wxMacDataBrowserControl::SetDisclosureColumn( DataBrowserPropertyID property ,
1566 Boolean expandableRows )
1567 {
1568 return SetDataBrowserListViewDisclosureColumn( m_controlRef, property, expandableRows);
1569 }
1570
1571 // ============================================================================
1572 // Higher-level Databrowser
1573 // ============================================================================
1574 //
1575 // basing on data item objects
1576 //
1577
1578 wxMacDataItem::wxMacDataItem()
1579 {
1580 m_data = NULL;
1581
1582 m_order = 0;
1583 m_colId = kTextColumnId; // for compat with existing wx*ListBox impls.
1584 }
1585
1586 wxMacDataItem::~wxMacDataItem()
1587 {
1588 }
1589
1590 void wxMacDataItem::SetOrder( SInt32 order )
1591 {
1592 m_order = order;
1593 }
1594
1595 SInt32 wxMacDataItem::GetOrder() const
1596 {
1597 return m_order;
1598 }
1599
1600 void wxMacDataItem::SetData( void* data)
1601 {
1602 m_data = data;
1603 }
1604
1605 void* wxMacDataItem::GetData() const
1606 {
1607 return m_data;
1608 }
1609
1610 short wxMacDataItem::GetColumn()
1611 {
1612 return m_colId;
1613 }
1614
1615 void wxMacDataItem::SetColumn( short col )
1616 {
1617 m_colId = col;
1618 }
1619
1620 void wxMacDataItem::SetLabel( const wxString& str)
1621 {
1622 m_label = str;
1623 m_cfLabel.Assign( str , wxLocale::GetSystemEncoding());
1624 }
1625
1626 const wxString& wxMacDataItem::GetLabel() const
1627 {
1628 return m_label;
1629 }
1630
1631 bool wxMacDataItem::IsLessThan(wxMacDataItemBrowserControl *WXUNUSED(owner) ,
1632 const wxMacDataItem* rhs,
1633 DataBrowserPropertyID sortProperty) const
1634 {
1635 const wxMacDataItem* otherItem = wx_const_cast(wxMacDataItem*,rhs);
1636 bool retval = false;
1637
1638 if ( sortProperty == m_colId ){
1639 retval = m_label.CmpNoCase( otherItem->m_label) < 0;
1640 }
1641
1642 else if ( sortProperty == kNumericOrderColumnId )
1643 retval = m_order < otherItem->m_order;
1644
1645 return retval;
1646 }
1647
1648 OSStatus wxMacDataItem::GetSetData( wxMacDataItemBrowserControl *WXUNUSED(owner) ,
1649 DataBrowserPropertyID property,
1650 DataBrowserItemDataRef itemData,
1651 bool changeValue )
1652 {
1653 OSStatus err = errDataBrowserPropertyNotSupported;
1654 if ( !changeValue )
1655 {
1656 if ( property == m_colId ){
1657 err = ::SetDataBrowserItemDataText( itemData, m_cfLabel );
1658 err = noErr;
1659 }
1660 else if ( property == kNumericOrderColumnId ){
1661 err = ::SetDataBrowserItemDataValue( itemData, m_order );
1662 err = noErr;
1663 }
1664 else{
1665 }
1666 }
1667 else
1668 {
1669 switch (property)
1670 {
1671 // no editable props here
1672 default:
1673 break;
1674 }
1675 }
1676
1677 return err;
1678 }
1679
1680 void wxMacDataItem::Notification(wxMacDataItemBrowserControl *WXUNUSED(owner) ,
1681 DataBrowserItemNotification WXUNUSED(message),
1682 DataBrowserItemDataRef WXUNUSED(itemData) ) const
1683 {
1684 }
1685
1686 IMPLEMENT_DYNAMIC_CLASS( wxMacDataItemBrowserControl , wxMacDataBrowserControl )
1687
1688 wxMacDataItemBrowserControl::wxMacDataItemBrowserControl( wxWindow* peer , const wxPoint& pos, const wxSize& size, long style) :
1689 wxMacDataBrowserControl( peer, pos, size, style )
1690 {
1691 m_suppressSelection = false;
1692 m_sortOrder = SortOrder_None;
1693 m_clientDataItemsType = wxClientData_None;
1694 }
1695
1696 wxMacDataItem* wxMacDataItemBrowserControl::CreateItem()
1697 {
1698 return new wxMacDataItem();
1699 }
1700
1701 wxMacDataItemBrowserSelectionSuppressor::wxMacDataItemBrowserSelectionSuppressor(wxMacDataItemBrowserControl *browser)
1702 {
1703 m_former = browser->SuppressSelection(true);
1704 m_browser = browser;
1705 }
1706
1707 wxMacDataItemBrowserSelectionSuppressor::~wxMacDataItemBrowserSelectionSuppressor()
1708 {
1709 m_browser->SuppressSelection(m_former);
1710 }
1711
1712 bool wxMacDataItemBrowserControl::SuppressSelection( bool suppress )
1713 {
1714 bool former = m_suppressSelection;
1715 m_suppressSelection = suppress;
1716
1717 return former;
1718 }
1719
1720 Boolean wxMacDataItemBrowserControl::CompareItems(DataBrowserItemID itemOneID,
1721 DataBrowserItemID itemTwoID,
1722 DataBrowserPropertyID sortProperty)
1723 {
1724 wxMacDataItem* itemOne = (wxMacDataItem*) itemOneID;
1725 wxMacDataItem* itemTwo = (wxMacDataItem*) itemTwoID;
1726 return CompareItems( itemOne , itemTwo , sortProperty );
1727 }
1728
1729 Boolean wxMacDataItemBrowserControl::CompareItems(const wxMacDataItem* itemOne,
1730 const wxMacDataItem* itemTwo,
1731 DataBrowserPropertyID sortProperty)
1732 {
1733 Boolean retval = false;
1734 if ( itemOne != NULL )
1735 retval = itemOne->IsLessThan( this , itemTwo , sortProperty);
1736 return retval;
1737 }
1738
1739 OSStatus wxMacDataItemBrowserControl::GetSetItemData(
1740 DataBrowserItemID itemID,
1741 DataBrowserPropertyID property,
1742 DataBrowserItemDataRef itemData,
1743 Boolean changeValue )
1744 {
1745 wxMacDataItem* item = (wxMacDataItem*) itemID;
1746 return GetSetItemData(item, property, itemData , changeValue );
1747 }
1748
1749 OSStatus wxMacDataItemBrowserControl::GetSetItemData(
1750 wxMacDataItem* item,
1751 DataBrowserPropertyID property,
1752 DataBrowserItemDataRef itemData,
1753 Boolean changeValue )
1754 {
1755 OSStatus err = errDataBrowserPropertyNotSupported;
1756 switch( property )
1757 {
1758 case kDataBrowserContainerIsClosableProperty :
1759 case kDataBrowserContainerIsSortableProperty :
1760 case kDataBrowserContainerIsOpenableProperty :
1761 // right now default behaviour on these
1762 break;
1763 default :
1764
1765 if ( item != NULL ){
1766 err = item->GetSetData( this, property , itemData , changeValue );
1767 }
1768 break;
1769
1770 }
1771 return err;
1772 }
1773
1774 void wxMacDataItemBrowserControl::ItemNotification(
1775 DataBrowserItemID itemID,
1776 DataBrowserItemNotification message,
1777 DataBrowserItemDataRef itemData)
1778 {
1779 wxMacDataItem* item = (wxMacDataItem*) itemID;
1780 ItemNotification( item , message, itemData);
1781 }
1782
1783 void wxMacDataItemBrowserControl::ItemNotification(
1784 const wxMacDataItem* item,
1785 DataBrowserItemNotification message,
1786 DataBrowserItemDataRef itemData)
1787 {
1788 if (item != NULL)
1789 item->Notification( this, message, itemData);
1790 }
1791
1792 unsigned int wxMacDataItemBrowserControl::GetItemCount(const wxMacDataItem* container,
1793 bool recurse , DataBrowserItemState state) const
1794 {
1795 ItemCount numItems = 0;
1796 verify_noerr( wxMacDataBrowserControl::GetItemCount( (DataBrowserItemID)container,
1797 recurse, state, &numItems ) );
1798 return numItems;
1799 }
1800
1801 unsigned int wxMacDataItemBrowserControl::GetSelectedItemCount( const wxMacDataItem* container,
1802 bool recurse ) const
1803 {
1804 return GetItemCount( container, recurse, kDataBrowserItemIsSelected );
1805
1806 }
1807
1808 void wxMacDataItemBrowserControl::GetItems(const wxMacDataItem* container,
1809 bool recurse , DataBrowserItemState state, wxArrayMacDataItemPtr &items) const
1810 {
1811 Handle handle = NewHandle(0);
1812 verify_noerr( wxMacDataBrowserControl::GetItems( (DataBrowserItemID)container ,
1813 recurse , state, handle) );
1814
1815 int itemCount = GetHandleSize(handle)/sizeof(DataBrowserItemID);
1816 HLock( handle );
1817 wxMacDataItemPtr* itemsArray = (wxMacDataItemPtr*) *handle;
1818 for ( int i = 0; i < itemCount; ++i)
1819 {
1820 items.Add(itemsArray[i]);
1821 }
1822 HUnlock( handle );
1823 DisposeHandle( handle );
1824 }
1825
1826 unsigned int wxMacDataItemBrowserControl::GetLineFromItem(const wxMacDataItem* item) const
1827 {
1828 DataBrowserTableViewRowIndex row;
1829 OSStatus err = GetItemRow( (DataBrowserItemID) item , &row);
1830 wxASSERT( err == noErr);
1831 return row;
1832 }
1833
1834 wxMacDataItem* wxMacDataItemBrowserControl::GetItemFromLine(unsigned int n) const
1835 {
1836 DataBrowserItemID id;
1837 OSStatus err = GetItemID( (DataBrowserTableViewRowIndex) n , &id);
1838 wxASSERT( err == noErr);
1839 return (wxMacDataItem*) id;
1840 }
1841
1842 void wxMacDataItemBrowserControl::UpdateItem(const wxMacDataItem *container,
1843 const wxMacDataItem *item , DataBrowserPropertyID property) const
1844 {
1845 verify_noerr( wxMacDataBrowserControl::UpdateItems((DataBrowserItemID)container, 1,
1846 (DataBrowserItemID*) &item, kDataBrowserItemNoProperty /* notSorted */, property ) );
1847 }
1848
1849 void wxMacDataItemBrowserControl::UpdateItems(const wxMacDataItem *container,
1850 wxArrayMacDataItemPtr &itemArray , DataBrowserPropertyID property) const
1851 {
1852 unsigned int noItems = itemArray.GetCount();
1853 DataBrowserItemID *items = new DataBrowserItemID[noItems];
1854 for ( unsigned int i = 0; i < noItems; ++i )
1855 items[i] = (DataBrowserItemID) itemArray[i];
1856
1857 verify_noerr( wxMacDataBrowserControl::UpdateItems((DataBrowserItemID)container, noItems,
1858 items, kDataBrowserItemNoProperty /* notSorted */, property ) );
1859 delete [] items;
1860 }
1861
1862 void wxMacDataItemBrowserControl::InsertColumn(int colId, DataBrowserPropertyType colType,
1863 const wxString& title, SInt16 just, int defaultWidth)
1864 {
1865 DataBrowserListViewColumnDesc columnDesc;
1866 columnDesc.headerBtnDesc.titleOffset = 0;
1867 columnDesc.headerBtnDesc.version = kDataBrowserListViewLatestHeaderDesc;
1868
1869 columnDesc.headerBtnDesc.btnFontStyle.flags =
1870 kControlUseFontMask | kControlUseJustMask;
1871
1872 columnDesc.headerBtnDesc.btnContentInfo.contentType = kControlContentTextOnly;
1873 columnDesc.headerBtnDesc.btnFontStyle.just = just;
1874 columnDesc.headerBtnDesc.btnFontStyle.font = kControlFontViewSystemFont;
1875 columnDesc.headerBtnDesc.btnFontStyle.style = normal;
1876
1877 // TODO: Why is m_font not defined when we enter wxLC_LIST mode, but is
1878 // defined for other modes?
1879 wxFontEncoding enc;
1880 if ( m_font.Ok() )
1881 enc = m_font.GetEncoding();
1882 else
1883 enc = wxLocale::GetSystemEncoding();
1884 wxMacCFStringHolder cfTitle;
1885 cfTitle.Assign( title, enc );
1886 columnDesc.headerBtnDesc.titleString = cfTitle;
1887
1888 columnDesc.headerBtnDesc.minimumWidth = 0;
1889 columnDesc.headerBtnDesc.maximumWidth = 30000;
1890
1891 columnDesc.propertyDesc.propertyID = (kMinColumnId + colId);
1892 columnDesc.propertyDesc.propertyType = colType;
1893 columnDesc.propertyDesc.propertyFlags = kDataBrowserListViewSortableColumn;
1894 columnDesc.propertyDesc.propertyFlags |= kDataBrowserListViewTypeSelectColumn;
1895 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
1896 columnDesc.propertyDesc.propertyFlags |= kDataBrowserListViewNoGapForIconInHeaderButton;
1897 #endif
1898
1899 verify_noerr( AddColumn( &columnDesc, kDataBrowserListViewAppendColumn ) );
1900
1901 if (defaultWidth > 0){
1902 SetColumnWidth(colId, defaultWidth);
1903 }
1904
1905 }
1906
1907 void wxMacDataItemBrowserControl::SetColumnWidth(int colId, int width)
1908 {
1909 DataBrowserPropertyID id;
1910 GetColumnIDFromIndex(colId, &id);
1911 verify_noerr( wxMacDataBrowserControl::SetColumnWidth(id, width));
1912 }
1913
1914 int wxMacDataItemBrowserControl::GetColumnWidth(int colId)
1915 {
1916 DataBrowserPropertyID id;
1917 GetColumnIDFromIndex(colId, &id);
1918 UInt16 result;
1919 verify_noerr( wxMacDataBrowserControl::GetColumnWidth(id, &result));
1920 return result;
1921 }
1922
1923 void wxMacDataItemBrowserControl::AddItem(wxMacDataItem *container, wxMacDataItem *item)
1924 {
1925 verify_noerr( wxMacDataBrowserControl::AddItems( (DataBrowserItemID)container, 1,
1926 (DataBrowserItemID*) &item, kDataBrowserItemNoProperty ) );
1927 }
1928
1929 void wxMacDataItemBrowserControl::AddItems(wxMacDataItem *container, wxArrayMacDataItemPtr &itemArray )
1930 {
1931 unsigned int noItems = itemArray.GetCount();
1932 DataBrowserItemID *items = new DataBrowserItemID[noItems];
1933 for ( unsigned int i = 0; i < noItems; ++i )
1934 items[i] = (DataBrowserItemID) itemArray[i];
1935
1936 verify_noerr( wxMacDataBrowserControl::AddItems( (DataBrowserItemID)container, noItems,
1937 (DataBrowserItemID*) items, kDataBrowserItemNoProperty ) );
1938 delete [] items;
1939 }
1940
1941 void wxMacDataItemBrowserControl::RemoveItem(wxMacDataItem *container, wxMacDataItem* item)
1942 {
1943 OSStatus err = wxMacDataBrowserControl::RemoveItems( (DataBrowserItemID)container, 1,
1944 (DataBrowserItemID*) &item, kDataBrowserItemNoProperty );
1945 verify_noerr( err );
1946 }
1947
1948 void wxMacDataItemBrowserControl::RemoveItems(wxMacDataItem *container, wxArrayMacDataItemPtr &itemArray)
1949 {
1950 unsigned int noItems = itemArray.GetCount();
1951 DataBrowserItemID *items = new DataBrowserItemID[noItems];
1952 for ( unsigned int i = 0; i < noItems; ++i )
1953 items[i] = (DataBrowserItemID) itemArray[i];
1954
1955 OSStatus err = wxMacDataBrowserControl::RemoveItems( (DataBrowserItemID)container, noItems,
1956 (DataBrowserItemID*) items, kDataBrowserItemNoProperty );
1957 verify_noerr( err );
1958 delete [] items;
1959 }
1960
1961 void wxMacDataItemBrowserControl::RemoveAllItems(wxMacDataItem *container)
1962 {
1963 OSStatus err = wxMacDataBrowserControl::RemoveItems( (DataBrowserItemID)container, 0 , NULL , kDataBrowserItemNoProperty );
1964 verify_noerr( err );
1965 }
1966
1967 void wxMacDataItemBrowserControl::SetSelectedItem(wxMacDataItem* item , DataBrowserSetOption option)
1968 {
1969 verify_noerr(wxMacDataBrowserControl::SetSelectedItems( 1, (DataBrowserItemID*) &item, option ));
1970 }
1971
1972 void wxMacDataItemBrowserControl::SetSelectedAllItems(DataBrowserSetOption option)
1973 {
1974 verify_noerr(wxMacDataBrowserControl::SetSelectedItems( 0 , NULL , option ));
1975 }
1976
1977 void wxMacDataItemBrowserControl::SetSelectedItems(wxArrayMacDataItemPtr &itemArray , DataBrowserSetOption option)
1978 {
1979 unsigned int noItems = itemArray.GetCount();
1980 DataBrowserItemID *items = new DataBrowserItemID[noItems];
1981 for ( unsigned int i = 0; i < noItems; ++i )
1982 items[i] = (DataBrowserItemID) itemArray[i];
1983
1984 verify_noerr(wxMacDataBrowserControl::SetSelectedItems( noItems, (DataBrowserItemID*) items, option ));
1985 delete [] items;
1986 }
1987
1988 Boolean wxMacDataItemBrowserControl::IsItemSelected( const wxMacDataItem* item) const
1989 {
1990 return wxMacDataBrowserControl::IsItemSelected( (DataBrowserItemID) item);
1991 }
1992
1993 void wxMacDataItemBrowserControl::RevealItem( wxMacDataItem* item, DataBrowserRevealOptions options)
1994 {
1995 verify_noerr(wxMacDataBrowserControl::RevealItem( (DataBrowserItemID) item, kDataBrowserNoItem , options ) );
1996 }
1997
1998 void wxMacDataItemBrowserControl::GetSelectionAnchor( wxMacDataItemPtr* first , wxMacDataItemPtr* last) const
1999 {
2000 verify_noerr(wxMacDataBrowserControl::GetSelectionAnchor( (DataBrowserItemID*) first, (DataBrowserItemID*) last) );
2001 }
2002
2003 wxClientDataType wxMacDataItemBrowserControl::GetClientDataType() const
2004 {
2005 return m_clientDataItemsType;
2006 }
2007 void wxMacDataItemBrowserControl::SetClientDataType(wxClientDataType clientDataItemsType)
2008 {
2009 m_clientDataItemsType = clientDataItemsType;
2010 }
2011
2012 unsigned int wxMacDataItemBrowserControl::MacGetCount() const
2013 {
2014 return GetItemCount(wxMacDataBrowserRootContainer,false,kDataBrowserItemAnyState);
2015 }
2016
2017 void wxMacDataItemBrowserControl::MacDelete( unsigned int n )
2018 {
2019 wxMacDataItem* item = (wxMacDataItem*)GetItemFromLine( n );
2020 RemoveItem( wxMacDataBrowserRootContainer, item );
2021 }
2022
2023 void wxMacDataItemBrowserControl::MacInsert( unsigned int n,
2024 const wxArrayStringsAdapter& items,
2025 int column )
2026 {
2027 size_t itemsCount = items.GetCount();
2028 if ( itemsCount == 0 )
2029 return;
2030
2031 SInt32 frontLineOrder = 0;
2032
2033 if ( m_sortOrder == SortOrder_None )
2034 {
2035 // increase the order of the lines to be shifted
2036 unsigned int lines = MacGetCount();
2037 for ( unsigned int i = n; i < lines; ++i)
2038 {
2039 wxMacDataItem* iter = (wxMacDataItem*) GetItemFromLine(i);
2040 iter->SetOrder( iter->GetOrder() + itemsCount );
2041 }
2042 if ( n > 0 )
2043 {
2044 wxMacDataItem* iter = (wxMacDataItem*) GetItemFromLine(n-1);
2045 frontLineOrder = iter->GetOrder();
2046 }
2047 }
2048
2049 wxArrayMacDataItemPtr ids;
2050 ids.SetCount( itemsCount );
2051
2052 for ( unsigned int i = 0; i < itemsCount; ++i )
2053 {
2054 wxMacDataItem* item = CreateItem();
2055 item->SetLabel( items[i]);
2056 if ( column != -1 )
2057 item->SetColumn( kMinColumnId + column );
2058
2059 if ( m_sortOrder == SortOrder_None )
2060 item->SetOrder( frontLineOrder + 1 + i );
2061
2062 ids[i] = item;
2063 }
2064
2065 AddItems( wxMacDataBrowserRootContainer, ids );
2066 }
2067
2068 int wxMacDataItemBrowserControl::MacAppend( const wxString& text)
2069 {
2070 wxMacDataItem* item = CreateItem();
2071 item->SetLabel( text );
2072 if ( m_sortOrder == SortOrder_None )
2073 {
2074 unsigned int lines = MacGetCount();
2075 if ( lines == 0 )
2076 item->SetOrder( 1 );
2077 else
2078 {
2079 wxMacDataItem* frontItem = (wxMacDataItem*) GetItemFromLine(lines-1);
2080 item->SetOrder( frontItem->GetOrder() + 1 );
2081 }
2082 }
2083 AddItem( wxMacDataBrowserRootContainer, item );
2084
2085 return GetLineFromItem(item);
2086 }
2087
2088 void wxMacDataItemBrowserControl::MacClear()
2089 {
2090 wxMacDataItemBrowserSelectionSuppressor suppressor(this);
2091 RemoveAllItems(wxMacDataBrowserRootContainer);
2092 }
2093
2094 void wxMacDataItemBrowserControl::MacDeselectAll()
2095 {
2096 wxMacDataItemBrowserSelectionSuppressor suppressor(this);
2097 SetSelectedAllItems( kDataBrowserItemsRemove );
2098 }
2099
2100 void wxMacDataItemBrowserControl::MacSetSelection( unsigned int n, bool select, bool multi )
2101 {
2102 wxMacDataItem* item = (wxMacDataItem*) GetItemFromLine(n);
2103 wxMacDataItemBrowserSelectionSuppressor suppressor(this);
2104
2105 if ( IsItemSelected( item ) != select )
2106 {
2107 if ( select )
2108 SetSelectedItem( item, multi ? kDataBrowserItemsAdd : kDataBrowserItemsAssign );
2109 else
2110 SetSelectedItem( item, kDataBrowserItemsRemove );
2111 }
2112
2113 MacScrollTo( n );
2114 }
2115
2116 bool wxMacDataItemBrowserControl::MacIsSelected( unsigned int n ) const
2117 {
2118 wxMacDataItem* item = (wxMacDataItem*) GetItemFromLine(n);
2119 return IsItemSelected( item );
2120 }
2121
2122 int wxMacDataItemBrowserControl::MacGetSelection() const
2123 {
2124 wxMacDataItemPtr first, last;
2125 GetSelectionAnchor( &first, &last );
2126
2127 if ( first != NULL )
2128 {
2129 return GetLineFromItem( first );
2130 }
2131
2132 return -1;
2133 }
2134
2135 int wxMacDataItemBrowserControl::MacGetSelections( wxArrayInt& aSelections ) const
2136 {
2137 aSelections.Empty();
2138 wxArrayMacDataItemPtr selectedItems;
2139 GetItems( wxMacDataBrowserRootContainer, false , kDataBrowserItemIsSelected, selectedItems);
2140
2141 int count = selectedItems.GetCount();
2142
2143 for ( int i = 0; i < count; ++i)
2144 {
2145 aSelections.Add(GetLineFromItem(selectedItems[i]));
2146 }
2147
2148 return count;
2149 }
2150
2151 void wxMacDataItemBrowserControl::MacSetString( unsigned int n, const wxString& text )
2152 {
2153 // as we don't store the strings we only have to issue a redraw
2154 wxMacDataItem* item = (wxMacDataItem*) GetItemFromLine( n);
2155 item->SetLabel( text );
2156 UpdateItem( wxMacDataBrowserRootContainer, item , kTextColumnId );
2157 }
2158
2159 wxString wxMacDataItemBrowserControl::MacGetString( unsigned int n ) const
2160 {
2161 wxMacDataItem * item = (wxMacDataItem*) GetItemFromLine( n );
2162 return item->GetLabel();
2163 }
2164
2165 void wxMacDataItemBrowserControl::MacSetClientData( unsigned int n, void * data)
2166 {
2167 wxMacDataItem* item = (wxMacDataItem*) GetItemFromLine( n);
2168 item->SetData( data );
2169 // not displayed, therefore no Update infos to DataBrowser
2170 }
2171
2172 void * wxMacDataItemBrowserControl::MacGetClientData( unsigned int n) const
2173 {
2174 wxMacDataItem * item = (wxMacDataItem*) GetItemFromLine( n );
2175 return item->GetData();
2176 }
2177
2178 void wxMacDataItemBrowserControl::MacScrollTo( unsigned int n )
2179 {
2180 UInt32 top , left ;
2181 GetScrollPosition( &top , &left ) ;
2182 wxMacDataItem * item = (wxMacDataItem*) GetItemFromLine( n );
2183
2184 UInt16 height ;
2185 GetRowHeight( (DataBrowserItemID) item , &height ) ;
2186 SetScrollPosition( n * ((UInt32)height) , left ) ;
2187
2188 RevealItem( item , kDataBrowserRevealWithoutSelecting );
2189 }
2190
2191
2192
2193 //
2194 // Tab Control
2195 //
2196
2197 OSStatus wxMacControl::SetTabEnabled( SInt16 tabNo , bool enable )
2198 {
2199 return ::SetTabEnabled( m_controlRef , tabNo , enable );
2200 }
2201
2202 //
2203 // Quartz Support
2204 //
2205
2206 // snippets from Sketch Sample from Apple :
2207
2208 #define kGenericRGBProfilePathStr "/System/Library/ColorSync/Profiles/Generic RGB Profile.icc"
2209
2210 /*
2211 This function locates, opens, and returns the profile reference for the calibrated
2212 Generic RGB color space. It is up to the caller to call CMCloseProfile when done
2213 with the profile reference this function returns.
2214 */
2215 CMProfileRef wxMacOpenGenericProfile()
2216 {
2217 static CMProfileRef cachedRGBProfileRef = NULL;
2218
2219 // we only create the profile reference once
2220 if (cachedRGBProfileRef == NULL)
2221 {
2222 CMProfileLocation loc;
2223
2224 loc.locType = cmPathBasedProfile;
2225 strcpy(loc.u.pathLoc.path, kGenericRGBProfilePathStr);
2226
2227 verify_noerr( CMOpenProfile(&cachedRGBProfileRef, &loc) );
2228 }
2229
2230 // clone the profile reference so that the caller has their own reference, not our cached one
2231 if (cachedRGBProfileRef)
2232 CMCloneProfileRef(cachedRGBProfileRef);
2233
2234 return cachedRGBProfileRef;
2235 }
2236
2237 /*
2238 Return the generic RGB color space. This is a 'get' function and the caller should
2239 not release the returned value unless the caller retains it first. Usually callers
2240 of this routine will immediately use the returned colorspace with CoreGraphics
2241 so they typically do not need to retain it themselves.
2242
2243 This function creates the generic RGB color space once and hangs onto it so it can
2244 return it whenever this function is called.
2245 */
2246
2247 CGColorSpaceRef wxMacGetGenericRGBColorSpace()
2248 {
2249 static wxMacCFRefHolder<CGColorSpaceRef> genericRGBColorSpace;
2250
2251 if (genericRGBColorSpace == NULL)
2252 {
2253 if ( UMAGetSystemVersion() >= 0x1040 )
2254 {
2255 genericRGBColorSpace.Set( CGColorSpaceCreateWithName( CFSTR("kCGColorSpaceGenericRGB") ) );
2256 }
2257 else
2258 {
2259 CMProfileRef genericRGBProfile = wxMacOpenGenericProfile();
2260
2261 if (genericRGBProfile)
2262 {
2263 genericRGBColorSpace.Set( CGColorSpaceCreateWithPlatformColorSpace(genericRGBProfile) );
2264
2265 wxASSERT_MSG( genericRGBColorSpace != NULL, wxT("couldn't create the generic RGB color space") );
2266
2267 // we opened the profile so it is up to us to close it
2268 CMCloseProfile(genericRGBProfile);
2269 }
2270 }
2271 }
2272
2273 return genericRGBColorSpace;
2274 }
2275
2276 #ifndef __LP64__
2277
2278 wxMacPortSaver::wxMacPortSaver( GrafPtr port )
2279 {
2280 ::GetPort( &m_port );
2281 ::SetPort( port );
2282 }
2283
2284 wxMacPortSaver::~wxMacPortSaver()
2285 {
2286 ::SetPort( m_port );
2287 }
2288 #endif
2289
2290 void wxMacGlobalToLocal( WindowRef window , Point*pt )
2291 {
2292 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4
2293 HIPoint p = CGPointMake( pt->h, pt->v );
2294 HIViewRef contentView ;
2295 // TODO check toolbar offset
2296 HIViewFindByID( HIViewGetRoot( window ), kHIViewWindowContentID , &contentView) ;
2297 HIPointConvert( &p, kHICoordSpace72DPIGlobal, NULL, kHICoordSpaceView, contentView );
2298 pt->h = p.x;
2299 pt->v = p.y;
2300 #else
2301 QDGlobalToLocalPoint( GetWindowPort(window), pt ) ;
2302 #endif
2303 }
2304
2305 void wxMacLocalToGlobal( WindowRef window , Point*pt )
2306 {
2307 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4
2308 HIPoint p = CGPointMake( pt->h, pt->v );
2309 HIViewRef contentView ;
2310 // TODO check toolbar offset
2311 HIViewFindByID( HIViewGetRoot( window ), kHIViewWindowContentID , &contentView) ;
2312 HIPointConvert( &p, kHICoordSpaceView, contentView, kHICoordSpace72DPIGlobal, NULL );
2313 pt->h = p.x;
2314 pt->v = p.y;
2315 #else
2316 QDLocalToGlobalPoint( GetWindowPort(window), pt ) ;
2317 #endif
2318 }
2319
2320 #endif // wxUSE_GUI