]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/utils.cpp
correction to last commit: don't test unsetenv() return value, it's void under Darwin
[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 *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 wxChar *wxGetUserHome (const wxString& user)
593 {
594 // TODO
595 return NULL;
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 #if TARGET_CARBON
675 OSStatus err = noErr;
676
677 #if 0
678 // lead sometimes to race conditions, although all calls used should be thread safe ...
679 static wxMacCarbonEvent s_wakeupEvent;
680 if ( !s_wakeupEvent.IsValid() )
681 {
682 err = s_wakeupEvent.Create( 'WXMC', 'WXMC', GetCurrentEventTime(),
683 kEventAttributeNone );
684 }
685 if ( err == noErr )
686 {
687
688 if ( IsEventInQueue( GetMainEventQueue() , s_wakeupEvent ) )
689 return;
690 s_wakeupEvent.SetCurrentTime();
691 err = PostEventToQueue(GetMainEventQueue(), s_wakeupEvent,
692 kEventPriorityHigh );
693 }
694 #else
695 wxMacCarbonEvent wakeupEvent;
696 wakeupEvent.Create( 'WXMC', 'WXMC', GetCurrentEventTime(),
697 kEventAttributeNone );
698 err = PostEventToQueue(GetMainEventQueue(), wakeupEvent,
699 kEventPriorityHigh );
700 #endif
701 #else
702 PostEvent( nullEvent , 0 );
703 #endif
704 }
705 else
706 {
707 WakeUpProcess( &gAppProcess );
708 }
709 }
710
711 #endif // wxUSE_BASE
712
713 #if wxUSE_GUI
714
715 // ----------------------------------------------------------------------------
716 // Native Struct Conversions
717 // ----------------------------------------------------------------------------
718
719 void wxMacRectToNative( const wxRect *wx , Rect *n )
720 {
721 n->left = wx->x;
722 n->top = wx->y;
723 n->right = wx->x + wx->width;
724 n->bottom = wx->y + wx->height;
725 }
726
727 void wxMacNativeToRect( const Rect *n , wxRect* wx )
728 {
729 wx->x = n->left;
730 wx->y = n->top;
731 wx->width = n->right - n->left;
732 wx->height = n->bottom - n->top;
733 }
734
735 void wxMacPointToNative( const wxPoint* wx , Point *n )
736 {
737 n->h = wx->x;
738 n->v = wx->y;
739 }
740
741 void wxMacNativeToPoint( const Point *n , wxPoint* wx )
742 {
743 wx->x = n->h;
744 wx->y = n->v;
745 }
746
747 // ----------------------------------------------------------------------------
748 // Carbon Event Support
749 // ----------------------------------------------------------------------------
750
751 OSStatus wxMacCarbonEvent::GetParameter(EventParamName inName, EventParamType inDesiredType, UInt32 inBufferSize, void * outData)
752 {
753 return ::GetEventParameter( m_eventRef , inName , inDesiredType , NULL , inBufferSize , NULL , outData );
754 }
755
756 OSStatus wxMacCarbonEvent::SetParameter(EventParamName inName, EventParamType inType, UInt32 inBufferSize, const void * inData)
757 {
758 return ::SetEventParameter( m_eventRef , inName , inType , inBufferSize , inData );
759 }
760
761 // ----------------------------------------------------------------------------
762 // Control Access Support
763 // ----------------------------------------------------------------------------
764
765 IMPLEMENT_DYNAMIC_CLASS( wxMacControl , wxObject )
766
767 wxMacControl::wxMacControl()
768 {
769 Init();
770 }
771
772 wxMacControl::wxMacControl(wxWindow* peer , bool isRootControl )
773 {
774 Init();
775 m_peer = peer;
776 m_isRootControl = isRootControl;
777 }
778
779 wxMacControl::wxMacControl( wxWindow* peer , ControlRef control )
780 {
781 Init();
782 m_peer = peer;
783 m_controlRef = control;
784 }
785
786 wxMacControl::wxMacControl( wxWindow* peer , WXWidget control )
787 {
788 Init();
789 m_peer = peer;
790 m_controlRef = (ControlRef) control;
791 }
792
793 wxMacControl::~wxMacControl()
794 {
795 }
796
797 void wxMacControl::Init()
798 {
799 m_peer = NULL;
800 m_controlRef = NULL;
801 m_needsFocusRect = false;
802 m_isRootControl = false;
803 }
804
805 void wxMacControl::Dispose()
806 {
807 wxASSERT_MSG( m_controlRef != NULL , wxT("Control Handle already NULL, Dispose called twice ?") );
808 wxASSERT_MSG( IsValidControlHandle(m_controlRef) , wxT("Invalid Control Handle (maybe already released) in Dispose") );
809
810 // we cannot check the ref count here anymore, as autorelease objects might delete their refs later
811 // we can have situations when being embedded, where the control gets deleted behind our back, so only
812 // CFRelease if we are safe
813 if ( IsValidControlHandle(m_controlRef) )
814 CFRelease(m_controlRef);
815 m_controlRef = NULL;
816 }
817
818 void wxMacControl::SetReference( URefCon data )
819 {
820 SetControlReference( m_controlRef , data );
821 }
822
823 OSStatus wxMacControl::GetData(ControlPartCode inPartCode , ResType inTag , Size inBufferSize , void * inOutBuffer , Size * outActualSize ) const
824 {
825 return ::GetControlData( m_controlRef , inPartCode , inTag , inBufferSize , inOutBuffer , outActualSize );
826 }
827
828 OSStatus wxMacControl::GetDataSize(ControlPartCode inPartCode , ResType inTag , Size * outActualSize ) const
829 {
830 return ::GetControlDataSize( m_controlRef , inPartCode , inTag , outActualSize );
831 }
832
833 OSStatus wxMacControl::SetData(ControlPartCode inPartCode , ResType inTag , Size inSize , const void * inData)
834 {
835 return ::SetControlData( m_controlRef , inPartCode , inTag , inSize , inData );
836 }
837
838 OSStatus wxMacControl::SendEvent( EventRef event , OptionBits inOptions )
839 {
840 #if TARGET_API_MAC_OSX
841 return SendEventToEventTargetWithOptions( event,
842 HIObjectGetEventTarget( (HIObjectRef) m_controlRef ), inOptions );
843 #else
844 #pragma unused(inOptions)
845 return SendEventToEventTarget(event,GetControlEventTarget( m_controlRef ) );
846 #endif
847 }
848
849 OSStatus wxMacControl::SendHICommand( HICommand &command , OptionBits inOptions )
850 {
851 wxMacCarbonEvent event( kEventClassCommand , kEventCommandProcess );
852
853 event.SetParameter<HICommand>(kEventParamDirectObject,command);
854
855 return SendEvent( event , inOptions );
856 }
857
858 OSStatus wxMacControl::SendHICommand( UInt32 commandID , OptionBits inOptions )
859 {
860 HICommand command;
861
862 memset( &command, 0 , sizeof(command) );
863 command.commandID = commandID;
864 return SendHICommand( command , inOptions );
865 }
866
867 void wxMacControl::Flash( ControlPartCode part , UInt32 ticks )
868 {
869 unsigned long finalTicks;
870
871 HiliteControl( m_controlRef , part );
872 Delay( ticks , &finalTicks );
873 HiliteControl( m_controlRef , kControlNoPart );
874 }
875
876 SInt32 wxMacControl::GetValue() const
877 {
878 return ::GetControl32BitValue( m_controlRef );
879 }
880
881 SInt32 wxMacControl::GetMaximum() const
882 {
883 return ::GetControl32BitMaximum( m_controlRef );
884 }
885
886 SInt32 wxMacControl::GetMinimum() const
887 {
888 return ::GetControl32BitMinimum( m_controlRef );
889 }
890
891 void wxMacControl::SetValue( SInt32 v )
892 {
893 ::SetControl32BitValue( m_controlRef , v );
894 }
895
896 void wxMacControl::SetMinimum( SInt32 v )
897 {
898 ::SetControl32BitMinimum( m_controlRef , v );
899 }
900
901 void wxMacControl::SetMaximum( SInt32 v )
902 {
903 ::SetControl32BitMaximum( m_controlRef , v );
904 }
905
906 void wxMacControl::SetValueAndRange( SInt32 value , SInt32 minimum , SInt32 maximum )
907 {
908 ::SetControl32BitMinimum( m_controlRef , minimum );
909 ::SetControl32BitMaximum( m_controlRef , maximum );
910 ::SetControl32BitValue( m_controlRef , value );
911 }
912
913 OSStatus wxMacControl::SetFocus( ControlFocusPart focusPart )
914 {
915 return SetKeyboardFocus( GetControlOwner( m_controlRef ), m_controlRef, focusPart );
916 }
917
918 bool wxMacControl::HasFocus() const
919 {
920 ControlRef control;
921 GetKeyboardFocus( GetUserFocusWindow() , &control );
922 return control == m_controlRef;
923 }
924
925 void wxMacControl::SetNeedsFocusRect( bool needs )
926 {
927 m_needsFocusRect = needs;
928 }
929
930 bool wxMacControl::NeedsFocusRect() const
931 {
932 return m_needsFocusRect;
933 }
934
935 void wxMacControl::VisibilityChanged(bool shown)
936 {
937 }
938
939 void wxMacControl::SuperChangedPosition()
940 {
941 }
942
943 void wxMacControl::SetFont( const wxFont & font , const wxColour& foreground , long windowStyle )
944 {
945 m_font = font;
946 ControlFontStyleRec fontStyle;
947 if ( font.MacGetThemeFontID() != kThemeCurrentPortFont )
948 {
949 switch ( font.MacGetThemeFontID() )
950 {
951 case kThemeSmallSystemFont :
952 fontStyle.font = kControlFontSmallSystemFont;
953 break;
954
955 case 109 : // mini font
956 fontStyle.font = -5;
957 break;
958
959 case kThemeSystemFont :
960 fontStyle.font = kControlFontBigSystemFont;
961 break;
962
963 default :
964 fontStyle.font = kControlFontBigSystemFont;
965 break;
966 }
967
968 fontStyle.flags = kControlUseFontMask;
969 }
970 else
971 {
972 fontStyle.font = font.MacGetFontNum();
973 fontStyle.style = font.MacGetFontStyle();
974 fontStyle.size = font.MacGetFontSize();
975 fontStyle.flags = kControlUseFontMask | kControlUseFaceMask | kControlUseSizeMask;
976 }
977
978 fontStyle.just = teJustLeft;
979 fontStyle.flags |= kControlUseJustMask;
980 if ( ( windowStyle & wxALIGN_MASK ) & wxALIGN_CENTER_HORIZONTAL )
981 fontStyle.just = teJustCenter;
982 else if ( ( windowStyle & wxALIGN_MASK ) & wxALIGN_RIGHT )
983 fontStyle.just = teJustRight;
984
985
986 // we only should do this in case of a non-standard color, as otherwise 'disabled' controls
987 // won't get grayed out by the system anymore
988
989 if ( foreground != *wxBLACK )
990 {
991 fontStyle.foreColor = MAC_WXCOLORREF( foreground.GetPixel() );
992 fontStyle.flags |= kControlUseForeColorMask;
993 }
994
995 ::SetControlFontStyle( m_controlRef , &fontStyle );
996 }
997
998 void wxMacControl::SetBackground( const wxBrush &WXUNUSED(brush) )
999 {
1000 // TODO
1001 // setting up a color proc is not recommended anymore
1002 }
1003
1004 void wxMacControl::SetRange( SInt32 minimum , SInt32 maximum )
1005 {
1006 ::SetControl32BitMinimum( m_controlRef , minimum );
1007 ::SetControl32BitMaximum( m_controlRef , maximum );
1008 }
1009
1010 short wxMacControl::HandleKey( SInt16 keyCode, SInt16 charCode, EventModifiers modifiers )
1011 {
1012 #ifndef __LP64__
1013 return HandleControlKey( m_controlRef , keyCode , charCode , modifiers );
1014 #else
1015 return 0;
1016 #endif
1017 }
1018
1019 void wxMacControl::SetActionProc( ControlActionUPP actionProc )
1020 {
1021 SetControlAction( m_controlRef , actionProc );
1022 }
1023
1024 void wxMacControl::SetViewSize( SInt32 viewSize )
1025 {
1026 SetControlViewSize(m_controlRef , viewSize );
1027 }
1028
1029 SInt32 wxMacControl::GetViewSize() const
1030 {
1031 return GetControlViewSize( m_controlRef );
1032 }
1033
1034 bool wxMacControl::IsVisible() const
1035 {
1036 return IsControlVisible( m_controlRef );
1037 }
1038
1039 void wxMacControl::SetVisibility( bool visible , bool redraw )
1040 {
1041 SetControlVisibility( m_controlRef , visible , redraw );
1042 }
1043
1044 bool wxMacControl::IsEnabled() const
1045 {
1046 #if TARGET_API_MAC_OSX
1047 return IsControlEnabled( m_controlRef );
1048 #else
1049 return IsControlActive( m_controlRef );
1050 #endif
1051 }
1052
1053 bool wxMacControl::IsActive() const
1054 {
1055 return IsControlActive( m_controlRef );
1056 }
1057
1058 void wxMacControl::Enable( bool enable )
1059 {
1060 if ( enable )
1061 EnableControl( m_controlRef );
1062 else
1063 DisableControl( m_controlRef );
1064 }
1065
1066 void wxMacControl::SetDrawingEnabled( bool enable )
1067 {
1068 HIViewSetDrawingEnabled( m_controlRef , enable );
1069 }
1070
1071 bool wxMacControl::GetNeedsDisplay() const
1072 {
1073 return HIViewGetNeedsDisplay( m_controlRef );
1074 }
1075
1076 void wxMacControl::SetNeedsDisplay( RgnHandle where )
1077 {
1078 if ( !IsVisible() )
1079 return;
1080
1081 HIViewSetNeedsDisplayInRegion( m_controlRef , where , true );
1082 }
1083
1084 void wxMacControl::SetNeedsDisplay( Rect* where )
1085 {
1086 if ( !IsVisible() )
1087 return;
1088
1089 if ( where != NULL )
1090 {
1091 RgnHandle update = NewRgn();
1092 RectRgn( update , where );
1093 HIViewSetNeedsDisplayInRegion( m_controlRef , update , true );
1094 DisposeRgn( update );
1095 }
1096 else
1097 HIViewSetNeedsDisplay( m_controlRef , true );
1098 }
1099
1100 void wxMacControl::Convert( wxPoint *pt , wxMacControl *from , wxMacControl *to )
1101 {
1102 HIPoint hiPoint;
1103
1104 hiPoint.x = pt->x;
1105 hiPoint.y = pt->y;
1106 HIViewConvertPoint( &hiPoint , from->m_controlRef , to->m_controlRef );
1107 pt->x = (int)hiPoint.x;
1108 pt->y = (int)hiPoint.y;
1109 }
1110
1111 void wxMacControl::SetRect( Rect *r )
1112 {
1113 //A HIRect is actually a CGRect on OSX - which consists of two structures -
1114 //CGPoint and CGSize, which have two floats each
1115 HIRect hir = { { r->left , r->top }, { r->right - r->left , r->bottom - r->top } };
1116 HIViewSetFrame ( m_controlRef , &hir );
1117 // eventuall we might have to do a SetVisibility( false , true );
1118 // before and a SetVisibility( true , true ); after
1119 }
1120
1121 void wxMacControl::GetRect( Rect *r )
1122 {
1123 GetControlBounds( m_controlRef , r );
1124 }
1125
1126 void wxMacControl::GetRectInWindowCoords( Rect *r )
1127 {
1128 UMAGetControlBoundsInWindowCoords( m_controlRef , r );
1129 }
1130
1131 void wxMacControl::GetBestRect( Rect *r )
1132 {
1133 short baselineoffset;
1134
1135 GetBestControlRect( m_controlRef , r , &baselineoffset );
1136 }
1137
1138 void wxMacControl::SetLabel( const wxString &title )
1139 {
1140 wxFontEncoding encoding;
1141
1142 if ( m_font.Ok() )
1143 encoding = m_font.GetEncoding();
1144 else
1145 encoding = wxFont::GetDefaultEncoding();
1146
1147 UMASetControlTitle( m_controlRef , title , encoding );
1148 }
1149
1150 void wxMacControl::GetFeatures( UInt32 * features )
1151 {
1152 GetControlFeatures( m_controlRef , features );
1153 }
1154
1155 OSStatus wxMacControl::GetRegion( ControlPartCode partCode , RgnHandle region )
1156 {
1157 OSStatus err = GetControlRegion( m_controlRef , partCode , region );
1158 return err;
1159 }
1160
1161 OSStatus wxMacControl::SetZOrder( bool above , wxMacControl* other )
1162 {
1163 #if TARGET_API_MAC_OSX
1164 return HIViewSetZOrder( m_controlRef,above ? kHIViewZOrderAbove : kHIViewZOrderBelow,
1165 (other != NULL) ? other->m_controlRef : NULL);
1166 #else
1167 return 0;
1168 #endif
1169 }
1170
1171 #if TARGET_API_MAC_OSX
1172 // SetNeedsDisplay would not invalidate the children
1173 static void InvalidateControlAndChildren( HIViewRef control )
1174 {
1175 HIViewSetNeedsDisplay( control , true );
1176 UInt16 childrenCount = 0;
1177 OSStatus err = CountSubControls( control , &childrenCount );
1178 if ( err == errControlIsNotEmbedder )
1179 return;
1180
1181 wxASSERT_MSG( err == noErr , wxT("Unexpected error when accessing subcontrols") );
1182
1183 for ( UInt16 i = childrenCount; i >=1; --i )
1184 {
1185 HIViewRef child;
1186
1187 err = GetIndexedSubControl( control , i , & child );
1188 if ( err == errControlIsNotEmbedder )
1189 return;
1190
1191 InvalidateControlAndChildren( child );
1192 }
1193 }
1194 #endif
1195
1196 void wxMacControl::InvalidateWithChildren()
1197 {
1198 #if TARGET_API_MAC_OSX
1199 InvalidateControlAndChildren( m_controlRef );
1200 #endif
1201 }
1202
1203 void wxMacControl::ScrollRect( wxRect *r , int dx , int dy )
1204 {
1205 wxASSERT( r != NULL );
1206
1207 HIRect scrollarea = CGRectMake( r->x , r->y , r->width , r->height);
1208 HIViewScrollRect ( m_controlRef , &scrollarea , dx ,dy );
1209 }
1210
1211 OSType wxMacCreator = 'WXMC';
1212 OSType wxMacControlProperty = 'MCCT';
1213
1214 void wxMacControl::SetReferenceInNativeControl()
1215 {
1216 void * data = this;
1217 verify_noerr( SetControlProperty ( m_controlRef ,
1218 wxMacCreator,wxMacControlProperty, sizeof(data), &data ) );
1219 }
1220
1221 wxMacControl* wxMacControl::GetReferenceFromNativeControl(ControlRef control)
1222 {
1223 wxMacControl* ctl = NULL;
1224 ByteCount actualSize;
1225 if ( GetControlProperty( control ,wxMacCreator,wxMacControlProperty, sizeof(ctl) ,
1226 &actualSize , &ctl ) == noErr )
1227 {
1228 return ctl;
1229 }
1230 return NULL;
1231 }
1232
1233 // ============================================================================
1234 // DataBrowser Wrapper
1235 // ============================================================================
1236 //
1237 // basing on DataBrowserItemIDs
1238 //
1239
1240 IMPLEMENT_ABSTRACT_CLASS( wxMacDataBrowserControl , wxMacControl )
1241
1242 pascal void wxMacDataBrowserControl::DataBrowserItemNotificationProc(
1243 ControlRef browser,
1244 DataBrowserItemID itemID,
1245 DataBrowserItemNotification message,
1246 DataBrowserItemDataRef itemData )
1247 {
1248 wxMacDataBrowserControl* ctl = wxDynamicCast(wxMacControl::GetReferenceFromNativeControl( browser ), wxMacDataBrowserControl);
1249 if ( ctl != 0 )
1250 {
1251 ctl->ItemNotification(itemID, message, itemData);
1252 }
1253 }
1254
1255 pascal OSStatus wxMacDataBrowserControl::DataBrowserGetSetItemDataProc(
1256 ControlRef browser,
1257 DataBrowserItemID itemID,
1258 DataBrowserPropertyID property,
1259 DataBrowserItemDataRef itemData,
1260 Boolean changeValue )
1261 {
1262 OSStatus err = errDataBrowserPropertyNotSupported;
1263 wxMacDataBrowserControl* ctl = wxDynamicCast(wxMacControl::GetReferenceFromNativeControl( browser ), wxMacDataBrowserControl);
1264 if ( ctl != 0 )
1265 {
1266 err = ctl->GetSetItemData(itemID, property, itemData, changeValue);
1267 }
1268 return err;
1269 }
1270
1271 pascal Boolean wxMacDataBrowserControl::DataBrowserCompareProc(
1272 ControlRef browser,
1273 DataBrowserItemID itemOneID,
1274 DataBrowserItemID itemTwoID,
1275 DataBrowserPropertyID sortProperty)
1276 {
1277 wxMacDataBrowserControl* ctl = wxDynamicCast(wxMacControl::GetReferenceFromNativeControl( browser ), wxMacDataBrowserControl);
1278 if ( ctl != 0 )
1279 {
1280 return ctl->CompareItems(itemOneID, itemTwoID, sortProperty);
1281 }
1282 return false;
1283 }
1284
1285 DataBrowserItemDataUPP gDataBrowserItemDataUPP = NULL;
1286 DataBrowserItemNotificationUPP gDataBrowserItemNotificationUPP = NULL;
1287 DataBrowserItemCompareUPP gDataBrowserItemCompareUPP = NULL;
1288
1289 wxMacDataBrowserControl::wxMacDataBrowserControl( wxWindow* peer, const wxPoint& pos, const wxSize& size, long style) : wxMacControl( peer )
1290 {
1291 Rect bounds = wxMacGetBoundsForControl( peer, pos, size );
1292 OSStatus err = ::CreateDataBrowserControl(
1293 MAC_WXHWND(peer->MacGetTopLevelWindowRef()),
1294 &bounds, kDataBrowserListView, &m_controlRef );
1295 SetReferenceInNativeControl();
1296 verify_noerr( err );
1297 if ( gDataBrowserItemCompareUPP == NULL )
1298 gDataBrowserItemCompareUPP = NewDataBrowserItemCompareUPP(DataBrowserCompareProc);
1299 if ( gDataBrowserItemDataUPP == NULL )
1300 gDataBrowserItemDataUPP = NewDataBrowserItemDataUPP(DataBrowserGetSetItemDataProc);
1301 if ( gDataBrowserItemNotificationUPP == NULL )
1302 {
1303 gDataBrowserItemNotificationUPP =
1304 #if TARGET_API_MAC_OSX
1305 (DataBrowserItemNotificationUPP) NewDataBrowserItemNotificationWithItemUPP(DataBrowserItemNotificationProc);
1306 #else
1307 NewDataBrowserItemNotificationUPP(DataBrowserItemNotificationProc);
1308 #endif
1309 }
1310
1311 DataBrowserCallbacks callbacks;
1312 InitializeDataBrowserCallbacks( &callbacks, kDataBrowserLatestCallbacks );
1313
1314 callbacks.u.v1.itemDataCallback = gDataBrowserItemDataUPP;
1315 callbacks.u.v1.itemCompareCallback = gDataBrowserItemCompareUPP;
1316 callbacks.u.v1.itemNotificationCallback = gDataBrowserItemNotificationUPP;
1317 SetCallbacks( &callbacks );
1318
1319 }
1320
1321 OSStatus wxMacDataBrowserControl::GetItemCount( DataBrowserItemID container,
1322 Boolean recurse,
1323 DataBrowserItemState state,
1324 ItemCount *numItems) const
1325 {
1326 return GetDataBrowserItemCount( m_controlRef, container, recurse, state, numItems );
1327 }
1328
1329 OSStatus wxMacDataBrowserControl::GetItems( DataBrowserItemID container,
1330 Boolean recurse,
1331 DataBrowserItemState state,
1332 Handle items) const
1333 {
1334 return GetDataBrowserItems( m_controlRef, container, recurse, state, items );
1335 }
1336
1337 OSStatus wxMacDataBrowserControl::SetSelectionFlags( DataBrowserSelectionFlags options )
1338 {
1339 return SetDataBrowserSelectionFlags( m_controlRef, options );
1340 }
1341
1342 OSStatus wxMacDataBrowserControl::AddColumn( DataBrowserListViewColumnDesc *columnDesc,
1343 DataBrowserTableViewColumnIndex position )
1344 {
1345 return AddDataBrowserListViewColumn( m_controlRef, columnDesc, position );
1346 }
1347
1348 OSStatus wxMacDataBrowserControl::GetColumnIDFromIndex( DataBrowserTableViewColumnIndex position, DataBrowserTableViewColumnID* id ){
1349 return GetDataBrowserTableViewColumnProperty( m_controlRef, position, id );
1350 }
1351
1352 OSStatus wxMacDataBrowserControl::RemoveColumn( DataBrowserTableViewColumnIndex position )
1353 {
1354 DataBrowserTableViewColumnID id;
1355 GetColumnIDFromIndex( position, &id );
1356 return RemoveDataBrowserTableViewColumn( m_controlRef, id );
1357 }
1358
1359 OSStatus wxMacDataBrowserControl::AutoSizeColumns()
1360 {
1361 return AutoSizeDataBrowserListViewColumns(m_controlRef);
1362 }
1363
1364 OSStatus wxMacDataBrowserControl::SetHasScrollBars( bool horiz, bool vert )
1365 {
1366 return SetDataBrowserHasScrollBars( m_controlRef, horiz, vert );
1367 }
1368
1369 OSStatus wxMacDataBrowserControl::SetHiliteStyle( DataBrowserTableViewHiliteStyle hiliteStyle )
1370 {
1371 return SetDataBrowserTableViewHiliteStyle( m_controlRef, hiliteStyle );
1372 }
1373
1374 OSStatus wxMacDataBrowserControl::SetHeaderButtonHeight(UInt16 height)
1375 {
1376 return SetDataBrowserListViewHeaderBtnHeight( m_controlRef, height );
1377 }
1378
1379 OSStatus wxMacDataBrowserControl::GetHeaderButtonHeight(UInt16 *height)
1380 {
1381 return GetDataBrowserListViewHeaderBtnHeight( m_controlRef, height );
1382 }
1383
1384 OSStatus wxMacDataBrowserControl::SetCallbacks(const DataBrowserCallbacks *callbacks)
1385 {
1386 return SetDataBrowserCallbacks( m_controlRef, callbacks );
1387 }
1388
1389 OSStatus wxMacDataBrowserControl::UpdateItems(
1390 DataBrowserItemID container,
1391 UInt32 numItems,
1392 const DataBrowserItemID *items,
1393 DataBrowserPropertyID preSortProperty,
1394 DataBrowserPropertyID propertyID ) const
1395 {
1396 return UpdateDataBrowserItems( m_controlRef, container, numItems, items, preSortProperty, propertyID );
1397 }
1398
1399 bool wxMacDataBrowserControl::IsItemSelected( DataBrowserItemID item ) const
1400 {
1401 return IsDataBrowserItemSelected( m_controlRef, item );
1402 }
1403
1404 OSStatus wxMacDataBrowserControl::AddItems(
1405 DataBrowserItemID container,
1406 UInt32 numItems,
1407 const DataBrowserItemID *items,
1408 DataBrowserPropertyID preSortProperty )
1409 {
1410 return AddDataBrowserItems( m_controlRef, container, numItems, items, preSortProperty );
1411 }
1412
1413 OSStatus wxMacDataBrowserControl::RemoveItems(
1414 DataBrowserItemID container,
1415 UInt32 numItems,
1416 const DataBrowserItemID *items,
1417 DataBrowserPropertyID preSortProperty )
1418 {
1419 return RemoveDataBrowserItems( m_controlRef, container, numItems, items, preSortProperty );
1420 }
1421
1422 OSStatus wxMacDataBrowserControl::RevealItem(
1423 DataBrowserItemID item,
1424 DataBrowserPropertyID propertyID,
1425 DataBrowserRevealOptions options ) const
1426 {
1427 return RevealDataBrowserItem( m_controlRef, item, propertyID, options );
1428 }
1429
1430 OSStatus wxMacDataBrowserControl::SetSelectedItems(
1431 UInt32 numItems,
1432 const DataBrowserItemID *items,
1433 DataBrowserSetOption operation )
1434 {
1435 return SetDataBrowserSelectedItems( m_controlRef, numItems, items, operation );
1436 }
1437
1438 OSStatus wxMacDataBrowserControl::GetSelectionAnchor( DataBrowserItemID *first, DataBrowserItemID *last ) const
1439 {
1440 return GetDataBrowserSelectionAnchor( m_controlRef, first, last );
1441 }
1442
1443 OSStatus wxMacDataBrowserControl::GetItemID( DataBrowserTableViewRowIndex row, DataBrowserItemID * item ) const
1444 {
1445 return GetDataBrowserTableViewItemID( m_controlRef, row, item );
1446 }
1447
1448 OSStatus wxMacDataBrowserControl::GetItemRow( DataBrowserItemID item, DataBrowserTableViewRowIndex * row ) const
1449 {
1450 return GetDataBrowserTableViewItemRow( m_controlRef, item, row );
1451 }
1452
1453 OSStatus wxMacDataBrowserControl::SetDefaultRowHeight( UInt16 height )
1454 {
1455 return SetDataBrowserTableViewRowHeight( m_controlRef , height );
1456 }
1457
1458 OSStatus wxMacDataBrowserControl::GetDefaultRowHeight( UInt16 * height ) const
1459 {
1460 return GetDataBrowserTableViewRowHeight( m_controlRef, height );
1461 }
1462
1463 OSStatus wxMacDataBrowserControl::SetRowHeight( DataBrowserItemID item , UInt16 height)
1464 {
1465 return SetDataBrowserTableViewItemRowHeight( m_controlRef, item , height );
1466 }
1467
1468 OSStatus wxMacDataBrowserControl::GetRowHeight( DataBrowserItemID item , UInt16 *height) const
1469 {
1470 return GetDataBrowserTableViewItemRowHeight( m_controlRef, item , height);
1471 }
1472
1473 OSStatus wxMacDataBrowserControl::GetColumnWidth( DataBrowserPropertyID column , UInt16 *width ) const
1474 {
1475 return GetDataBrowserTableViewNamedColumnWidth( m_controlRef , column , width );
1476 }
1477
1478 OSStatus wxMacDataBrowserControl::SetColumnWidth( DataBrowserPropertyID column , UInt16 width )
1479 {
1480 return SetDataBrowserTableViewNamedColumnWidth( m_controlRef , column , width );
1481 }
1482
1483 OSStatus wxMacDataBrowserControl::GetDefaultColumnWidth( UInt16 *width ) const
1484 {
1485 return GetDataBrowserTableViewColumnWidth( m_controlRef , width );
1486 }
1487
1488 OSStatus wxMacDataBrowserControl::SetDefaultColumnWidth( UInt16 width )
1489 {
1490 return SetDataBrowserTableViewColumnWidth( m_controlRef , width );
1491 }
1492
1493 OSStatus wxMacDataBrowserControl::GetColumnCount(UInt32* numColumns) const
1494 {
1495 return GetDataBrowserTableViewColumnCount( m_controlRef, numColumns);
1496 }
1497
1498 OSStatus wxMacDataBrowserControl::GetColumnPosition( DataBrowserPropertyID column,
1499 DataBrowserTableViewColumnIndex *position) const
1500 {
1501 return GetDataBrowserTableViewColumnPosition( m_controlRef , column , position);
1502 }
1503
1504 OSStatus wxMacDataBrowserControl::SetColumnPosition( DataBrowserPropertyID column, DataBrowserTableViewColumnIndex position)
1505 {
1506 return SetDataBrowserTableViewColumnPosition( m_controlRef , column , position);
1507 }
1508
1509 OSStatus wxMacDataBrowserControl::GetScrollPosition( UInt32 *top , UInt32 *left ) const
1510 {
1511 return GetDataBrowserScrollPosition( m_controlRef , top , left );
1512 }
1513
1514 OSStatus wxMacDataBrowserControl::SetScrollPosition( UInt32 top , UInt32 left )
1515 {
1516 return SetDataBrowserScrollPosition( m_controlRef , top , left );
1517 }
1518
1519 OSStatus wxMacDataBrowserControl::GetSortProperty( DataBrowserPropertyID *column ) const
1520 {
1521 return GetDataBrowserSortProperty( m_controlRef , column );
1522 }
1523
1524 OSStatus wxMacDataBrowserControl::SetSortProperty( DataBrowserPropertyID column )
1525 {
1526 return SetDataBrowserSortProperty( m_controlRef , column );
1527 }
1528
1529 OSStatus wxMacDataBrowserControl::GetSortOrder( DataBrowserSortOrder *order ) const
1530 {
1531 return GetDataBrowserSortOrder( m_controlRef , order );
1532 }
1533
1534 OSStatus wxMacDataBrowserControl::SetSortOrder( DataBrowserSortOrder order )
1535 {
1536 return SetDataBrowserSortOrder( m_controlRef , order );
1537 }
1538
1539 OSStatus wxMacDataBrowserControl::GetPropertyFlags( DataBrowserPropertyID property,
1540 DataBrowserPropertyFlags *flags ) const
1541 {
1542 return GetDataBrowserPropertyFlags( m_controlRef , property , flags );
1543 }
1544
1545 OSStatus wxMacDataBrowserControl::SetPropertyFlags( DataBrowserPropertyID property,
1546 DataBrowserPropertyFlags flags )
1547 {
1548 return SetDataBrowserPropertyFlags( m_controlRef , property , flags );
1549 }
1550
1551 OSStatus wxMacDataBrowserControl::GetHeaderDesc( DataBrowserPropertyID property,
1552 DataBrowserListViewHeaderDesc *desc ) const
1553 {
1554 return GetDataBrowserListViewHeaderDesc( m_controlRef , property , desc );
1555 }
1556
1557 OSStatus wxMacDataBrowserControl::SetHeaderDesc( DataBrowserPropertyID property,
1558 DataBrowserListViewHeaderDesc *desc )
1559 {
1560 return SetDataBrowserListViewHeaderDesc( m_controlRef , property , desc );
1561 }
1562
1563 OSStatus wxMacDataBrowserControl::SetDisclosureColumn( DataBrowserPropertyID property ,
1564 Boolean expandableRows )
1565 {
1566 return SetDataBrowserListViewDisclosureColumn( m_controlRef, property, expandableRows);
1567 }
1568
1569 // ============================================================================
1570 // Higher-level Databrowser
1571 // ============================================================================
1572 //
1573 // basing on data item objects
1574 //
1575
1576 wxMacDataItem::wxMacDataItem()
1577 {
1578 m_data = NULL;
1579
1580 m_order = 0;
1581 m_colId = kTextColumnId; // for compat with existing wx*ListBox impls.
1582 }
1583
1584 wxMacDataItem::~wxMacDataItem()
1585 {
1586 }
1587
1588 void wxMacDataItem::SetOrder( SInt32 order )
1589 {
1590 m_order = order;
1591 }
1592
1593 SInt32 wxMacDataItem::GetOrder() const
1594 {
1595 return m_order;
1596 }
1597
1598 void wxMacDataItem::SetData( void* data)
1599 {
1600 m_data = data;
1601 }
1602
1603 void* wxMacDataItem::GetData() const
1604 {
1605 return m_data;
1606 }
1607
1608 short wxMacDataItem::GetColumn()
1609 {
1610 return m_colId;
1611 }
1612
1613 void wxMacDataItem::SetColumn( short col )
1614 {
1615 m_colId = col;
1616 }
1617
1618 void wxMacDataItem::SetLabel( const wxString& str)
1619 {
1620 m_label = str;
1621 m_cfLabel.Assign( str , wxLocale::GetSystemEncoding());
1622 }
1623
1624 const wxString& wxMacDataItem::GetLabel() const
1625 {
1626 return m_label;
1627 }
1628
1629 bool wxMacDataItem::IsLessThan(wxMacDataItemBrowserControl *owner ,
1630 const wxMacDataItem* rhs,
1631 DataBrowserPropertyID sortProperty) const
1632 {
1633 const wxMacDataItem* otherItem = wx_const_cast(wxMacDataItem*,rhs);
1634 bool retval = false;
1635
1636 if ( sortProperty == m_colId ){
1637 retval = m_label.CmpNoCase( otherItem->m_label) < 0;
1638 }
1639
1640 else if ( sortProperty == kNumericOrderColumnId )
1641 retval = m_order < otherItem->m_order;
1642
1643 return retval;
1644 }
1645
1646 OSStatus wxMacDataItem::GetSetData( wxMacDataItemBrowserControl *owner ,
1647 DataBrowserPropertyID property,
1648 DataBrowserItemDataRef itemData,
1649 bool changeValue )
1650 {
1651 OSStatus err = errDataBrowserPropertyNotSupported;
1652 if ( !changeValue )
1653 {
1654 if ( property == m_colId ){
1655 err = ::SetDataBrowserItemDataText( itemData, m_cfLabel );
1656 err = noErr;
1657 }
1658 else if ( property == kNumericOrderColumnId ){
1659 err = ::SetDataBrowserItemDataValue( itemData, m_order );
1660 err = noErr;
1661 }
1662 else{
1663 }
1664 }
1665 else
1666 {
1667 switch (property)
1668 {
1669 // no editable props here
1670 default:
1671 break;
1672 }
1673 }
1674
1675 return err;
1676 }
1677
1678 void wxMacDataItem::Notification(wxMacDataItemBrowserControl *owner ,
1679 DataBrowserItemNotification message,
1680 DataBrowserItemDataRef itemData ) const
1681 {
1682 }
1683
1684 IMPLEMENT_DYNAMIC_CLASS( wxMacDataItemBrowserControl , wxMacDataBrowserControl )
1685
1686 wxMacDataItemBrowserControl::wxMacDataItemBrowserControl( wxWindow* peer , const wxPoint& pos, const wxSize& size, long style) :
1687 wxMacDataBrowserControl( peer, pos, size, style )
1688 {
1689 m_suppressSelection = false;
1690 m_sortOrder = SortOrder_None;
1691 m_clientDataItemsType = wxClientData_None;
1692 }
1693
1694 wxMacDataItem* wxMacDataItemBrowserControl::CreateItem()
1695 {
1696 return new wxMacDataItem();
1697 }
1698
1699 wxMacDataItemBrowserSelectionSuppressor::wxMacDataItemBrowserSelectionSuppressor(wxMacDataItemBrowserControl *browser)
1700 {
1701 m_former = browser->SuppressSelection(true);
1702 m_browser = browser;
1703 }
1704
1705 wxMacDataItemBrowserSelectionSuppressor::~wxMacDataItemBrowserSelectionSuppressor()
1706 {
1707 m_browser->SuppressSelection(m_former);
1708 }
1709
1710 bool wxMacDataItemBrowserControl::SuppressSelection( bool suppress )
1711 {
1712 bool former = m_suppressSelection;
1713 m_suppressSelection = suppress;
1714
1715 return former;
1716 }
1717
1718 Boolean wxMacDataItemBrowserControl::CompareItems(DataBrowserItemID itemOneID,
1719 DataBrowserItemID itemTwoID,
1720 DataBrowserPropertyID sortProperty)
1721 {
1722 wxMacDataItem* itemOne = (wxMacDataItem*) itemOneID;
1723 wxMacDataItem* itemTwo = (wxMacDataItem*) itemTwoID;
1724 return CompareItems( itemOne , itemTwo , sortProperty );
1725 }
1726
1727 Boolean wxMacDataItemBrowserControl::CompareItems(const wxMacDataItem* itemOne,
1728 const wxMacDataItem* itemTwo,
1729 DataBrowserPropertyID sortProperty)
1730 {
1731 Boolean retval = false;
1732 if ( itemOne != NULL )
1733 retval = itemOne->IsLessThan( this , itemTwo , sortProperty);
1734 return retval;
1735 }
1736
1737 OSStatus wxMacDataItemBrowserControl::GetSetItemData(
1738 DataBrowserItemID itemID,
1739 DataBrowserPropertyID property,
1740 DataBrowserItemDataRef itemData,
1741 Boolean changeValue )
1742 {
1743 wxMacDataItem* item = (wxMacDataItem*) itemID;
1744 return GetSetItemData(item, property, itemData , changeValue );
1745 }
1746
1747 OSStatus wxMacDataItemBrowserControl::GetSetItemData(
1748 wxMacDataItem* item,
1749 DataBrowserPropertyID property,
1750 DataBrowserItemDataRef itemData,
1751 Boolean changeValue )
1752 {
1753 OSStatus err = errDataBrowserPropertyNotSupported;
1754 switch( property )
1755 {
1756 case kDataBrowserContainerIsClosableProperty :
1757 case kDataBrowserContainerIsSortableProperty :
1758 case kDataBrowserContainerIsOpenableProperty :
1759 // right now default behaviour on these
1760 break;
1761 default :
1762
1763 if ( item != NULL ){
1764 err = item->GetSetData( this, property , itemData , changeValue );
1765 }
1766 break;
1767
1768 }
1769 return err;
1770 }
1771
1772 void wxMacDataItemBrowserControl::ItemNotification(
1773 DataBrowserItemID itemID,
1774 DataBrowserItemNotification message,
1775 DataBrowserItemDataRef itemData)
1776 {
1777 wxMacDataItem* item = (wxMacDataItem*) itemID;
1778 ItemNotification( item , message, itemData);
1779 }
1780
1781 void wxMacDataItemBrowserControl::ItemNotification(
1782 const wxMacDataItem* item,
1783 DataBrowserItemNotification message,
1784 DataBrowserItemDataRef itemData)
1785 {
1786 if (item != NULL)
1787 item->Notification( this, message, itemData);
1788 }
1789
1790 unsigned int wxMacDataItemBrowserControl::GetItemCount(const wxMacDataItem* container,
1791 bool recurse , DataBrowserItemState state) const
1792 {
1793 ItemCount numItems = 0;
1794 verify_noerr( wxMacDataBrowserControl::GetItemCount( (DataBrowserItemID)container,
1795 recurse, state, &numItems ) );
1796 return numItems;
1797 }
1798
1799 unsigned int wxMacDataItemBrowserControl::GetSelectedItemCount( const wxMacDataItem* container,
1800 bool recurse ) const
1801 {
1802 return GetItemCount( container, recurse, kDataBrowserItemIsSelected );
1803
1804 }
1805
1806 void wxMacDataItemBrowserControl::GetItems(const wxMacDataItem* container,
1807 bool recurse , DataBrowserItemState state, wxArrayMacDataItemPtr &items) const
1808 {
1809 Handle handle = NewHandle(0);
1810 verify_noerr( wxMacDataBrowserControl::GetItems( (DataBrowserItemID)container ,
1811 recurse , state, handle) );
1812
1813 int itemCount = GetHandleSize(handle)/sizeof(DataBrowserItemID);
1814 HLock( handle );
1815 wxMacDataItemPtr* itemsArray = (wxMacDataItemPtr*) *handle;
1816 for ( int i = 0; i < itemCount; ++i)
1817 {
1818 items.Add(itemsArray[i]);
1819 }
1820 HUnlock( handle );
1821 DisposeHandle( handle );
1822 }
1823
1824 unsigned int wxMacDataItemBrowserControl::GetLineFromItem(const wxMacDataItem* item) const
1825 {
1826 DataBrowserTableViewRowIndex row;
1827 OSStatus err = GetItemRow( (DataBrowserItemID) item , &row);
1828 wxASSERT( err == noErr);
1829 return row;
1830 }
1831
1832 wxMacDataItem* wxMacDataItemBrowserControl::GetItemFromLine(unsigned int n) const
1833 {
1834 DataBrowserItemID id;
1835 OSStatus err = GetItemID( (DataBrowserTableViewRowIndex) n , &id);
1836 wxASSERT( err == noErr);
1837 return (wxMacDataItem*) id;
1838 }
1839
1840 void wxMacDataItemBrowserControl::UpdateItem(const wxMacDataItem *container,
1841 const wxMacDataItem *item , DataBrowserPropertyID property) const
1842 {
1843 verify_noerr( wxMacDataBrowserControl::UpdateItems((DataBrowserItemID)container, 1,
1844 (DataBrowserItemID*) &item, kDataBrowserItemNoProperty /* notSorted */, property ) );
1845 }
1846
1847 void wxMacDataItemBrowserControl::UpdateItems(const wxMacDataItem *container,
1848 wxArrayMacDataItemPtr &itemArray , DataBrowserPropertyID property) const
1849 {
1850 unsigned int noItems = itemArray.GetCount();
1851 DataBrowserItemID *items = new DataBrowserItemID[noItems];
1852 for ( unsigned int i = 0; i < noItems; ++i )
1853 items[i] = (DataBrowserItemID) itemArray[i];
1854
1855 verify_noerr( wxMacDataBrowserControl::UpdateItems((DataBrowserItemID)container, noItems,
1856 items, kDataBrowserItemNoProperty /* notSorted */, property ) );
1857 delete [] items;
1858 }
1859
1860 void wxMacDataItemBrowserControl::InsertColumn(int colId, DataBrowserPropertyType colType,
1861 const wxString& title, SInt16 just, int defaultWidth)
1862 {
1863 DataBrowserListViewColumnDesc columnDesc;
1864 columnDesc.headerBtnDesc.titleOffset = 0;
1865 columnDesc.headerBtnDesc.version = kDataBrowserListViewLatestHeaderDesc;
1866
1867 columnDesc.headerBtnDesc.btnFontStyle.flags =
1868 kControlUseFontMask | kControlUseJustMask;
1869
1870 columnDesc.headerBtnDesc.btnContentInfo.contentType = kControlContentTextOnly;
1871 columnDesc.headerBtnDesc.btnFontStyle.just = just;
1872 columnDesc.headerBtnDesc.btnFontStyle.font = kControlFontViewSystemFont;
1873 columnDesc.headerBtnDesc.btnFontStyle.style = normal;
1874
1875 // TODO: Why is m_font not defined when we enter wxLC_LIST mode, but is
1876 // defined for other modes?
1877 wxFontEncoding enc;
1878 if ( m_font.Ok() )
1879 enc = m_font.GetEncoding();
1880 else
1881 enc = wxLocale::GetSystemEncoding();
1882 wxMacCFStringHolder cfTitle;
1883 cfTitle.Assign( title, enc );
1884 columnDesc.headerBtnDesc.titleString = cfTitle;
1885
1886 columnDesc.headerBtnDesc.minimumWidth = 0;
1887 columnDesc.headerBtnDesc.maximumWidth = 30000;
1888
1889 columnDesc.propertyDesc.propertyID = (kMinColumnId + colId);
1890 columnDesc.propertyDesc.propertyType = colType;
1891 columnDesc.propertyDesc.propertyFlags = kDataBrowserListViewSortableColumn;
1892 #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
1893 columnDesc.propertyDesc.propertyFlags |= kDataBrowserListViewTypeSelectColumn;
1894 #endif
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 RevealItem( GetItemFromLine( n) , kDataBrowserRevealWithoutSelecting );
2181 }
2182
2183
2184
2185 //
2186 // Tab Control
2187 //
2188
2189 OSStatus wxMacControl::SetTabEnabled( SInt16 tabNo , bool enable )
2190 {
2191 return ::SetTabEnabled( m_controlRef , tabNo , enable );
2192 }
2193
2194 //
2195 // Quartz Support
2196 //
2197
2198 #ifdef __WXMAC_OSX__
2199 // snippets from Sketch Sample from Apple :
2200
2201 #define kGenericRGBProfilePathStr "/System/Library/ColorSync/Profiles/Generic RGB Profile.icc"
2202
2203 /*
2204 This function locates, opens, and returns the profile reference for the calibrated
2205 Generic RGB color space. It is up to the caller to call CMCloseProfile when done
2206 with the profile reference this function returns.
2207 */
2208 CMProfileRef wxMacOpenGenericProfile()
2209 {
2210 static CMProfileRef cachedRGBProfileRef = NULL;
2211
2212 // we only create the profile reference once
2213 if (cachedRGBProfileRef == NULL)
2214 {
2215 CMProfileLocation loc;
2216
2217 loc.locType = cmPathBasedProfile;
2218 strcpy(loc.u.pathLoc.path, kGenericRGBProfilePathStr);
2219
2220 verify_noerr( CMOpenProfile(&cachedRGBProfileRef, &loc) );
2221 }
2222
2223 // clone the profile reference so that the caller has their own reference, not our cached one
2224 if (cachedRGBProfileRef)
2225 CMCloneProfileRef(cachedRGBProfileRef);
2226
2227 return cachedRGBProfileRef;
2228 }
2229
2230 /*
2231 Return the generic RGB color space. This is a 'get' function and the caller should
2232 not release the returned value unless the caller retains it first. Usually callers
2233 of this routine will immediately use the returned colorspace with CoreGraphics
2234 so they typically do not need to retain it themselves.
2235
2236 This function creates the generic RGB color space once and hangs onto it so it can
2237 return it whenever this function is called.
2238 */
2239
2240 CGColorSpaceRef wxMacGetGenericRGBColorSpace()
2241 {
2242 static wxMacCFRefHolder<CGColorSpaceRef> genericRGBColorSpace;
2243
2244 if (genericRGBColorSpace == NULL)
2245 {
2246 if ( UMAGetSystemVersion() >= 0x1040 )
2247 {
2248 genericRGBColorSpace.Set( CGColorSpaceCreateWithName( CFSTR("kCGColorSpaceGenericRGB") ) );
2249 }
2250 else
2251 {
2252 CMProfileRef genericRGBProfile = wxMacOpenGenericProfile();
2253
2254 if (genericRGBProfile)
2255 {
2256 genericRGBColorSpace.Set( CGColorSpaceCreateWithPlatformColorSpace(genericRGBProfile) );
2257
2258 wxASSERT_MSG( genericRGBColorSpace != NULL, wxT("couldn't create the generic RGB color space") );
2259
2260 // we opened the profile so it is up to us to close it
2261 CMCloseProfile(genericRGBProfile);
2262 }
2263 }
2264 }
2265
2266 return genericRGBColorSpace;
2267 }
2268 #endif
2269
2270 #ifndef __LP64__
2271
2272 wxMacPortSaver::wxMacPortSaver( GrafPtr port )
2273 {
2274 ::GetPort( &m_port );
2275 ::SetPort( port );
2276 }
2277
2278 wxMacPortSaver::~wxMacPortSaver()
2279 {
2280 ::SetPort( m_port );
2281 }
2282 #endif
2283
2284 void wxMacGlobalToLocal( WindowRef window , Point*pt )
2285 {
2286 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4
2287 HIPoint p = CGPointMake( pt->h, pt->v );
2288 HIViewRef contentView ;
2289 // TODO check toolbar offset
2290 HIViewFindByID( HIViewGetRoot( window ), kHIViewWindowContentID , &contentView) ;
2291 HIPointConvert( &p, kHICoordSpace72DPIGlobal, NULL, kHICoordSpaceView, contentView );
2292 pt->h = p.x;
2293 pt->v = p.y;
2294 #else
2295 QDGlobalToLocalPoint( GetWindowPort(window), pt ) ;
2296 #endif
2297 }
2298
2299 void wxMacLocalToGlobal( WindowRef window , Point*pt )
2300 {
2301 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4
2302 HIPoint p = CGPointMake( pt->h, pt->v );
2303 HIViewRef contentView ;
2304 // TODO check toolbar offset
2305 HIViewFindByID( HIViewGetRoot( window ), kHIViewWindowContentID , &contentView) ;
2306 HIPointConvert( &p, kHICoordSpaceView, contentView, kHICoordSpace72DPIGlobal, NULL );
2307 pt->h = p.x;
2308 pt->v = p.y;
2309 #else
2310 QDLocalToGlobalPoint( GetWindowPort(window), pt ) ;
2311 #endif
2312 }
2313
2314 #endif // wxUSE_GUI