summaryrefslogtreecommitdiffstats
path: root/macosx/tkMacOSXDialog.c
diff options
context:
space:
mode:
authorfvogel <fvogelnew1@free.fr>2017-06-05 18:32:24 (GMT)
committerfvogel <fvogelnew1@free.fr>2017-06-05 18:32:24 (GMT)
commitfbac4859a673c9a5f0c8936ed8d18ea9e9145304 (patch)
tree4e184d638205d9ce2ef854ebea9393e5d8d91bd3 /macosx/tkMacOSXDialog.c
parent452ee6a6849e04a6a94bc7488e935129614041f8 (diff)
parentfd3fd3d844d9ff5f83c3fd26ee88f2c02892c180 (diff)
downloadtk-fbac4859a673c9a5f0c8936ed8d18ea9e9145304.zip
tk-fbac4859a673c9a5f0c8936ed8d18ea9e9145304.tar.gz
tk-fbac4859a673c9a5f0c8936ed8d18ea9e9145304.tar.bz2
merge trunk
Diffstat (limited to 'macosx/tkMacOSXDialog.c')
-rw-r--r--macosx/tkMacOSXDialog.c555
1 files changed, 372 insertions, 183 deletions
diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c
index 80a7a11..3397f71 100644
--- a/macosx/tkMacOSXDialog.c
+++ b/macosx/tkMacOSXDialog.c
@@ -6,6 +6,7 @@
* Copyright (c) 1996-1997 Sun Microsystems, Inc.
* Copyright 2001-2009, Apple Inc.
* Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
+ * Copyright (c) 2017 Christian Gollwitzer.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -24,6 +25,22 @@
#define modalOther -1
#define modalError -2
+/*Vars for filtering in "open file" and "save file" dialogs.*/
+typedef struct {
+ bool doFileTypes; // show the accessory view which displays the filter menu
+ bool preselectFilter; // a filter was selected by the typevariable
+ bool userHasSelectedFilter; // The user has changed the filter in the accessory view
+ NSMutableArray *fileTypeNames; // array of names, e.g. "Text document"
+ NSMutableArray *fileTypeExtensions; // array of allowed extensions per name, e.g. "txt", "doc"
+ NSMutableArray *fileTypeLabels; // displayed string, e.g. "Text document (.txt, .doc)"
+ NSMutableArray *allAllowedExtensions; // set of all allowed extensions
+ NSInteger fileTypeIndex; // index of currently selected filter
+} filepanelFilterInfo;
+
+filepanelFilterInfo filterInfo;
+
+NSOpenPanel *openpanel;
+NSSavePanel *savepanel;
static const char *const colorOptionStrings[] = {
"-initialcolor", "-parent", "-title", NULL
@@ -142,22 +159,6 @@ static const short alertNativeButtonIndexAndTypeToButtonIndex[][3] = {
[TYPE_YESNOCANCEL] = {5, 6, 4},
};
-/*
- * Construct a file URL from directory and filename. Either may
- * be nil. If both are nil, returns nil.
- */
-#if MAC_OS_X_VERSION_MIN_REQUIRED > 1050
-static NSURL *getFileURL(NSString *directory, NSString *filename) {
- NSURL *url = nil;
- if (directory) {
- url = [NSURL fileURLWithPath:directory];
- }
- if (filename) {
- url = [NSURL URLWithString:filename relativeToURL:url];
- }
- return url;
-}
-#endif
#pragma mark TKApplication(TKDialog)
@@ -212,6 +213,7 @@ static NSURL *getFileURL(NSString *directory, NSString *filename) {
}
}
+
- (void) tkAlertDidEnd: (NSAlert *) alert returnCode: (NSInteger) returnCode
contextInfo: (void *) contextInfo
{
@@ -247,6 +249,23 @@ static NSURL *getFileURL(NSString *directory, NSString *filename) {
ckfree(callbackInfo);
}
}
+
+- (void)selectFormat:(id)sender {
+ NSPopUpButton *button = (NSPopUpButton *)sender;
+ filterInfo.fileTypeIndex = [button indexOfSelectedItem];
+ NSMutableArray *allowedtypes = filterInfo.fileTypeExtensions[filterInfo.fileTypeIndex];
+ [openpanel setAllowedFileTypes:allowedtypes];
+ filterInfo.userHasSelectedFilter = true;
+
+}
+
+- (void)saveFormat:(id)sender {
+ NSPopUpButton *button = (NSPopUpButton *)sender;
+ filterInfo.fileTypeIndex = [button indexOfSelectedItem];
+ NSMutableArray *allowedtypes = filterInfo.fileTypeExtensions[filterInfo.fileTypeIndex];
+ [savepanel setAllowedFileTypes:allowedtypes];
+}
+
@end
#pragma mark -
@@ -360,6 +379,98 @@ Tk_ChooseColorObjCmd(
end:
return result;
}
+
+/* dissect the -filetype nested lists and store the information
+ * in the filterInfo structure */
+int parseFileFilters(Tcl_Interp *interp, Tcl_Obj *fileTypesPtr, Tcl_Obj *typeVariablePtr) {
+
+ if (!fileTypesPtr) {
+ filterInfo.doFileTypes = false;
+ return TCL_OK;
+ }
+
+ FileFilterList fl;
+ TkInitFileFilters(&fl);
+ if (TkGetFileFilters(interp, &fl, fileTypesPtr, 0) != TCL_OK) {
+ TkFreeFileFilters(&fl);
+ return TCL_ERROR;
+ }
+
+ filterInfo.doFileTypes = (fl.filters != NULL);
+
+ filterInfo.fileTypeIndex = 0;
+ filterInfo.fileTypeExtensions = [NSMutableArray array];
+ filterInfo.fileTypeNames = [NSMutableArray array];
+ filterInfo.fileTypeLabels = [NSMutableArray array];
+ filterInfo.allAllowedExtensions = [NSMutableArray array];
+
+ if (filterInfo.doFileTypes) {
+ for (FileFilter *filterPtr = fl.filters; filterPtr;
+ filterPtr = filterPtr->next) {
+ NSString * name = [[NSString alloc] initWithUTF8String: filterPtr -> name];
+ [filterInfo.fileTypeNames addObject:name];
+ [name release];
+ NSMutableArray * clauseextensions = [NSMutableArray array];
+ NSMutableArray * displayextensions = [NSMutableArray array];
+
+ for (FileFilterClause *clausePtr = filterPtr->clauses; clausePtr;
+ clausePtr = clausePtr->next) {
+ for (GlobPattern *globPtr = clausePtr->patterns; globPtr;
+ globPtr = globPtr->next) {
+ const char *str = globPtr->pattern;
+ while (*str && (*str == '*' || *str == '.')) {
+ str++;
+ }
+ if (*str) {
+ NSString *extension = [[NSString alloc] initWithUTF8String:str];
+ if (![filterInfo.allAllowedExtensions containsObject:extension]) {
+ [filterInfo.allAllowedExtensions addObject:extension];
+ }
+
+ [clauseextensions addObject:extension];
+ [displayextensions addObject:[@"." stringByAppendingString:extension]];
+
+ [extension release];
+ }
+ }
+ }
+ [filterInfo.fileTypeExtensions addObject:clauseextensions];
+
+ NSMutableString * label = [[NSMutableString alloc] initWithString:name];
+ [label appendString:@" ("];
+ [label appendString:[displayextensions componentsJoinedByString:@", "]];
+ [label appendString:@")"];
+ [filterInfo.fileTypeLabels addObject:label];
+ [label release];
+
+ }
+
+ /* Check if the typevariable exists and matches one of the names */
+ filterInfo.preselectFilter = false;
+ filterInfo.userHasSelectedFilter = false;
+ if (typeVariablePtr) {
+ /* extract the variable content as a NSString */
+ Tcl_Obj *selectedFileTypeObj = Tcl_ObjGetVar2(interp, typeVariablePtr, NULL, TCL_GLOBAL_ONLY);
+
+ /* check that the typevariable exists */
+ if (selectedFileTypeObj != NULL) {
+ const char *selectedFileType = Tcl_GetString(selectedFileTypeObj);
+ NSString *selectedFileTypeStr = [[NSString alloc] initWithUTF8String:selectedFileType];
+ NSUInteger index = [filterInfo.fileTypeNames indexOfObject:selectedFileTypeStr];
+
+ if (index != NSNotFound) {
+ filterInfo.fileTypeIndex = index;
+ filterInfo.preselectFilter = true;
+ }
+ }
+ }
+
+ }
+
+ TkFreeFileFilters(&fl);
+ return TCL_OK;
+}
+
/*
*----------------------------------------------------------------------
@@ -388,19 +499,16 @@ Tk_GetOpenFileObjCmd(
char *str;
int i, result = TCL_ERROR, haveParentOption = 0;
int index, len, multiple = 0;
- FileFilterList fl;
- Tcl_Obj *cmdObj = NULL, *typeVariablePtr = NULL;
+ Tcl_Obj *cmdObj = NULL, *typeVariablePtr = NULL, *fileTypesPtr = NULL;
FilePanelCallbackInfo callbackInfoStruct;
FilePanelCallbackInfo *callbackInfo = &callbackInfoStruct;
NSString *directory = nil, *filename = nil;
- NSString *message, *title, *type;
+ NSString *message = nil, *title = nil;
NSWindow *parent;
- NSMutableArray *fileTypes = nil;
- NSOpenPanel *panel = [NSOpenPanel openPanel];
+ openpanel = [NSOpenPanel openPanel];
NSInteger modalReturnCode = modalError;
BOOL parentIsKey = NO;
- TkInitFileFilters(&fl);
for (i = 1; i < objc; i += 2) {
if (Tcl_GetIndexFromObjStruct(interp, objv[i], openOptionStrings,
sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
@@ -416,9 +524,7 @@ Tk_GetOpenFileObjCmd(
case OPEN_DEFAULT:
break;
case OPEN_FILETYPES:
- if (TkGetFileFilters(interp, &fl, objv[i + 1], 0) != TCL_OK) {
- goto end;
- }
+ fileTypesPtr = objv[i + 1];
break;
case OPEN_INITDIR:
str = Tcl_GetStringFromObj(objv[i + 1], &len);
@@ -432,13 +538,12 @@ Tk_GetOpenFileObjCmd(
if (len) {
filename = [[[NSString alloc] initWithUTF8String:str]
autorelease];
+ [openpanel setNameFieldStringValue:filename];
}
break;
case OPEN_MESSAGE:
message = [[NSString alloc] initWithUTF8String:
Tcl_GetString(objv[i + 1])];
- [panel setMessage:message];
- [message release];
break;
case OPEN_MULTIPLE:
if (Tcl_GetBooleanFromObj(interp, objv[i + 1],
@@ -457,8 +562,6 @@ Tk_GetOpenFileObjCmd(
case OPEN_TITLE:
title = [[NSString alloc] initWithUTF8String:
Tcl_GetString(objv[i + 1])];
- [panel setTitle:title];
- [title release];
break;
case OPEN_TYPEVARIABLE:
typeVariablePtr = objv[i + 1];
@@ -468,40 +571,70 @@ Tk_GetOpenFileObjCmd(
break;
}
}
- [panel setAllowsMultipleSelection:multiple];
- if (fl.filters) {
- fileTypes = [NSMutableArray array];
- for (FileFilter *filterPtr = fl.filters; filterPtr;
- filterPtr = filterPtr->next) {
- for (FileFilterClause *clausePtr = filterPtr->clauses; clausePtr;
- clausePtr = clausePtr->next) {
- for (GlobPattern *globPtr = clausePtr->patterns; globPtr;
- globPtr = globPtr->next) {
- str = globPtr->pattern;
- while (*str && (*str == '*' || *str == '.')) {
- str++;
- }
- if (*str) {
- type = [[NSString alloc] initWithUTF8String:str];
- if (![fileTypes containsObject:type]) {
- [fileTypes addObject:type];
- }
- [type release];
- }
- }
- for (MacFileType *mfPtr = clausePtr->macTypes; mfPtr;
- mfPtr = mfPtr->next) {
- if (mfPtr->type) {
- type = NSFileTypeForHFSTypeCode(mfPtr->type);
- if (![fileTypes containsObject:type]) {
- [fileTypes addObject:type];
- }
- }
- }
- }
+
+ /* From OSX 10.11, the title string is silently ignored.
+ * Prepend the title to the message
+ * NOTE should be conditional on OSX version, but
+ * -mmacosx-version-min does not revert this behaviour*/
+ if (title) {
+ [openpanel setTitle:title];
+ if (message) {
+ NSString *fullmessage = [[NSString alloc] initWithFormat:@"%@\n%@",title,message];
+ [message release];
+ [title release];
+ message = fullmessage;
+ } else {
+ message = title;
+ }
+ }
+
+ if (message) {
+ [openpanel setMessage:message];
+ [message release];
+ }
+
+ [openpanel setAllowsMultipleSelection:multiple];
+
+ if (parseFileFilters(interp, fileTypesPtr, typeVariablePtr) != TCL_OK) {
+ goto end;
+ }
+
+ if (filterInfo.doFileTypes) {
+ NSView *accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 200, 32.0)];
+ NSTextField *label = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 60, 22)];
+ [label setEditable:NO];
+ [label setStringValue:@"Enable:"];
+ [label setBordered:NO];
+ [label setBezeled:NO];
+ [label setDrawsBackground:NO];
+
+ NSPopUpButton *popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 140, 22.0) pullsDown:NO];
+ [popupButton addItemsWithTitles:filterInfo.fileTypeLabels];
+ [popupButton setAction:@selector(selectFormat:)];
+
+ [accessoryView addSubview:label];
+ [accessoryView addSubview:popupButton];
+
+ if (filterInfo.preselectFilter) {
+ /* A specific filter was selected from the typevariable. Select it and
+ * open the accessory view */
+ [popupButton selectItemAtIndex:filterInfo.fileTypeIndex];
+ /* on OSX > 10.11, the optons are not visible by default. Ergo allow all file types
+ [openpanel setAllowedFileTypes:filterInfo.fileTypeExtensions[filterInfo.fileTypeIndex]];
+ */
+ [openpanel setAllowedFileTypes:filterInfo.allAllowedExtensions];
+ } else {
+ [openpanel setAllowedFileTypes:filterInfo.allAllowedExtensions];
}
+
+ [openpanel setAllowsOtherFileTypes:NO];
+
+ [openpanel setAccessoryView:accessoryView];
+ } else {
+ /* No filters are given. Allow picking all files */
+ [openpanel setAllowsOtherFileTypes:YES];
}
- [panel setAllowedFileTypes:fileTypes];
+
if (cmdObj) {
callbackInfo = ckalloc(sizeof(FilePanelCallbackInfo));
if (Tcl_IsShared(cmdObj)) {
@@ -509,6 +642,7 @@ Tk_GetOpenFileObjCmd(
}
Tcl_IncrRefCount(cmdObj);
}
+
callbackInfo->cmdObj = cmdObj;
callbackInfo->interp = interp;
callbackInfo->multiple = multiple;
@@ -516,52 +650,63 @@ Tk_GetOpenFileObjCmd(
if (haveParentOption && parent && ![parent attachedSheet]) {
parentIsKey = [parent isKeyWindow];
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
- [panel beginSheetForDirectory:directory
+ [openpanel beginSheetForDirectory:directory
file:filename
- types:fileTypes
+ types:openFileTypes
modalForWindow:parent
modalDelegate:NSApp
didEndSelector:
@selector(tkFilePanelDidEnd:returnCode:contextInfo:)
contextInfo:callbackInfo];
#else
- [panel setAllowedFileTypes:fileTypes];
- [panel setDirectoryURL:getFileURL(directory, filename)];
- [panel beginSheetModalForWindow:parent
+ if (directory) {
+ [openpanel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]];
+ }
+ [openpanel setNameFieldStringValue:filename];
+ [openpanel beginSheetModalForWindow:parent
completionHandler:^(NSInteger returnCode)
- { [NSApp tkFilePanelDidEnd:panel
+ { [NSApp tkFilePanelDidEnd:openpanel
returnCode:returnCode
contextInfo:callbackInfo ]; } ];
#endif
- modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:panel];
+ modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:openpanel];
} else {
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
- modalReturnCode = [panel runModalForDirectory:directory
+ modalReturnCode = [openpanel runModalForDirectory:directory
file:filename];
#else
- [panel setDirectoryURL:getFileURL(directory, filename)];
- modalReturnCode = [panel runModal];
+ if (directory) {
+ [openpanel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]];
+ }
+ [openpanel setNameFieldStringValue:filename];
+ modalReturnCode = [openpanel runModal];
#endif
- [NSApp tkFilePanelDidEnd:panel returnCode:modalReturnCode
+ [NSApp tkFilePanelDidEnd:openpanel returnCode:modalReturnCode
contextInfo:callbackInfo];
}
result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
if (parentIsKey) {
[parent makeKeyWindow];
}
- if (typeVariablePtr && result == TCL_OK) {
+
+ if ((typeVariablePtr && (modalReturnCode == NSOKButton)) &&
+ filterInfo.doFileTypes && filterInfo.userHasSelectedFilter) {
/*
- * The -typevariable option is not really supported.
+ * The -typevariable must be set to the selected file type, if the dialog was not cancelled
*/
-
- Tcl_SetVar2(interp, Tcl_GetString(typeVariablePtr), NULL,
- "", TCL_GLOBAL_ONLY);
+ #if 0
+ NSLog(@"result: %i modal: %li", result, (long)modalReturnCode);
+ #endif
+ NSString * selectedFilter = filterInfo.fileTypeNames[filterInfo.fileTypeIndex];
+ Tcl_ObjSetVar2(interp, typeVariablePtr, NULL,
+ Tcl_NewStringObj([selectedFilter UTF8String], -1), TCL_GLOBAL_ONLY);
}
+
end:
- TkFreeFileFilters(&fl);
return result;
}
+
/*
*----------------------------------------------------------------------
@@ -591,19 +736,16 @@ Tk_GetSaveFileObjCmd(
int i, result = TCL_ERROR, haveParentOption = 0;
int confirmOverwrite = 1;
int index, len;
- FileFilterList fl;
- Tcl_Obj *cmdObj = NULL;
+ Tcl_Obj *cmdObj = NULL, *typeVariablePtr = NULL, *fileTypesPtr = NULL;
FilePanelCallbackInfo callbackInfoStruct;
FilePanelCallbackInfo *callbackInfo = &callbackInfoStruct;
NSString *directory = nil, *filename = nil, *defaultType = nil;
- NSString *message, *title, *type;
+ NSString *message = nil, *title = nil;
NSWindow *parent;
- NSMutableArray *fileTypes = nil;
- NSSavePanel *panel = [NSSavePanel savePanel];
+ savepanel = [NSSavePanel savePanel];
NSInteger modalReturnCode = modalError;
BOOL parentIsKey = NO;
- TkInitFileFilters(&fl);
for (i = 1; i < objc; i += 2) {
if (Tcl_GetIndexFromObjStruct(interp, objv[i], saveOptionStrings,
sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
@@ -616,96 +758,120 @@ Tk_GetSaveFileObjCmd(
goto end;
}
switch (index) {
- case SAVE_DEFAULT:
- str = Tcl_GetStringFromObj(objv[i + 1], &len);
- while (*str && (*str == '*' || *str == '.')) {
- str++;
- }
- if (*str) {
- defaultType = [[[NSString alloc] initWithUTF8String:str]
- autorelease];
- }
- break;
- case SAVE_FILETYPES:
- if (TkGetFileFilters(interp, &fl, objv[i + 1], 0) != TCL_OK) {
- goto end;
- }
- break;
- case SAVE_INITDIR:
- str = Tcl_GetStringFromObj(objv[i + 1], &len);
- if (len) {
- directory = [[[NSString alloc] initWithUTF8String:str]
- autorelease];
- }
- break;
- case SAVE_INITFILE:
- str = Tcl_GetStringFromObj(objv[i + 1], &len);
- if (len) {
- filename = [[[NSString alloc] initWithUTF8String:str]
- autorelease];
- }
- break;
- case SAVE_MESSAGE:
- message = [[NSString alloc] initWithUTF8String:
- Tcl_GetString(objv[i + 1])];
- [panel setMessage:message];
+ case SAVE_DEFAULT:
+ str = Tcl_GetStringFromObj(objv[i + 1], &len);
+ while (*str && (*str == '*' || *str == '.')) {
+ str++;
+ }
+ if (*str) {
+ defaultType = [[[NSString alloc] initWithUTF8String:str]
+ autorelease];
+ }
+ break;
+ case SAVE_FILETYPES:
+ fileTypesPtr = objv[i + 1];
+ break;
+ case SAVE_INITDIR:
+ str = Tcl_GetStringFromObj(objv[i + 1], &len);
+ if (len) {
+ directory = [[[NSString alloc] initWithUTF8String:str]
+ autorelease];
+ }
+ break;
+ case SAVE_INITFILE:
+ str = Tcl_GetStringFromObj(objv[i + 1], &len);
+ if (len) {
+ filename = [[[NSString alloc] initWithUTF8String:str]
+ autorelease];
+ [savepanel setNameFieldStringValue:filename];
+ }
+ break;
+ case SAVE_MESSAGE:
+ message = [[NSString alloc] initWithUTF8String:
+ Tcl_GetString(objv[i + 1])];
+ break;
+ case SAVE_PARENT:
+ str = Tcl_GetStringFromObj(objv[i + 1], &len);
+ tkwin = Tk_NameToWindow(interp, str, tkwin);
+ if (!tkwin) {
+ goto end;
+ }
+ haveParentOption = 1;
+ break;
+ case SAVE_TITLE:
+ title = [[NSString alloc] initWithUTF8String:
+ Tcl_GetString(objv[i + 1])];
+ break;
+ case SAVE_TYPEVARIABLE:
+ typeVariablePtr = objv[i + 1];
+ break;
+ case SAVE_COMMAND:
+ cmdObj = objv[i+1];
+ break;
+ case SAVE_CONFIRMOW:
+ if (Tcl_GetBooleanFromObj(interp, objv[i + 1],
+ &confirmOverwrite) != TCL_OK) {
+ goto end;
+ }
+ break;
+ }
+ }
+
+ if (title) {
+ [savepanel setTitle:title];
+ if (message) {
+ NSString *fullmessage = [[NSString alloc] initWithFormat:@"%@\n%@",title,message];
[message release];
- break;
- case SAVE_PARENT:
- str = Tcl_GetStringFromObj(objv[i + 1], &len);
- tkwin = Tk_NameToWindow(interp, str, tkwin);
- if (!tkwin) {
- goto end;
- }
- haveParentOption = 1;
- break;
- case SAVE_TITLE:
- title = [[NSString alloc] initWithUTF8String:
- Tcl_GetString(objv[i + 1])];
- [panel setTitle:title];
[title release];
- break;
- case SAVE_TYPEVARIABLE:
- break;
- case SAVE_COMMAND:
- cmdObj = objv[i+1];
- break;
- case SAVE_CONFIRMOW:
- if (Tcl_GetBooleanFromObj(interp, objv[i + 1],
- &confirmOverwrite) != TCL_OK) {
- goto end;
- }
- break;
+ message = fullmessage;
+ } else {
+ message = title;
}
}
- if (fl.filters || defaultType) {
- fileTypes = [NSMutableArray array];
- [fileTypes addObject:defaultType ? defaultType : (id)kUTTypeContent];
- for (FileFilter *filterPtr = fl.filters; filterPtr;
- filterPtr = filterPtr->next) {
- for (FileFilterClause *clausePtr = filterPtr->clauses; clausePtr;
- clausePtr = clausePtr->next) {
- for (GlobPattern *globPtr = clausePtr->patterns; globPtr;
- globPtr = globPtr->next) {
- str = globPtr->pattern;
- while (*str && (*str == '*' || *str == '.')) {
- str++;
- }
- if (*str) {
- type = [[NSString alloc] initWithUTF8String:str];
- if (![fileTypes containsObject:type]) {
- [fileTypes addObject:type];
- }
- [type release];
- }
- }
- }
- }
- [panel setAllowedFileTypes:fileTypes];
- [panel setAllowsOtherFileTypes:YES];
+
+ if (message) {
+ [savepanel setMessage:message];
+ [message release];
+ }
+
+ if (parseFileFilters(interp, fileTypesPtr, typeVariablePtr) != TCL_OK) {
+ goto end;
}
- [panel setCanSelectHiddenExtension:YES];
- [panel setExtensionHidden:NO];
+
+ if (filterInfo.doFileTypes) {
+ NSView *accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 200, 32.0)];
+ NSTextField *label = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 60, 22)];
+ [label setEditable:NO];
+ [label setStringValue:NSLocalizedString(@"Format:", nil)];
+ [label setBordered:NO];
+ [label setBezeled:NO];
+ [label setDrawsBackground:NO];
+
+ NSPopUpButton *popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 140, 22.0) pullsDown:NO];
+ [popupButton addItemsWithTitles:filterInfo.fileTypeLabels];
+ [popupButton selectItemAtIndex:filterInfo.fileTypeIndex];
+ [popupButton setAction:@selector(saveFormat:)];
+
+ [accessoryView addSubview:label];
+ [accessoryView addSubview:popupButton];
+
+ [savepanel setAccessoryView:accessoryView];
+
+ [savepanel setAllowedFileTypes:filterInfo.fileTypeExtensions[filterInfo.fileTypeIndex]];
+ [savepanel setAllowsOtherFileTypes:NO];
+ } else if (defaultType) {
+ /* If no filetypes are given, defaultextension is an alternative way
+ * to specify the attached extension. Just propose this extension,
+ * but don't display an accessory view */
+ NSMutableArray *AllowedFileTypes = [NSMutableArray array];
+ [AllowedFileTypes addObject:defaultType];
+ [savepanel setAllowedFileTypes:AllowedFileTypes];
+ [savepanel setAllowsOtherFileTypes:YES];
+ }
+
+ [savepanel setCanSelectHiddenExtension:YES];
+ [savepanel setExtensionHidden:NO];
+
if (cmdObj) {
callbackInfo = ckalloc(sizeof(FilePanelCallbackInfo));
if (Tcl_IsShared(cmdObj)) {
@@ -716,11 +882,12 @@ Tk_GetSaveFileObjCmd(
callbackInfo->cmdObj = cmdObj;
callbackInfo->interp = interp;
callbackInfo->multiple = 0;
+
parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
if (haveParentOption && parent && ![parent attachedSheet]) {
parentIsKey = [parent isKeyWindow];
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
- [panel beginSheetForDirectory:directory
+ [savepanel beginSheetForDirectory:directory
file:filename
modalForWindow:parent
modalDelegate:NSApp
@@ -728,30 +895,52 @@ Tk_GetSaveFileObjCmd(
@selector(tkFilePanelDidEnd:returnCode:contextInfo:)
contextInfo:callbackInfo];
#else
- [panel setDirectoryURL:getFileURL(directory, filename)];
- [panel beginSheetModalForWindow:parent
+ if (directory) {
+ [savepanel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]];
+ }
+ [savepanel setNameFieldStringValue:filename];
+ [savepanel beginSheetModalForWindow:parent
completionHandler:^(NSInteger returnCode)
- { [NSApp tkFilePanelDidEnd:panel
+ { [NSApp tkFilePanelDidEnd:savepanel
returnCode:returnCode
contextInfo:callbackInfo ]; } ];
#endif
- modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:panel];
+ modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:savepanel];
} else {
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
- modalReturnCode = [panel runModalForDirectory:directory file:filename];
+ modalReturnCode = [savepanel runModalForDirectory:directory file:filename];
#else
- [panel setDirectoryURL:getFileURL(directory, filename)];
- modalReturnCode = [panel runModal];
+ if (directory) {
+ [savepanel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]];
+ }
+ [savepanel setNameFieldStringValue:filename];
+ modalReturnCode = [savepanel runModal];
+ #if 0
+ NSLog(@"modal: %li", modalReturnCode);
+ #endif
#endif
- [NSApp tkFilePanelDidEnd:panel returnCode:modalReturnCode
+ [NSApp tkFilePanelDidEnd:savepanel returnCode:modalReturnCode
contextInfo:callbackInfo];
}
result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
if (parentIsKey) {
[parent makeKeyWindow];
}
+
+ if ((typeVariablePtr && (modalReturnCode == NSOKButton)) && filterInfo.doFileTypes) {
+ /*
+ * The -typevariable must be set to the selected file type, if the dialog was not cancelled
+ */
+ #if 0
+ NSLog(@"result: %i modal: %li", result, (long)modalReturnCode);
+ #endif
+ NSString * selectedFilter = filterInfo.fileTypeNames[filterInfo.fileTypeIndex];
+ Tcl_ObjSetVar2(interp, typeVariablePtr, NULL,
+ Tcl_NewStringObj([selectedFilter UTF8String], -1), TCL_GLOBAL_ONLY);
+ }
+
+
end:
- TkFreeFileFilters(&fl);
return result;
}
@@ -787,7 +976,7 @@ Tk_ChooseDirectoryObjCmd(
Tcl_Obj *cmdObj = NULL;
FilePanelCallbackInfo callbackInfoStruct;
FilePanelCallbackInfo *callbackInfo = &callbackInfoStruct;
- NSString *directory = nil, *filename = nil;
+ NSString *directory = nil;
NSString *message, *title;
NSWindow *parent;
NSOpenPanel *panel = [NSOpenPanel openPanel];
@@ -863,13 +1052,13 @@ Tk_ChooseDirectoryObjCmd(
parentIsKey = [parent isKeyWindow];
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
[panel beginSheetForDirectory:directory
- file:filename
+ file:nil
modalForWindow:parent
modalDelegate:NSApp
didEndSelector: @selector(tkFilePanelDidEnd:returnCode:contextInfo:)
contextInfo:callbackInfo];
#else
- [panel setDirectoryURL:getFileURL(directory, filename)];
+ [panel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]];
[panel beginSheetModalForWindow:parent
completionHandler:^(NSInteger returnCode)
{ [NSApp tkFilePanelDidEnd:panel
@@ -881,7 +1070,7 @@ Tk_ChooseDirectoryObjCmd(
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
modalReturnCode = [panel runModalForDirectory:directory file:nil];
#else
- [panel setDirectoryURL:getFileURL(directory, filename)];
+ [panel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]];
modalReturnCode = [panel runModal];
#endif
[NSApp tkFilePanelDidEnd:panel returnCode:modalReturnCode