better file-extension support for Mac OS X put-file dialog

svn: r12638
This commit is contained in:
Matthew Flatt 2008-11-29 18:52:25 +00:00
parent 789e51897c
commit 7f4ddbe5fa
6 changed files with 157 additions and 42 deletions

View File

@ -118,22 +118,24 @@ Under Windows, if @scheme[extension] is not @scheme[#f], the returned path
is @scheme[(string-append "*." extension)], then the result pathname is guaranteed
to have an extension mapping @scheme[extension].
Under Mac OS X, if @scheme[extension] is not @scheme[#f]
and @scheme[filters] contains the single
pattern @scheme[(string-append "*." extension)], then the result pathname is
guaranteed to have an extension mapping @scheme[extension]. Otherwise,
@scheme[extension] and @scheme[filters] are ignored.
Under Mac OS X, if @scheme[extension] is not @scheme[#f], the returned
path will get a default extension if the user does not supply one.
If @scheme[filters] contains as @scheme["*.*"] pattern, then the user
can supply any extension that is recognized by the system; otherwise,
the extension on the returned path will be either @scheme[extension]
or @scheme[_other-extension] for any @scheme[(string-append "*."
_other-extension)] pattern in @scheme[filters]. In particular, if the
only pattern in @scheme[filters] is empty or contains only
@scheme[(string-append "*." extension)], then the result pathname is
guaranteed to have an extension mapping @scheme[extension].
The @scheme[extension] argument is ignored under X, and @scheme[filters]
can be used to specify glob-patterns.
The @scheme[extension] argument is ignored under X, and
@scheme[filters] can be used to specify glob-patterns.
The @scheme[style] list is treated as for
@scheme[get-file].
The @scheme[style] list is treated as for @scheme[get-file].
See also @scheme[path-dialog%].
}
@defproc[(get-directory [message (or/c string? false/c) #f]

View File

@ -1333,6 +1333,8 @@ xform: $(XSRCS) xsrc/xcglue.c
wx_font.o : $(srcdir)/../../wxmac/src/mac/wx_font.m
$(CXX) -o wx_font.o -c $(srcdir)/../../wxmac/src/mac/wx_font.m
wx_file_dialog.o : $(srcdir)/../../wxmac/src/mac/wx_file_dialog.m
$(CXX) -o wx_file_dialog.o -c $(srcdir)/../../wxmac/src/mac/wx_file_dialog.m
wx_xt_LIBS = ../../wxxt/contrib/xpm/lib/libXpm.@LTA@ @JPEG_A@ @PNG_A@ @ZLIB_A@
wx_mac_LIBS = -framework Carbon -framework Cocoa -framework QuickTime -framework AGL -framework OpenGL @JPEG_A@ @PNG_A@ -lz @LIBS@
@ -1377,8 +1379,8 @@ MRFWRES = PLT_MrEd.framework/Versions/$(FWVERSION)_3m/Resources/PLT_MrEd.rsrc
cp -r "PLT_MrEd.framework/Versions/$(FWVERSION)_3m/Resources" "../PLT_MrEd.framework/Versions/$(FWVERSION)_3m/Resources"
/usr/bin/install_name_tool -change "PLT_MrEd.framework/Versions/$(FWVERSION)_3m/PLT_MrEd" "@executable_path/../../../PLT_MrEd.framework/Versions/$(FWVERSION)_3m/PLT_MrEd" "../MrEd@MMM@.app/Contents/MacOS/MrEd@MMM@"
$(MRFW) : $(XOBJS) $(@WXVARIANT@_PLAIN_OBJS) ../../mzscheme/libmzscheme3m.@LIBSFX@ wx_font.o $(MRFWRES)
$(MREDLINKER) $(LDFLAGS) -dynamiclib -o $(MRFW) -Wl,-headerpad_max_install_names $(XOBJS) $(@WXVARIANT@_PLAIN_OBJS) ../../mzscheme/libmzscheme3m.@LIBSFX@ $(@WXVARIANT@_LIBS) @X_EXTRA_LIBS@ wx_font.o
$(MRFW) : $(XOBJS) $(@WXVARIANT@_PLAIN_OBJS) ../../mzscheme/libmzscheme3m.@LIBSFX@ wx_font.o wx_file_dialog.o $(MRFWRES)
$(MREDLINKER) $(LDFLAGS) -dynamiclib -o $(MRFW) -Wl,-headerpad_max_install_names $(XOBJS) $(@WXVARIANT@_PLAIN_OBJS) ../../mzscheme/libmzscheme3m.@LIBSFX@ $(@WXVARIANT@_LIBS) @X_EXTRA_LIBS@ wx_font.o wx_file_dialog.o
$(MRFWRES): $(srcdir)/../../mac/osx_appl.ss $(srcdir)/../../mac/cw/MrEd.r
rm -rf PLT_MrEd.framework/Resources PLT_MrEd.framework/PLT_MrEd

View File

@ -146,6 +146,7 @@ OBJS = \
wx_xbm.o \
\
wx_font.o \
wx_file_dialog.o \
\
$(MIN_OBJS)
@ -385,9 +386,11 @@ ALSelectors.o : $(ALISTDEPS) $(ALISTDIR)/ALSelectors.c
$(CC) $(ALISTCCFLAGS) -o ALSelectors.o -c $(ALISTDIR)/ALSelectors.c
########################################
# Cocoa fonts #
# Cocoa #
########################################
wx_file_dialog.o : $(srcdir)/mac/wx_file_dialog.m
$(CXX) -o wx_file_dialog.o -c $(srcdir)/mac/wx_file_dialog.m
wx_font.o : $(srcdir)/mac/wx_font.m
$(CXX) -o wx_font.o -c $(srcdir)/mac/wx_font.m

View File

@ -585,7 +585,8 @@ static void ExtensionCallback(NavEventCallbackMessage callBackSelector,
}
break;
case kNavCBStart:
{
if (0) {
/* No longer needed */
EventTypeSpec spec[1];
spec[0].eventClass = kEventClassKeyboard;
spec[0].eventKind = kEventRawKeyDown;
@ -638,6 +639,40 @@ static char *GetNthPath(NavReplyRecord *reply, int index)
static NavEventUPP extProc = NewNavEventUPP((NavEventProcPtr)ExtensionCallback);
static WindowPtr extract_sheet_parent(wxWindow *parent)
{
if (parent) {
wxFrame *f;
if (wxSubType(parent->__type, wxTYPE_FRAME)) {
f = (wxFrame *)parent;
} else if (wxSubType(parent->__type, wxTYPE_DIALOG_BOX)) {
f = (wxFrame *)parent->GetParent();
} else
f = NULL;
if (f)
f = f->GetSheetParent();
if (f) {
CGrafPtr graf;
wxMacDC *mdc;
WindowPtr win;
mdc = f->MacDC();
graf = mdc->macGrafPort();
win = GetWindowFromPort(graf);
if (IsWindowVisible(win))
return win;
}
}
return NULL;
}
extern "C" void wx_set_nav_file_types(NavDialogRef dlg, int cnt, char **exts, char *def_ext);
char *wxFileSelector(char *message, char *default_path,
char *default_filename, char *default_extension,
char *wildcard, int flags,
@ -652,6 +687,8 @@ char *wxFileSelector(char *message, char *default_path,
NavUserAction action;
NavReplyRecord *reply;
char *temp;
char **acceptable_extensions = NULL;
int num_acceptable = 0, single_type = 0;
if (!navinited) {
if (!NavLoad()) {
@ -691,10 +728,14 @@ char *wxFileSelector(char *message, char *default_path,
if (s2) {
int len, flen;
len = strlen(default_extension);
if ((s1[0] == '*')
if ((s1[0] == '*')
&& (s1[1] == '.')
&& ((s2 - s1) == (len + 2))
&& !strncmp(default_extension, s1+2, len)) {
&& !strncmp(default_extension, s1+2, len)
&& (!s1[len+2]
|| ((s1[len+2] == '|')
&& !s1[len+3]))) {
single_type = 1;
dialogOptions.optionFlags |= kNavPreserveSaveFileExtension;
/* Make sure initial name has specified extension: */
if (!default_filename)
@ -714,6 +755,44 @@ char *wxFileSelector(char *message, char *default_path,
}
}
}
if (!single_type) {
/* Extract defaults */
int cnt = 0;
char **a, *ext;
s1 = wildcard;
while (s1) {
s1 = strchr(s1, '|');
if (s1) {
if ((s1[1] == '*')
&& (s1[2] == '.')) {
cnt++;
s1 = strchr(s1 + 1, '|');
if (s1) s1++;
} else
s1 = 0;
}
}
if (cnt) {
int i;
a = new WXGC_PTRS char*[cnt];
s1 = wildcard;
for (i = 0; i < cnt; i++) {
s1 = strchr(s1, '|');
s1 += 3;
s2 = strchr(s1, '|');
if (!s2)
s2 = s1 + strlen(s1);
ext = new WXGC_ATOMIC char[s2 - s1 + 1];
memcpy(ext, s1, s2 - s1);
ext[s2 - s1] = 0;
a[i] = ext;
s1 = s2 + 1;
}
acceptable_extensions = a;
num_acceptable = cnt;
}
}
}
if (default_filename) {
@ -723,30 +802,13 @@ char *wxFileSelector(char *message, char *default_path,
cbi->has_parent = 1;
if (parent) {
wxFrame *f;
if (wxSubType(parent->__type, wxTYPE_FRAME)) {
f = (wxFrame *)parent;
} else if (wxSubType(parent->__type, wxTYPE_DIALOG_BOX)) {
f = (wxFrame *)parent->GetParent();
} else
f = NULL;
if (f)
f = f->GetSheetParent();
if (f) {
CGrafPtr graf;
wxMacDC *mdc;
WindowPtr win;
mdc = f->MacDC();
graf = mdc->macGrafPort();
win = GetWindowFromPort(graf);
if (IsWindowVisible(win)) {
dialogOptions.parentWindow = win;
dialogOptions.modality = kWindowModalityWindowModal;
cbi->has_parent = 1;
}
WindowPtr win;
win = extract_sheet_parent(parent);
if (win) {
dialogOptions.parentWindow = win;
dialogOptions.modality = kWindowModalityWindowModal;
cbi->has_parent = 1;
}
}
@ -767,6 +829,9 @@ char *wxFileSelector(char *message, char *default_path,
extProc, cbi_sr,
&outDialog);
cbi->is_put = 1;
if (derr == noErr)
wx_set_nav_file_types(outDialog, num_acceptable, acceptable_extensions,
default_extension);
}
cbi->dialog = outDialog;

View File

@ -0,0 +1,43 @@
/* Set options for the Cocoa file dialog */
#import <Cocoa/Cocoa.h>
#include <Carbon/Carbon.h>
void wx_set_nav_file_types(NavDialogRef dlg, int cnt, char **exts, char *def_ext)
{
if (cnt) {
id pool = [[NSAutoreleasePool alloc] init];
id *objs;
int i, j, allow_others = 0;
NSArray *a;
NSSavePanel *sp = (NSSavePanel *)dlg;
for (i = 0; i < cnt; i++) {
if (!strcmp(exts[i], "*"))
allow_others = 1;
}
objs = (id *)malloc(sizeof(id) * (1 + (cnt - allow_others)));
j = 0;
objs[j++] = [[NSString alloc] initWithUTF8String: def_ext];
for (i = 0; i < cnt; i++) {
if (strcmp(exts[i], "*"))
objs[j++] = [[NSString alloc] initWithUTF8String: exts[i]];
}
a = [NSArray arrayWithObjects:objs count:j];
[sp setAllowedFileTypes:a];
sp.canSelectHiddenExtension = TRUE;
if (!allow_others)
sp.allowsOtherFileTypes = FALSE;
for (i = 0; i < j; i++) {
[objs[i] release];
}
free(objs);
[pool release];
}
}

View File

@ -1,6 +1,6 @@
/* The easiest way to find out whether a font is fixed-width is to
jump over the to Coacao world. The ATS and Cocoa worlds are
jump over the to Cocao world. The ATS and Cocoa worlds are
connected through the PostScript name of a font. */
#import <Cocoa/Cocoa.h>