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