diff --git a/include/mac/carbon/LgiOsDefs.h b/include/mac/carbon/LgiOsDefs.h --- a/include/mac/carbon/LgiOsDefs.h +++ b/include/mac/carbon/LgiOsDefs.h @@ -1,340 +1,342 @@ // // FILE: LgiOsDefs.h (Mac) // AUTHOR: Matthew Allen // DATE: 1/12/2005 // DESCRIPTION: Lgi Mac OS X defines // // Copyright (C) 2005, Matthew Allen // fret@memecode.com // #ifndef __LGI_MAC_OS_DEFS_H #define __LGI_MAC_OS_DEFS_H #include #include #include #include #include "LgiInc.h" #include "LgiDefs.h" #include "GAutoPtr.h" #include "LgiClass.h" #include "pthread.h" ////////////////////////////////////////////////////////////////// // Includes #include "LgiInc.h" ////////////////////////////////////////////////////////////////// // Typedefs typedef WindowRef OsWindow; typedef ControlRef OsView; typedef pthread_t OsThread; typedef UniChar OsChar; typedef ATSUStyle OsFont; typedef CGContextRef OsPainter; typedef CGContextRef OsBitmap; typedef int OsProcessId; class LgiClass GMessage { public: typedef NativeInt Param; typedef NativeInt Result; int m; Param a; Param b; GMessage() { m = a = b = 0; } GMessage(int M, Param A = 0, Param B = 0) { m = M; a = A; b = B; } }; class OsAppArguments { struct OsAppArgumentsPriv *d; public: int Args; char **Arg; OsAppArguments(int args = 0, char **arg = 0); ~OsAppArguments(); void Set(char *CmdLine); OsAppArguments &operator =(OsAppArguments &a); }; ////////////////////////////////////////////////////////////////// // Defines #define MsgCode(msg) (msg->m) #define MsgA(msg) (msg->a) #define MsgB(msg) (msg->b) extern GMessage CreateMsg(int m, int a = 0, int b = 0); #define _stricmp strcasecmp #define _strnicmp strncasecmp // Posix system #define POSIX 1 // Process typedef int OsProcess; typedef int OsProcessId; // Threads typedef pthread_t OsThreadId; typedef pthread_mutex_t OsSemaphore; #define LgiGetCurrentThread() pthread_self() // Sockets #define ValidSocket(s) ((s)>=0) #define INVALID_SOCKET -1 typedef int OsSocket; // Sleep the current thread LgiFunc void LgiSleep(int i); // Run the message loop to process any pending messages #define LgiYield() GApp::ObjInstance()->Run(false) #define LGI_GViewMagic 0x14412662 #define LGI_FileDropFormat "furl" // typeFileURL #define LGI_LgiDropFormat "lgi " #define LGI_WideCharset "utf-16" #define LGI_PrintfInt64 "%lli" #define atoi64 atoll #define sprintf_s snprintf #define vsprintf_s vsnprintf #define swprintf_s swprintf #define LGI_IllegalFileNameChars "/:" // FIXME: what other characters should be in here? // Window flags #define GWF_VISIBLE 0x00000001 #define GWF_DISABLED 0x00000002 #define GWF_FOCUS 0x00000004 #define GWF_OVER 0x00000008 #define GWF_DROP_TARGET 0x00000010 #define GWF_SUNKEN 0x00000020 #define GWF_FLAT 0x00000040 #define GWF_RAISED 0x00000080 #define GWF_BORDER 0x00000100 #define GWF_DIALOG 0x00000200 #define GWF_DESTRUCTOR 0x00000400 #define GWF_QUIT_WND 0x00000800 // Menu flags #define ODS_SELECTED 0x1 #define ODS_DISABLED 0x2 #define ODS_CHECKED 0x4 /// Edge type: Sunken #define SUNKEN 1 /// Edge type: Raised #define RAISED 2 /// Edge type: Chiseled #define CHISEL 3 /// Edge type: Flat #define FLAT 4 /// The directory separator character on Linux as a char #define DIR_CHAR '/' /// The directory separator character on Linux as a string #define DIR_STR "/" /// The standard end of line string for Linux #define EOL_SEQUENCE "\n" /// Tests a char for being a slash #define IsSlash(c) (((c)=='/')||((c)=='\\')) /// Tests a char for being a quote #define IsQuote(c) (((c)=='\"')||((c)=='\'')) /// The path list separator character for Linux #define LGI_PATH_SEPARATOR ":" /// The pattern that matches all files in Linux #define LGI_ALL_FILES "*" /// The stardard extension for dynamically linked code #define LGI_LIBRARY_EXT "dylib" +/// The standard executable extension +#define LGI_EXECUTABLE_EXT "" // Carbon user events #define GViewThisPtr 'gvtp' #define kEventClassUser 'user' #define kEventUser 1 #define kEventParamLgiEvent 'Lgie' #define kEventParamLgiA 'Lgia' #define kEventParamLgiB 'Lgib' /// Base point for system messages. #define M_SYSTEM 0 /// Message that indicates the user is trying to close a top level window. #define M_CLOSE (M_SYSTEM+92) /// Minimum value for application defined message ID's #define M_USER (M_SYSTEM+1000) /// \brief Mouse enter event /// /// a = bool Inside; // is the mouse inside the client area?\n /// b = MAKELONG(x, y); // mouse location #define M_MOUSEENTER (M_USER+100) /// \brief Mouse exit event /// /// a = bool Inside; // is the mouse inside the client area?\n /// b = MAKELONG(x, y); // mouse location #define M_MOUSEEXIT (M_USER+101) /// \brief GView change notification /// /// a = (GView*) Wnd;\n /// b = (int) Flags; // Specific to each GView #define M_CHANGE (M_USER+102) /// \brief Pass a text message up to the UI to descibe whats happening /// /// a = (GView*) Wnd;\n /// b = (char*) Text; // description from window #define M_DESCRIBE (M_USER+103) // return (bool) #define M_WANT_DIALOG_PROC (M_USER+104) #define M_MENU (M_USER+105) #define M_COMMAND (M_USER+106) #define M_DRAG_DROP (M_USER+107) #define M_TRAY_NOTIFY (M_USER+108) #define M_CUT (M_USER+109) #define M_COPY (M_USER+110) #define M_PASTE (M_USER+111) #define M_PULSE (M_USER+112) #define M_DELETE (M_USER+113) /// GThreadWork object completed /// /// MsgA = (GThreadOwner*) Owner; /// MsgB = (GThreadWork*) WorkUnit; #define M_GTHREADWORK_COMPELTE (M_USER+114) /// Standard ID for an "Ok" button. /// \sa LgiMsg #define IDOK 1 /// Standard ID for a "Cancel" button. /// \sa LgiMsg #define IDCANCEL 2 /// Standard ID for a "Yes" button. /// \sa LgiMsg #define IDYES 3 /// Standard ID for a "No" button. /// \sa LgiMsg #define IDNO 4 /// Standard message box with an Ok button. /// \sa LgiMsg #define MB_OK 5 /// Standard message box with Ok and Cancel buttons. /// \sa LgiMsg #define MB_OKCANCEL 6 /// Standard message box with Yes and No buttons. /// \sa LgiMsg #define MB_YESNO 7 /// Standard message box with Yes, No and Cancel buttons. /// \sa LgiMsg #define MB_YESNOCANCEL 8 #define MB_SYSTEMMODAL 0x1000 /// The CTRL key is pressed /// \sa GKey #define LGI_VKEY_CTRL 0x001 /// The ALT key is pressed /// \sa GKey #define LGI_VKEY_ALT 0x002 /// The SHIFT key is pressed /// \sa GKey #define LGI_VKEY_SHIFT 0x004 /// The left mouse button is pressed /// \sa GMouse #define LGI_VMOUSE_LEFT 0x008 /// The middle mouse button is pressed /// \sa GMouse #define LGI_VMOUSE_MIDDLE 0x010 /// The right mouse button is pressed /// \sa GMouse #define LGI_VMOUSE_RIGHT 0x020 /// The ctrl key is pressed /// \sa GMouse #define LGI_VMOUSE_CTRL 0x040 /// The alt key is pressed /// \sa GMouse #define LGI_VMOUSE_ALT 0x080 /// The shift key is pressed /// \sa GMouse #define LGI_VMOUSE_SHIFT 0x100 /// The mouse event is a down click /// \sa GMouse #define LGI_VMOUSE_DOWN 0x200 /// The mouse event is a double click /// \sa GMouse #define LGI_VMOUSE_DOUBLE 0x400 // Keys #define VK_F1 1 #define VK_F2 2 #define VK_ENTER 3 #define VK_F3 4 #define VK_F4 5 #define VK_F5 6 #define VK_F6 7 #define VK_BACKSPACE 8 #define VK_TAB 9 #define VK_F7 11 #define VK_F8 12 #define VK_RETURN 13 #define VK_F9 14 #define VK_F10 15 #define VK_F11 16 #define VK_F12 17 #define VK_SHIFT 18 #define VK_PAGEUP 19 #define VK_PAGEDOWN 20 #define VK_HOME 21 #define VK_END 22 #define VK_INSERT 23 #define VK_DELETE 24 #define VK_APPS 25 #define VK_ESCAPE 27 #define VK_LEFT 28 #define VK_RIGHT 29 #define VK_UP 30 #define VK_DOWN 31 ///////////////////////////////////////////////////////////////////////////////////// // Externs LgiFunc GView *GWindowFromHandle(OsView hWnd); LgiFunc int GetMouseWheelLines(); LgiFunc int WinPointToHeight(int Pt); LgiFunc int WinHeightToPoint(int Ht); LgiFunc int stricmp(const char *a, const char *b); LgiFunc char *strlwr(char *a); LgiFunc char *strupr(char *a); LgiFunc char *p2c(unsigned char *s); LgiFunc void c2p255(Str255 &d, char *s); LgiFunc char *CFStringToUtf8(CFStringRef r); LgiFunc CFStringRef Utf8ToCFString(char *s, int len = -1); /// Convert a string d'n'd format to an OS dependant integer. LgiFunc int FormatToInt(char *s); /// Convert a Os dependant integer d'n'd format to a string. LgiFunc char *FormatToStr(int f); #endif diff --git a/src/mac/carbon/Lgi/GFileSelect.cpp b/src/mac/carbon/Lgi/GFileSelect.cpp --- a/src/mac/carbon/Lgi/GFileSelect.cpp +++ b/src/mac/carbon/Lgi/GFileSelect.cpp @@ -1,509 +1,509 @@ /// \file /// \author Matthew Allen /// \brief Native mac file open dialog. #include #include #include "Lgi.h" #include "GToken.h" ////////////////////////////////////////////////////////////////////////// // This is just a private data container to make it easier to change the // implementation of this class without effecting headers and applications. class GFileSelectPrivate { friend class GFileSelect; friend class GFileSelectDlg; friend class GFolderList; GView *Parent; GFileSelect *Select; char *Title; char *DefExt; bool MultiSelect; List Files; int CurrentType; List Types; List History; bool ShowReadOnly; bool ReadOnly; bool EatClose; public: static char *InitPath; static bool InitShowHiddenFiles; static GRect InitSize; GFileSelectPrivate(GFileSelect *select) { ShowReadOnly = false; ReadOnly = false; EatClose = false; Select = select; Title = 0; DefExt = 0; MultiSelect = false; Parent = 0; CurrentType = -1; } virtual ~GFileSelectPrivate() { DeleteArray(Title); DeleteArray(DefExt); Types.DeleteObjects(); Files.DeleteArrays(); History.DeleteArrays(); } Boolean FilterProc(AEDesc * theItem, NavFilterModes filterMode) { FSRef fs; if (!AEGetDescData(theItem, &fs, sizeof(fs))) { UInt8 path[300]; FSRefMakePath(&fs, path, sizeof(path)); if (DirExists((char*)path)) return true; char *Dir = strrchr((char*)path, '/'); if (Dir) { Dir++; for (GFileType *t = Types.First(); t; t = Types.Next()) { char *e = t->Extension(); if (e) { if (MatchStr(e, Dir)) return true; } } return false; } } return true; } void DoTypes(NavDialogRef Dlg) { if (Types.Length()) { int Len = 0; for (GFileType *t = Types.First(); t; t = Types.Next()) { if (t->Extension()) { if (stricmp(t->Extension(), LGI_ALL_FILES)) Len++; } } if (Len) { CFMutableArrayRef identifiers = CFArrayCreateMutable( kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks ); if (identifiers) { for (GFileType *t = Types.First(); t; t = Types.Next()) { char *Ext = t->Extension(); GToken e(Ext, ";"); for (int i=0; iShowReadOnly = b;; + d->ShowReadOnly = b; } bool GFileSelect::ReadOnly() { return d->ReadOnly; } char *GFileSelect::Name() { return d->Files.First(); } bool GFileSelect::Name(const char *n) { d->Files.DeleteArrays(); if (n) { char *ns = NewStr(n); if (ns) { for (char *c = ns; *c; c++) { if (strchr(LGI_IllegalFileNameChars, *c)) *c = '_'; } d->Files.Insert(ns); } } return true; } char *GFileSelect::operator [](int i) { return d->Files.ItemAt(i); } int GFileSelect::Length() { return d->Files.Length(); } int GFileSelect::Types() { return d->Types.Length(); } void GFileSelect::ClearTypes() { d->Types.DeleteObjects(); } GFileType *GFileSelect::TypeAt(int n) { return d->Types.ItemAt(n); } bool GFileSelect::Type(const char *Description, const char *Extension, int Data) { GFileType *Type = new GFileType; if (Type) { Type->Description(Description); Type->Extension(Extension); d->Types.Insert(Type); } return Type != 0; } int GFileSelect::SelectedType() { return d->CurrentType; } GViewI *GFileSelect::Parent() { return d->Parent; } void GFileSelect::Parent(GViewI *Window) { d->Parent = dynamic_cast(Window); } bool GFileSelect::MultiSelect() { return d->MultiSelect; } void GFileSelect::MultiSelect(bool Multi) { d->MultiSelect = Multi; } #define CharPropImpl(Func, Var) \ char *GFileSelect::Func() \ { \ return Var; \ } \ void GFileSelect::Func(const char *i) \ { \ DeleteArray(Var); \ if (i) \ { \ Var = NewStr(i); \ } \ } CharPropImpl(InitialDir, d->InitPath); CharPropImpl(Title, d->Title); CharPropImpl(DefaultExtension, d->DefExt); void Lgi_NavEventProc( NavEventCallbackMessage callBackSelector, NavCBRecPtr callBackParms, void * callBackUD) { GFileSelectPrivate *d = (GFileSelectPrivate*) callBackUD; switch (callBackSelector) { case kNavCBStart: { if (d->InitPath) { OSStatus e = noErr; AEDesc theLocation = {typeNull, NULL}; FSRef Ref; e = FSPathMakeRef((uchar*) d->InitPath, &Ref, 0); if (e) printf("%s:%i - FSPathMakeRef failed.\n", _FL); FSSpec Spec; FSGetCatalogInfo(&Ref, kFSCatInfoNone, 0, 0, &Spec, 0); e = AECreateDesc(typeFSS, &Spec, sizeof(FSSpec), &theLocation); if (e) printf("%s:%i - FSMakeFSSpec failed.\n", _FL); e = NavCustomControl(callBackParms->context, kNavCtlSetLocation, (void*)&theLocation); if (e) printf("%s:%i - FSMakeFSSpec failed.\n", _FL); } break; } } } Boolean Lgi_NavObjectFilterProc(AEDesc * theItem, void *info, void *callBackUD, NavFilterModes filterMode) { GFileSelectPrivate *d = (GFileSelectPrivate*) callBackUD; return d->FilterProc(theItem, filterMode); } bool GFileSelect::Open() { bool Status = false; NavDialogCreationOptions o; ZeroObj(o); OSStatus e = NavGetDefaultDialogCreationOptions(&o); if (e) printf("%s:%i - NavGetDefaultDialogCreationOptions failed with %i\n", _FL, (int)e); else { if (Name()) o.saveFileName = Utf8ToCFString(Name()); o.modality = kWindowModalityAppModal; if (MultiSelect()) o.optionFlags |= kNavAllowMultipleFiles; NavEventUPP EventUPP = NewNavEventUPP(Lgi_NavEventProc); NavObjectFilterUPP ObjectUPP = NewNavObjectFilterUPP(Lgi_NavObjectFilterProc); NavDialogRef Dlg = 0; e = NavCreateGetFileDialog( &o, 0, // NavTypeListHandle inTypeList, EventUPP, 0, // NavPreviewUPP inPreviewProc, 0, // ObjectUPP, d, &Dlg); if (e) printf("%s:%i - NavCreateGetFileDialog failed with %i\n", _FL, (int)e); - else + else if (Dlg) { d->DoTypes(Dlg); e = NavDialogRun(Dlg); if (e) printf("%s:%i - NavDialogRun failed with %i\n", _FL, (int)e); else { Status = d->DoReply(Dlg); } NavDialogDispose(Dlg); } DisposeNavEventUPP(EventUPP); DisposeNavObjectFilterUPP(ObjectUPP); } return Status; } bool GFileSelect::OpenFolder() { bool Status = false; NavDialogCreationOptions o; ZeroObj(o); OSStatus e = NavGetDefaultDialogCreationOptions(&o); if (e) printf("%s:%i - NavGetDefaultDialogCreationOptions failed with %i\n", _FL, (int)e); else { if (Name()) o.saveFileName = Utf8ToCFString(Name()); o.modality = kWindowModalityAppModal; NavEventUPP EventUPP = NewNavEventUPP(Lgi_NavEventProc); NavObjectFilterUPP ObjectUPP = NewNavObjectFilterUPP(Lgi_NavObjectFilterProc); NavDialogRef Dlg = 0; e = NavCreateChooseFolderDialog(&o, EventUPP, 0, // ObjectUPP, d, &Dlg); if (e) printf("%s:%i - NavCreateGetFileDialog failed with %i\n", _FL, (int)e); else { d->DoTypes(Dlg); e = NavDialogRun(Dlg); if (e) printf("%s:%i - NavDialogRun failed with %i\n", _FL, (int)e); else { Status = d->DoReply(Dlg); } NavDialogDispose(Dlg); } DisposeNavEventUPP(EventUPP); DisposeNavObjectFilterUPP(ObjectUPP); } return Status; } bool GFileSelect::Save() { bool Status = false; NavDialogCreationOptions o; ZeroObj(o); OSStatus e = NavGetDefaultDialogCreationOptions(&o); if (e) printf("%s:%i - NavGetDefaultDialogCreationOptions failed with %i\n", _FL, (int)e); else { if (Name()) o.saveFileName = Utf8ToCFString(Name()); o.modality = kWindowModalityAppModal; NavEventUPP EventUPP = NewNavEventUPP(Lgi_NavEventProc); NavObjectFilterUPP ObjectUPP = NewNavObjectFilterUPP(Lgi_NavObjectFilterProc); NavDialogRef Dlg = 0; e = NavCreatePutFileDialog( &o, 'type', 'lgi ', EventUPP, d, &Dlg); if (e) printf("%s:%i - NavCreatePutFileDialog failed with %i\n", _FL, (int)e); - else + else if (Dlg) { d->DoTypes(Dlg); e = NavDialogRun(Dlg); if (e) printf("%s:%i - NavDialogRun failed with %i\n", _FL, (int)e); else { Status = d->DoReply(Dlg, true); } NavDialogDispose(Dlg); } DisposeNavEventUPP(EventUPP); DisposeNavObjectFilterUPP(ObjectUPP); } return Status; }