]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/utils.cpp
202080f5df925d5e476927b654fb513d45b746f1
[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 #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 WXUNUSED(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,
1290 const wxPoint& pos,
1291 const wxSize& size,
1292 long WXUNUSED(style))
1293 : wxMacControl( peer )
1294 {
1295 Rect bounds = wxMacGetBoundsForControl( peer, pos, size );
1296 OSStatus err = ::CreateDataBrowserControl(
1297 MAC_WXHWND(peer->MacGetTopLevelWindowRef()),
1298 &bounds, kDataBrowserListView, &m_controlRef );
1299 SetReferenceInNativeControl();
1300 verify_noerr( err );
1301 if ( gDataBrowserItemCompareUPP == NULL )
1302 gDataBrowserItemCompareUPP = NewDataBrowserItemCompareUPP(DataBrowserCompareProc);
1303 if ( gDataBrowserItemDataUPP == NULL )
1304 gDataBrowserItemDataUPP = NewDataBrowserItemDataUPP(DataBrowserGetSetItemDataProc);
1305 if ( gDataBrowserItemNotificationUPP == NULL )
1306 {
1307 gDataBrowserItemNotificationUPP =
1308 #if TARGET_API_MAC_OSX
1309 (DataBrowserItemNotificationUPP) NewDataBrowserItemNotificationWithItemUPP(DataBrowserItemNotificationProc);
1310 #else
1311 NewDataBrowserItemNotificationUPP(DataBrowserItemNotificationProc);
1312 #endif
1313 }
1314
1315 DataBrowserCallbacks callbacks;
1316 InitializeDataBrowserCallbacks( &callbacks, kDataBrowserLatestCallbacks );
1317
1318 callbacks.u.v1.itemDataCallback = gDataBrowserItemDataUPP;
1319 callbacks.u.v1.itemCompareCallback = gDataBrowserItemCompareUPP;
1320 callbacks.u.v1.itemNotificationCallback = gDataBrowserItemNotificationUPP;
1321 SetCallbacks( &callbacks );
1322
1323 }
1324
1325 OSStatus wxMacDataBrowserControl::GetItemCount( DataBrowserItemID container,
1326 Boolean recurse,
1327 DataBrowserItemState state,
1328 ItemCount *numItems) const
1329 {
1330 return GetDataBrowserItemCount( m_controlRef, container, recurse, state, numItems );
1331 }
1332
1333 OSStatus wxMacDataBrowserControl::GetItems( DataBrowserItemID container,
1334 Boolean recurse,
1335 DataBrowserItemState state,
1336 Handle items) const
1337 {
1338 return GetDataBrowserItems( m_controlRef, container, recurse, state, items );
1339 }
1340
1341 OSStatus wxMacDataBrowserControl::SetSelectionFlags( DataBrowserSelectionFlags options )
1342 {
1343 return SetDataBrowserSelectionFlags( m_controlRef, options );
1344 }
1345
1346 OSStatus wxMacDataBrowserControl::AddColumn( DataBrowserListViewColumnDesc *columnDesc,
1347 DataBrowserTableViewColumnIndex position )
1348 {
1349 return AddDataBrowserListViewColumn( m_controlRef, columnDesc, position );
1350 }
1351
1352 OSStatus wxMacDataBrowserControl::GetColumnIDFromIndex( DataBrowserTableViewColumnIndex position, DataBrowserTableViewColumnID* id ){
1353 return GetDataBrowserTableViewColumnProperty( m_controlRef, position, id );
1354 }
1355
1356 OSStatus wxMacDataBrowserControl::RemoveColumn( DataBrowserTableViewColumnIndex position )
1357 {
1358 DataBrowserTableViewColumnID id;
1359 GetColumnIDFromIndex( position, &id );
1360 return RemoveDataBrowserTableViewColumn( m_controlRef, id );
1361 }
1362
1363 OSStatus wxMacDataBrowserControl::AutoSizeColumns()
1364 {
1365 return AutoSizeDataBrowserListViewColumns(m_controlRef);
1366 }
1367
1368 OSStatus wxMacDataBrowserControl::SetHasScrollBars( bool horiz, bool vert )
1369 {
1370 return SetDataBrowserHasScrollBars( m_controlRef, horiz, vert );
1371 }
1372
1373 OSStatus wxMacDataBrowserControl::SetHiliteStyle( DataBrowserTableViewHiliteStyle hiliteStyle )
1374 {
1375 return SetDataBrowserTableViewHiliteStyle( m_controlRef, hiliteStyle );
1376 }
1377
1378 OSStatus wxMacDataBrowserControl::SetHeaderButtonHeight(UInt16 height)
1379 {
1380 return SetDataBrowserListViewHeaderBtnHeight( m_controlRef, height );
1381 }
1382
1383 OSStatus wxMacDataBrowserControl::GetHeaderButtonHeight(UInt16 *height)
1384 {
1385 return GetDataBrowserListViewHeaderBtnHeight( m_controlRef, height );
1386 }
1387
1388 OSStatus wxMacDataBrowserControl::SetCallbacks(const DataBrowserCallbacks *callbacks)
1389 {
1390 return SetDataBrowserCallbacks( m_controlRef, callbacks );
1391 }
1392
1393 OSStatus wxMacDataBrowserControl::UpdateItems(
1394 DataBrowserItemID container,
1395 UInt32 numItems,
1396 const DataBrowserItemID *items,
1397 DataBrowserPropertyID preSortProperty,
1398 DataBrowserPropertyID propertyID ) const
1399 {
1400 return UpdateDataBrowserItems( m_controlRef, container, numItems, items, preSortProperty, propertyID );
1401 }
1402
1403 bool wxMacDataBrowserControl::IsItemSelected( DataBrowserItemID item ) const
1404 {
1405 return IsDataBrowserItemSelected( m_controlRef, item );
1406 }
1407
1408 OSStatus wxMacDataBrowserControl::AddItems(
1409 DataBrowserItemID container,
1410 UInt32 numItems,
1411 const DataBrowserItemID *items,
1412 DataBrowserPropertyID preSortProperty )
1413 {
1414 return AddDataBrowserItems( m_controlRef, container, numItems, items, preSortProperty );
1415 }
1416
1417 OSStatus wxMacDataBrowserControl::RemoveItems(
1418 DataBrowserItemID container,
1419 UInt32 numItems,
1420 const DataBrowserItemID *items,
1421 DataBrowserPropertyID preSortProperty )
1422 {
1423 return RemoveDataBrowserItems( m_controlRef, container, numItems, items, preSortProperty );
1424 }
1425
1426 OSStatus wxMacDataBrowserControl::RevealItem(
1427 DataBrowserItemID item,
1428 DataBrowserPropertyID propertyID,
1429 DataBrowserRevealOptions options ) const
1430 {
1431 return RevealDataBrowserItem( m_controlRef, item, propertyID, options );
1432 }
1433
1434 OSStatus wxMacDataBrowserControl::SetSelectedItems(
1435 UInt32 numItems,
1436 const DataBrowserItemID *items,
1437 DataBrowserSetOption operation )
1438 {
1439 return SetDataBrowserSelectedItems( m_controlRef, numItems, items, operation );
1440 }
1441
1442 OSStatus wxMacDataBrowserControl::GetSelectionAnchor( DataBrowserItemID *first, DataBrowserItemID *last ) const
1443 {
1444 return GetDataBrowserSelectionAnchor( m_controlRef, first, last );
1445 }
1446
1447 OSStatus wxMacDataBrowserControl::GetItemID( DataBrowserTableViewRowIndex row, DataBrowserItemID * item ) const
1448 {
1449 return GetDataBrowserTableViewItemID( m_controlRef, row, item );
1450 }
1451
1452 OSStatus wxMacDataBrowserControl::GetItemRow( DataBrowserItemID item, DataBrowserTableViewRowIndex * row ) const
1453 {
1454 return GetDataBrowserTableViewItemRow( m_controlRef, item, row );
1455 }
1456
1457 OSStatus wxMacDataBrowserControl::SetDefaultRowHeight( UInt16 height )
1458 {
1459 return SetDataBrowserTableViewRowHeight( m_controlRef , height );
1460 }
1461
1462 OSStatus wxMacDataBrowserControl::GetDefaultRowHeight( UInt16 * height ) const
1463 {
1464 return GetDataBrowserTableViewRowHeight( m_controlRef, height );
1465 }
1466
1467 OSStatus wxMacDataBrowserControl::SetRowHeight( DataBrowserItemID item , UInt16 height)
1468 {
1469 return SetDataBrowserTableViewItemRowHeight( m_controlRef, item , height );
1470 }
1471
1472 OSStatus wxMacDataBrowserControl::GetRowHeight( DataBrowserItemID item , UInt16 *height) const
1473 {
1474 return GetDataBrowserTableViewItemRowHeight( m_controlRef, item , height);
1475 }
1476
1477 OSStatus wxMacDataBrowserControl::GetColumnWidth( DataBrowserPropertyID column , UInt16 *width ) const
1478 {
1479 return GetDataBrowserTableViewNamedColumnWidth( m_controlRef , column , width );
1480 }
1481
1482 OSStatus wxMacDataBrowserControl::SetColumnWidth( DataBrowserPropertyID column , UInt16 width )
1483 {
1484 return SetDataBrowserTableViewNamedColumnWidth( m_controlRef , column , width );
1485 }
1486
1487 OSStatus wxMacDataBrowserControl::GetDefaultColumnWidth( UInt16 *width ) const
1488 {
1489 return GetDataBrowserTableViewColumnWidth( m_controlRef , width );
1490 }
1491
1492 OSStatus wxMacDataBrowserControl::SetDefaultColumnWidth( UInt16 width )
1493 {
1494 return SetDataBrowserTableViewColumnWidth( m_controlRef , width );
1495 }
1496
1497 OSStatus wxMacDataBrowserControl::GetColumnCount(UInt32* numColumns) const
1498 {
1499 return GetDataBrowserTableViewColumnCount( m_controlRef, numColumns);
1500 }
1501
1502 OSStatus wxMacDataBrowserControl::GetColumnPosition( DataBrowserPropertyID column,
1503 DataBrowserTableViewColumnIndex *position) const
1504 {
1505 return GetDataBrowserTableViewColumnPosition( m_controlRef , column , position);
1506 }
1507
1508 OSStatus wxMacDataBrowserControl::SetColumnPosition( DataBrowserPropertyID column, DataBrowserTableViewColumnIndex position)
1509 {
1510 return SetDataBrowserTableViewColumnPosition( m_controlRef , column , position);
1511 }
1512
1513 OSStatus wxMacDataBrowserControl::GetScrollPosition( UInt32 *top , UInt32 *left ) const
1514 {
1515 return GetDataBrowserScrollPosition( m_controlRef , top , left );
1516 }
1517
1518 OSStatus wxMacDataBrowserControl::SetScrollPosition( UInt32 top , UInt32 left )
1519 {
1520 return SetDataBrowserScrollPosition( m_controlRef , top , left );
1521 }
1522
1523 OSStatus wxMacDataBrowserControl::GetSortProperty( DataBrowserPropertyID *column ) const
1524 {
1525 return GetDataBrowserSortProperty( m_controlRef , column );
1526 }
1527
1528 OSStatus wxMacDataBrowserControl::SetSortProperty( DataBrowserPropertyID column )
1529 {
1530 return SetDataBrowserSortProperty( m_controlRef , column );
1531 }
1532
1533 OSStatus wxMacDataBrowserControl::GetSortOrder( DataBrowserSortOrder *order ) const
1534 {
1535 return GetDataBrowserSortOrder( m_controlRef , order );
1536 }
1537
1538 OSStatus wxMacDataBrowserControl::SetSortOrder( DataBrowserSortOrder order )
1539 {
1540 return SetDataBrowserSortOrder( m_controlRef , order );
1541 }
1542
1543 OSStatus wxMacDataBrowserControl::GetPropertyFlags( DataBrowserPropertyID property,
1544 DataBrowserPropertyFlags *flags ) const
1545 {
1546 return GetDataBrowserPropertyFlags( m_controlRef , property , flags );
1547 }
1548
1549 OSStatus wxMacDataBrowserControl::SetPropertyFlags( DataBrowserPropertyID property,
1550 DataBrowserPropertyFlags flags )
1551 {
1552 return SetDataBrowserPropertyFlags( m_controlRef , property , flags );
1553 }
1554
1555 OSStatus wxMacDataBrowserControl::GetHeaderDesc( DataBrowserPropertyID property,
1556 DataBrowserListViewHeaderDesc *desc ) const
1557 {
1558 return GetDataBrowserListViewHeaderDesc( m_controlRef , property , desc );
1559 }
1560
1561 OSStatus wxMacDataBrowserControl::SetHeaderDesc( DataBrowserPropertyID property,
1562 DataBrowserListViewHeaderDesc *desc )
1563 {
1564 return SetDataBrowserListViewHeaderDesc( m_controlRef , property , desc );
1565 }
1566
1567 OSStatus wxMacDataBrowserControl::SetDisclosureColumn( DataBrowserPropertyID property ,
1568 Boolean expandableRows )
1569 {
1570 return SetDataBrowserListViewDisclosureColumn( m_controlRef, property, expandableRows);
1571 }
1572
1573 // ============================================================================
1574 // Higher-level Databrowser
1575 // ============================================================================
1576 //
1577 // basing on data item objects
1578 //
1579
1580 wxMacDataItem::wxMacDataItem()
1581 {
1582 m_data = NULL;
1583
1584 m_order = 0;
1585 m_colId = kTextColumnId; // for compat with existing wx*ListBox impls.
1586 }
1587
1588 wxMacDataItem::~wxMacDataItem()
1589 {
1590 }
1591
1592 void wxMacDataItem::SetOrder( SInt32 order )
1593 {
1594 m_order = order;
1595 }
1596
1597 SInt32 wxMacDataItem::GetOrder() const
1598 {
1599 return m_order;
1600 }
1601
1602 void wxMacDataItem::SetData( void* data)
1603 {
1604 m_data = data;
1605 }
1606
1607 void* wxMacDataItem::GetData() const
1608 {
1609 return m_data;
1610 }
1611
1612 short wxMacDataItem::GetColumn()
1613 {
1614 return m_colId;
1615 }
1616
1617 void wxMacDataItem::SetColumn( short col )
1618 {
1619 m_colId = col;
1620 }
1621
1622 void wxMacDataItem::SetLabel( const wxString& str)
1623 {
1624 m_label = str;
1625 m_cfLabel.Assign( str , wxLocale::GetSystemEncoding());
1626 }
1627
1628 const wxString& wxMacDataItem::GetLabel() const
1629 {
1630 return m_label;
1631 }
1632
1633 bool wxMacDataItem::IsLessThan(wxMacDataItemBrowserControl *WXUNUSED(owner) ,
1634 const wxMacDataItem* rhs,
1635 DataBrowserPropertyID sortProperty) const
1636 {
1637 const wxMacDataItem* otherItem = wx_const_cast(wxMacDataItem*,rhs);
1638 bool retval = false;
1639
1640 if ( sortProperty == m_colId ){
1641 retval = m_label.CmpNoCase( otherItem->m_label) < 0;
1642 }
1643
1644 else if ( sortProperty == kNumericOrderColumnId )
1645 retval = m_order < otherItem->m_order;
1646
1647 return retval;
1648 }
1649
1650 OSStatus wxMacDataItem::GetSetData( wxMacDataItemBrowserControl *WXUNUSED(owner) ,
1651 DataBrowserPropertyID property,
1652 DataBrowserItemDataRef itemData,
1653 bool changeValue )
1654 {
1655 OSStatus err = errDataBrowserPropertyNotSupported;
1656 if ( !changeValue )
1657 {
1658 if ( property == m_colId ){
1659 err = ::SetDataBrowserItemDataText( itemData, m_cfLabel );
1660 err = noErr;
1661 }
1662 else if ( property == kNumericOrderColumnId ){
1663 err = ::SetDataBrowserItemDataValue( itemData, m_order );
1664 err = noErr;
1665 }
1666 else{
1667 }
1668 }
1669 else
1670 {
1671 switch (property)
1672 {
1673 // no editable props here
1674 default:
1675 break;
1676 }
1677 }
1678
1679 return err;
1680 }
1681
1682 void wxMacDataItem::Notification(wxMacDataItemBrowserControl *WXUNUSED(owner) ,
1683 DataBrowserItemNotification WXUNUSED(message),
1684 DataBrowserItemDataRef WXUNUSED(itemData) ) const
1685 {
1686 }
1687
1688 IMPLEMENT_DYNAMIC_CLASS( wxMacDataItemBrowserControl , wxMacDataBrowserControl )
1689
1690 wxMacDataItemBrowserControl::wxMacDataItemBrowserControl( wxWindow* peer , const wxPoint& pos, const wxSize& size, long style) :
1691 wxMacDataBrowserControl( peer, pos, size, style )
1692 {
1693 m_suppressSelection = false;
1694 m_sortOrder = SortOrder_None;
1695 m_clientDataItemsType = wxClientData_None;
1696 }
1697
1698 wxMacDataItem* wxMacDataItemBrowserControl::CreateItem()
1699 {
1700 return new wxMacDataItem();
1701 }
1702
1703 wxMacDataItemBrowserSelectionSuppressor::wxMacDataItemBrowserSelectionSuppressor(wxMacDataItemBrowserControl *browser)
1704 {
1705 m_former = browser->SuppressSelection(true);
1706 m_browser = browser;
1707 }
1708
1709 wxMacDataItemBrowserSelectionSuppressor::~wxMacDataItemBrowserSelectionSuppressor()
1710 {
1711 m_browser->SuppressSelection(m_former);
1712 }
1713
1714 bool wxMacDataItemBrowserControl::SuppressSelection( bool suppress )
1715 {
1716 bool former = m_suppressSelection;
1717 m_suppressSelection = suppress;
1718
1719 return former;
1720 }
1721
1722 Boolean wxMacDataItemBrowserControl::CompareItems(DataBrowserItemID itemOneID,
1723 DataBrowserItemID itemTwoID,
1724 DataBrowserPropertyID sortProperty)
1725 {
1726 wxMacDataItem* itemOne = (wxMacDataItem*) itemOneID;
1727 wxMacDataItem* itemTwo = (wxMacDataItem*) itemTwoID;
1728 return CompareItems( itemOne , itemTwo , sortProperty );
1729 }
1730
1731 Boolean wxMacDataItemBrowserControl::CompareItems(const wxMacDataItem* itemOne,
1732 const wxMacDataItem* itemTwo,
1733 DataBrowserPropertyID sortProperty)
1734 {
1735 Boolean retval = false;
1736 if ( itemOne != NULL )
1737 retval = itemOne->IsLessThan( this , itemTwo , sortProperty);
1738 return retval;
1739 }
1740
1741 OSStatus wxMacDataItemBrowserControl::GetSetItemData(
1742 DataBrowserItemID itemID,
1743 DataBrowserPropertyID property,
1744 DataBrowserItemDataRef itemData,
1745 Boolean changeValue )
1746 {
1747 wxMacDataItem* item = (wxMacDataItem*) itemID;
1748 return GetSetItemData(item, property, itemData , changeValue );
1749 }
1750
1751 OSStatus wxMacDataItemBrowserControl::GetSetItemData(
1752 wxMacDataItem* item,
1753 DataBrowserPropertyID property,
1754 DataBrowserItemDataRef itemData,
1755 Boolean changeValue )
1756 {
1757 OSStatus err = errDataBrowserPropertyNotSupported;
1758 switch( property )
1759 {
1760 case kDataBrowserContainerIsClosableProperty :
1761 case kDataBrowserContainerIsSortableProperty :
1762 case kDataBrowserContainerIsOpenableProperty :
1763 // right now default behaviour on these
1764 break;
1765 default :
1766
1767 if ( item != NULL ){
1768 err = item->GetSetData( this, property , itemData , changeValue );
1769 }
1770 break;
1771
1772 }
1773 return err;
1774 }
1775
1776 void wxMacDataItemBrowserControl::ItemNotification(
1777 DataBrowserItemID itemID,
1778 DataBrowserItemNotification message,
1779 DataBrowserItemDataRef itemData)
1780 {
1781 wxMacDataItem* item = (wxMacDataItem*) itemID;
1782 ItemNotification( item , message, itemData);
1783 }
1784
1785 void wxMacDataItemBrowserControl::ItemNotification(
1786 const wxMacDataItem* item,
1787 DataBrowserItemNotification message,
1788 DataBrowserItemDataRef itemData)
1789 {
1790 if (item != NULL)
1791 item->Notification( this, message, itemData);
1792 }
1793
1794 unsigned int wxMacDataItemBrowserControl::GetItemCount(const wxMacDataItem* container,
1795 bool recurse , DataBrowserItemState state) const
1796 {
1797 ItemCount numItems = 0;
1798 verify_noerr( wxMacDataBrowserControl::GetItemCount( (DataBrowserItemID)container,
1799 recurse, state, &numItems ) );
1800 return numItems;
1801 }
1802
1803 unsigned int wxMacDataItemBrowserControl::GetSelectedItemCount( const wxMacDataItem* container,
1804 bool recurse ) const
1805 {
1806 return GetItemCount( container, recurse, kDataBrowserItemIsSelected );
1807
1808 }
1809
1810 void wxMacDataItemBrowserControl::GetItems(const wxMacDataItem* container,
1811 bool recurse , DataBrowserItemState state, wxArrayMacDataItemPtr &items) const
1812 {
1813 Handle handle = NewHandle(0);
1814 verify_noerr( wxMacDataBrowserControl::GetItems( (DataBrowserItemID)container ,
1815 recurse , state, handle) );
1816
1817 int itemCount = GetHandleSize(handle)/sizeof(DataBrowserItemID);
1818 HLock( handle );
1819 wxMacDataItemPtr* itemsArray = (wxMacDataItemPtr*) *handle;
1820 for ( int i = 0; i < itemCount; ++i)
1821 {
1822 items.Add(itemsArray[i]);
1823 }
1824 HUnlock( handle );
1825 DisposeHandle( handle );
1826 }
1827
1828 unsigned int wxMacDataItemBrowserControl::GetLineFromItem(const wxMacDataItem* item) const
1829 {
1830 DataBrowserTableViewRowIndex row;
1831 OSStatus err = GetItemRow( (DataBrowserItemID) item , &row);
1832 wxASSERT( err == noErr);
1833 return row;
1834 }
1835
1836 wxMacDataItem* wxMacDataItemBrowserControl::GetItemFromLine(unsigned int n) const
1837 {
1838 DataBrowserItemID id;
1839 OSStatus err = GetItemID( (DataBrowserTableViewRowIndex) n , &id);
1840 wxASSERT( err == noErr);
1841 return (wxMacDataItem*) id;
1842 }
1843
1844 void wxMacDataItemBrowserControl::UpdateItem(const wxMacDataItem *container,
1845 const wxMacDataItem *item , DataBrowserPropertyID property) const
1846 {
1847 verify_noerr( wxMacDataBrowserControl::UpdateItems((DataBrowserItemID)container, 1,
1848 (DataBrowserItemID*) &item, kDataBrowserItemNoProperty /* notSorted */, property ) );
1849 }
1850
1851 void wxMacDataItemBrowserControl::UpdateItems(const wxMacDataItem *container,
1852 wxArrayMacDataItemPtr &itemArray , DataBrowserPropertyID property) const
1853 {
1854 unsigned int noItems = itemArray.GetCount();
1855 DataBrowserItemID *items = new DataBrowserItemID[noItems];
1856 for ( unsigned int i = 0; i < noItems; ++i )
1857 items[i] = (DataBrowserItemID) itemArray[i];
1858
1859 verify_noerr( wxMacDataBrowserControl::UpdateItems((DataBrowserItemID)container, noItems,
1860 items, kDataBrowserItemNoProperty /* notSorted */, property ) );
1861 delete [] items;
1862 }
1863
1864 void wxMacDataItemBrowserControl::InsertColumn(int colId, DataBrowserPropertyType colType,
1865 const wxString& title, SInt16 just, int defaultWidth)
1866 {
1867 DataBrowserListViewColumnDesc columnDesc;
1868 columnDesc.headerBtnDesc.titleOffset = 0;
1869 columnDesc.headerBtnDesc.version = kDataBrowserListViewLatestHeaderDesc;
1870
1871 columnDesc.headerBtnDesc.btnFontStyle.flags =
1872 kControlUseFontMask | kControlUseJustMask;
1873
1874 columnDesc.headerBtnDesc.btnContentInfo.contentType = kControlContentTextOnly;
1875 columnDesc.headerBtnDesc.btnFontStyle.just = just;
1876 columnDesc.headerBtnDesc.btnFontStyle.font = kControlFontViewSystemFont;
1877 columnDesc.headerBtnDesc.btnFontStyle.style = normal;
1878
1879 // TODO: Why is m_font not defined when we enter wxLC_LIST mode, but is
1880 // defined for other modes?
1881 wxFontEncoding enc;
1882 if ( m_font.Ok() )
1883 enc = m_font.GetEncoding();
1884 else
1885 enc = wxLocale::GetSystemEncoding();
1886 wxMacCFStringHolder cfTitle;
1887 cfTitle.Assign( title, enc );
1888 columnDesc.headerBtnDesc.titleString = cfTitle;
1889
1890 columnDesc.headerBtnDesc.minimumWidth = 0;
1891 columnDesc.headerBtnDesc.maximumWidth = 30000;
1892
1893 columnDesc.propertyDesc.propertyID = (kMinColumnId + colId);
1894 columnDesc.propertyDesc.propertyType = colType;
1895 columnDesc.propertyDesc.propertyFlags = kDataBrowserListViewSortableColumn;
1896 #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
1897 columnDesc.propertyDesc.propertyFlags |= kDataBrowserListViewTypeSelectColumn;
1898 #endif
1899 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
1900 columnDesc.propertyDesc.propertyFlags |= kDataBrowserListViewNoGapForIconInHeaderButton;
1901 #endif
1902
1903 verify_noerr( AddColumn( &columnDesc, kDataBrowserListViewAppendColumn ) );
1904
1905 if (defaultWidth > 0){
1906 SetColumnWidth(colId, defaultWidth);
1907 }
1908
1909 }
1910
1911 void wxMacDataItemBrowserControl::SetColumnWidth(int colId, int width)
1912 {
1913 DataBrowserPropertyID id;
1914 GetColumnIDFromIndex(colId, &id);
1915 verify_noerr( wxMacDataBrowserControl::SetColumnWidth(id, width));
1916 }
1917
1918 int wxMacDataItemBrowserControl::GetColumnWidth(int colId)
1919 {
1920 DataBrowserPropertyID id;
1921 GetColumnIDFromIndex(colId, &id);
1922 UInt16 result;
1923 verify_noerr( wxMacDataBrowserControl::GetColumnWidth(id, &result));
1924 return result;
1925 }
1926
1927 void wxMacDataItemBrowserControl::AddItem(wxMacDataItem *container, wxMacDataItem *item)
1928 {
1929 verify_noerr( wxMacDataBrowserControl::AddItems( (DataBrowserItemID)container, 1,
1930 (DataBrowserItemID*) &item, kDataBrowserItemNoProperty ) );
1931 }
1932
1933 void wxMacDataItemBrowserControl::AddItems(wxMacDataItem *container, wxArrayMacDataItemPtr &itemArray )
1934 {
1935 unsigned int noItems = itemArray.GetCount();
1936 DataBrowserItemID *items = new DataBrowserItemID[noItems];
1937 for ( unsigned int i = 0; i < noItems; ++i )
1938 items[i] = (DataBrowserItemID) itemArray[i];
1939
1940 verify_noerr( wxMacDataBrowserControl::AddItems( (DataBrowserItemID)container, noItems,
1941 (DataBrowserItemID*) items, kDataBrowserItemNoProperty ) );
1942 delete [] items;
1943 }
1944
1945 void wxMacDataItemBrowserControl::RemoveItem(wxMacDataItem *container, wxMacDataItem* item)
1946 {
1947 OSStatus err = wxMacDataBrowserControl::RemoveItems( (DataBrowserItemID)container, 1,
1948 (DataBrowserItemID*) &item, kDataBrowserItemNoProperty );
1949 verify_noerr( err );
1950 }
1951
1952 void wxMacDataItemBrowserControl::RemoveItems(wxMacDataItem *container, wxArrayMacDataItemPtr &itemArray)
1953 {
1954 unsigned int noItems = itemArray.GetCount();
1955 DataBrowserItemID *items = new DataBrowserItemID[noItems];
1956 for ( unsigned int i = 0; i < noItems; ++i )
1957 items[i] = (DataBrowserItemID) itemArray[i];
1958
1959 OSStatus err = wxMacDataBrowserControl::RemoveItems( (DataBrowserItemID)container, noItems,
1960 (DataBrowserItemID*) items, kDataBrowserItemNoProperty );
1961 verify_noerr( err );
1962 delete [] items;
1963 }
1964
1965 void wxMacDataItemBrowserControl::RemoveAllItems(wxMacDataItem *container)
1966 {
1967 OSStatus err = wxMacDataBrowserControl::RemoveItems( (DataBrowserItemID)container, 0 , NULL , kDataBrowserItemNoProperty );
1968 verify_noerr( err );
1969 }
1970
1971 void wxMacDataItemBrowserControl::SetSelectedItem(wxMacDataItem* item , DataBrowserSetOption option)
1972 {
1973 verify_noerr(wxMacDataBrowserControl::SetSelectedItems( 1, (DataBrowserItemID*) &item, option ));
1974 }
1975
1976 void wxMacDataItemBrowserControl::SetSelectedAllItems(DataBrowserSetOption option)
1977 {
1978 verify_noerr(wxMacDataBrowserControl::SetSelectedItems( 0 , NULL , option ));
1979 }
1980
1981 void wxMacDataItemBrowserControl::SetSelectedItems(wxArrayMacDataItemPtr &itemArray , DataBrowserSetOption option)
1982 {
1983 unsigned int noItems = itemArray.GetCount();
1984 DataBrowserItemID *items = new DataBrowserItemID[noItems];
1985 for ( unsigned int i = 0; i < noItems; ++i )
1986 items[i] = (DataBrowserItemID) itemArray[i];
1987
1988 verify_noerr(wxMacDataBrowserControl::SetSelectedItems( noItems, (DataBrowserItemID*) items, option ));
1989 delete [] items;
1990 }
1991
1992 Boolean wxMacDataItemBrowserControl::IsItemSelected( const wxMacDataItem* item) const
1993 {
1994 return wxMacDataBrowserControl::IsItemSelected( (DataBrowserItemID) item);
1995 }
1996
1997 void wxMacDataItemBrowserControl::RevealItem( wxMacDataItem* item, DataBrowserRevealOptions options)
1998 {
1999 verify_noerr(wxMacDataBrowserControl::RevealItem( (DataBrowserItemID) item, kDataBrowserNoItem , options ) );
2000 }
2001
2002 void wxMacDataItemBrowserControl::GetSelectionAnchor( wxMacDataItemPtr* first , wxMacDataItemPtr* last) const
2003 {
2004 verify_noerr(wxMacDataBrowserControl::GetSelectionAnchor( (DataBrowserItemID*) first, (DataBrowserItemID*) last) );
2005 }
2006
2007 wxClientDataType wxMacDataItemBrowserControl::GetClientDataType() const
2008 {
2009 return m_clientDataItemsType;
2010 }
2011 void wxMacDataItemBrowserControl::SetClientDataType(wxClientDataType clientDataItemsType)
2012 {
2013 m_clientDataItemsType = clientDataItemsType;
2014 }
2015
2016 unsigned int wxMacDataItemBrowserControl::MacGetCount() const
2017 {
2018 return GetItemCount(wxMacDataBrowserRootContainer,false,kDataBrowserItemAnyState);
2019 }
2020
2021 void wxMacDataItemBrowserControl::MacDelete( unsigned int n )
2022 {
2023 wxMacDataItem* item = (wxMacDataItem*)GetItemFromLine( n );
2024 RemoveItem( wxMacDataBrowserRootContainer, item );
2025 }
2026
2027 void wxMacDataItemBrowserControl::MacInsert( unsigned int n,
2028 const wxArrayStringsAdapter& items,
2029 int column )
2030 {
2031 size_t itemsCount = items.GetCount();
2032 if ( itemsCount == 0 )
2033 return;
2034
2035 SInt32 frontLineOrder = 0;
2036
2037 if ( m_sortOrder == SortOrder_None )
2038 {
2039 // increase the order of the lines to be shifted
2040 unsigned int lines = MacGetCount();
2041 for ( unsigned int i = n; i < lines; ++i)
2042 {
2043 wxMacDataItem* iter = (wxMacDataItem*) GetItemFromLine(i);
2044 iter->SetOrder( iter->GetOrder() + itemsCount );
2045 }
2046 if ( n > 0 )
2047 {
2048 wxMacDataItem* iter = (wxMacDataItem*) GetItemFromLine(n-1);
2049 frontLineOrder = iter->GetOrder();
2050 }
2051 }
2052
2053 wxArrayMacDataItemPtr ids;
2054 ids.SetCount( itemsCount );
2055
2056 for ( unsigned int i = 0; i < itemsCount; ++i )
2057 {
2058 wxMacDataItem* item = CreateItem();
2059 item->SetLabel( items[i]);
2060 if ( column != -1 )
2061 item->SetColumn( kMinColumnId + column );
2062
2063 if ( m_sortOrder == SortOrder_None )
2064 item->SetOrder( frontLineOrder + 1 + i );
2065
2066 ids[i] = item;
2067 }
2068
2069 AddItems( wxMacDataBrowserRootContainer, ids );
2070 }
2071
2072 int wxMacDataItemBrowserControl::MacAppend( const wxString& text)
2073 {
2074 wxMacDataItem* item = CreateItem();
2075 item->SetLabel( text );
2076 if ( m_sortOrder == SortOrder_None )
2077 {
2078 unsigned int lines = MacGetCount();
2079 if ( lines == 0 )
2080 item->SetOrder( 1 );
2081 else
2082 {
2083 wxMacDataItem* frontItem = (wxMacDataItem*) GetItemFromLine(lines-1);
2084 item->SetOrder( frontItem->GetOrder() + 1 );
2085 }
2086 }
2087 AddItem( wxMacDataBrowserRootContainer, item );
2088
2089 return GetLineFromItem(item);
2090 }
2091
2092 void wxMacDataItemBrowserControl::MacClear()
2093 {
2094 wxMacDataItemBrowserSelectionSuppressor suppressor(this);
2095 RemoveAllItems(wxMacDataBrowserRootContainer);
2096 }
2097
2098 void wxMacDataItemBrowserControl::MacDeselectAll()
2099 {
2100 wxMacDataItemBrowserSelectionSuppressor suppressor(this);
2101 SetSelectedAllItems( kDataBrowserItemsRemove );
2102 }
2103
2104 void wxMacDataItemBrowserControl::MacSetSelection( unsigned int n, bool select, bool multi )
2105 {
2106 wxMacDataItem* item = (wxMacDataItem*) GetItemFromLine(n);
2107 wxMacDataItemBrowserSelectionSuppressor suppressor(this);
2108
2109 if ( IsItemSelected( item ) != select )
2110 {
2111 if ( select )
2112 SetSelectedItem( item, multi ? kDataBrowserItemsAdd : kDataBrowserItemsAssign );
2113 else
2114 SetSelectedItem( item, kDataBrowserItemsRemove );
2115 }
2116
2117 MacScrollTo( n );
2118 }
2119
2120 bool wxMacDataItemBrowserControl::MacIsSelected( unsigned int n ) const
2121 {
2122 wxMacDataItem* item = (wxMacDataItem*) GetItemFromLine(n);
2123 return IsItemSelected( item );
2124 }
2125
2126 int wxMacDataItemBrowserControl::MacGetSelection() const
2127 {
2128 wxMacDataItemPtr first, last;
2129 GetSelectionAnchor( &first, &last );
2130
2131 if ( first != NULL )
2132 {
2133 return GetLineFromItem( first );
2134 }
2135
2136 return -1;
2137 }
2138
2139 int wxMacDataItemBrowserControl::MacGetSelections( wxArrayInt& aSelections ) const
2140 {
2141 aSelections.Empty();
2142 wxArrayMacDataItemPtr selectedItems;
2143 GetItems( wxMacDataBrowserRootContainer, false , kDataBrowserItemIsSelected, selectedItems);
2144
2145 int count = selectedItems.GetCount();
2146
2147 for ( int i = 0; i < count; ++i)
2148 {
2149 aSelections.Add(GetLineFromItem(selectedItems[i]));
2150 }
2151
2152 return count;
2153 }
2154
2155 void wxMacDataItemBrowserControl::MacSetString( unsigned int n, const wxString& text )
2156 {
2157 // as we don't store the strings we only have to issue a redraw
2158 wxMacDataItem* item = (wxMacDataItem*) GetItemFromLine( n);
2159 item->SetLabel( text );
2160 UpdateItem( wxMacDataBrowserRootContainer, item , kTextColumnId );
2161 }
2162
2163 wxString wxMacDataItemBrowserControl::MacGetString( unsigned int n ) const
2164 {
2165 wxMacDataItem * item = (wxMacDataItem*) GetItemFromLine( n );
2166 return item->GetLabel();
2167 }
2168
2169 void wxMacDataItemBrowserControl::MacSetClientData( unsigned int n, void * data)
2170 {
2171 wxMacDataItem* item = (wxMacDataItem*) GetItemFromLine( n);
2172 item->SetData( data );
2173 // not displayed, therefore no Update infos to DataBrowser
2174 }
2175
2176 void * wxMacDataItemBrowserControl::MacGetClientData( unsigned int n) const
2177 {
2178 wxMacDataItem * item = (wxMacDataItem*) GetItemFromLine( n );
2179 return item->GetData();
2180 }
2181
2182 void wxMacDataItemBrowserControl::MacScrollTo( unsigned int n )
2183 {
2184 RevealItem( GetItemFromLine( n) , kDataBrowserRevealWithoutSelecting );
2185 }
2186
2187
2188
2189 //
2190 // Tab Control
2191 //
2192
2193 OSStatus wxMacControl::SetTabEnabled( SInt16 tabNo , bool enable )
2194 {
2195 return ::SetTabEnabled( m_controlRef , tabNo , enable );
2196 }
2197
2198 //
2199 // Quartz Support
2200 //
2201
2202 #ifdef __WXMAC_OSX__
2203 // snippets from Sketch Sample from Apple :
2204
2205 #define kGenericRGBProfilePathStr "/System/Library/ColorSync/Profiles/Generic RGB Profile.icc"
2206
2207 /*
2208 This function locates, opens, and returns the profile reference for the calibrated
2209 Generic RGB color space. It is up to the caller to call CMCloseProfile when done
2210 with the profile reference this function returns.
2211 */
2212 CMProfileRef wxMacOpenGenericProfile()
2213 {
2214 static CMProfileRef cachedRGBProfileRef = NULL;
2215
2216 // we only create the profile reference once
2217 if (cachedRGBProfileRef == NULL)
2218 {
2219 CMProfileLocation loc;
2220
2221 loc.locType = cmPathBasedProfile;
2222 strcpy(loc.u.pathLoc.path, kGenericRGBProfilePathStr);
2223
2224 verify_noerr( CMOpenProfile(&cachedRGBProfileRef, &loc) );
2225 }
2226
2227 // clone the profile reference so that the caller has their own reference, not our cached one
2228 if (cachedRGBProfileRef)
2229 CMCloneProfileRef(cachedRGBProfileRef);
2230
2231 return cachedRGBProfileRef;
2232 }
2233
2234 /*
2235 Return the generic RGB color space. This is a 'get' function and the caller should
2236 not release the returned value unless the caller retains it first. Usually callers
2237 of this routine will immediately use the returned colorspace with CoreGraphics
2238 so they typically do not need to retain it themselves.
2239
2240 This function creates the generic RGB color space once and hangs onto it so it can
2241 return it whenever this function is called.
2242 */
2243
2244 CGColorSpaceRef wxMacGetGenericRGBColorSpace()
2245 {
2246 static wxMacCFRefHolder<CGColorSpaceRef> genericRGBColorSpace;
2247
2248 if (genericRGBColorSpace == NULL)
2249 {
2250 if ( UMAGetSystemVersion() >= 0x1040 )
2251 {
2252 genericRGBColorSpace.Set( CGColorSpaceCreateWithName( CFSTR("kCGColorSpaceGenericRGB") ) );
2253 }
2254 else
2255 {
2256 CMProfileRef genericRGBProfile = wxMacOpenGenericProfile();
2257
2258 if (genericRGBProfile)
2259 {
2260 genericRGBColorSpace.Set( CGColorSpaceCreateWithPlatformColorSpace(genericRGBProfile) );
2261
2262 wxASSERT_MSG( genericRGBColorSpace != NULL, wxT("couldn't create the generic RGB color space") );
2263
2264 // we opened the profile so it is up to us to close it
2265 CMCloseProfile(genericRGBProfile);
2266 }
2267 }
2268 }
2269
2270 return genericRGBColorSpace;
2271 }
2272 #endif
2273
2274 #ifndef __LP64__
2275
2276 wxMacPortSaver::wxMacPortSaver( GrafPtr port )
2277 {
2278 ::GetPort( &m_port );
2279 ::SetPort( port );
2280 }
2281
2282 wxMacPortSaver::~wxMacPortSaver()
2283 {
2284 ::SetPort( m_port );
2285 }
2286 #endif
2287
2288 void wxMacGlobalToLocal( WindowRef window , Point*pt )
2289 {
2290 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4
2291 HIPoint p = CGPointMake( pt->h, pt->v );
2292 HIViewRef contentView ;
2293 // TODO check toolbar offset
2294 HIViewFindByID( HIViewGetRoot( window ), kHIViewWindowContentID , &contentView) ;
2295 HIPointConvert( &p, kHICoordSpace72DPIGlobal, NULL, kHICoordSpaceView, contentView );
2296 pt->h = p.x;
2297 pt->v = p.y;
2298 #else
2299 QDGlobalToLocalPoint( GetWindowPort(window), pt ) ;
2300 #endif
2301 }
2302
2303 void wxMacLocalToGlobal( WindowRef window , Point*pt )
2304 {
2305 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4
2306 HIPoint p = CGPointMake( pt->h, pt->v );
2307 HIViewRef contentView ;
2308 // TODO check toolbar offset
2309 HIViewFindByID( HIViewGetRoot( window ), kHIViewWindowContentID , &contentView) ;
2310 HIPointConvert( &p, kHICoordSpaceView, contentView, kHICoordSpace72DPIGlobal, NULL );
2311 pt->h = p.x;
2312 pt->v = p.y;
2313 #else
2314 QDLocalToGlobalPoint( GetWindowPort(window), pt ) ;
2315 #endif
2316 }
2317
2318 #endif // wxUSE_GUI