summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorculler <culler>2017-11-25 21:08:45 (GMT)
committerculler <culler>2017-11-25 21:08:45 (GMT)
commit35d2c42c649984e5ba5d5b31d52c6fef3b450417 (patch)
tree13164dd0d1579b6fa396a6e5d08ab30667dcb22f
parent945ce561d3f680c8fea5981211b8afd2a2dc255d (diff)
downloadtk-35d2c42c649984e5ba5d5b31d52c6fef3b450417.zip
tk-35d2c42c649984e5ba5d5b31d52c6fef3b450417.tar.gz
tk-35d2c42c649984e5ba5d5b31d52c6fef3b450417.tar.bz2
Simultaneously with the previous commit Christian Gollwitzer provided
this more complete patch that deals with *.* and compilation problems with gcc.
-rw-r--r--macosx/tkMacOSXDialog.c170
1 files changed, 113 insertions, 57 deletions
diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c
index 97a282d..96b1e0b 100644
--- a/macosx/tkMacOSXDialog.c
+++ b/macosx/tkMacOSXDialog.c
@@ -31,11 +31,16 @@ 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
+ NSMutableArray *fileTypeAllowsAll; // boolean if the all pattern (*.*) is included
+
+ NSMutableArray *allowedExtensions; // set of all allowed extensions
+ bool allowedExtensionsAllowAll; // set of all allowed extensions includes *.*
+
+ NSUInteger fileTypeIndex; // index of currently selected filter
} filepanelFilterInfo;
filepanelFilterInfo filterInfo;
@@ -268,34 +273,37 @@ static NSURL *getFileURL(NSString *directory, NSString *filename) {
}
- (void)selectFormat:(id)sender {
- NSPopUpButton *button = (NSPopUpButton *)sender;
- filterInfo.fileTypeIndex = [button indexOfSelectedItem];
-#ifdef __clang__
- NSMutableArray *allowedtypes = filterInfo.fileTypeExtensions[filterInfo.fileTypeIndex];
-#else
- NSMutableArray *allowedtypes = nil;
-#endif
- if (allowedtypes && [allowedtypes count] > 0) {
- [openpanel setAllowedFileTypes:allowedtypes];
- } else {
+ NSPopUpButton *button = (NSPopUpButton *)sender;
+ filterInfo.fileTypeIndex = [button indexOfSelectedItem];
+
+ if ([[filterInfo.fileTypeAllowsAll objectAtIndex:filterInfo.fileTypeIndex] boolValue]) {
+ [openpanel setAllowsOtherFileTypes:YES];
+ /* setAllowsOtherFileTypes might have no effect; it's inherited from the
+ * NSSavePanel, where it has the effect that it does not append an extension
+ * Setting the allowed file types to nil allows selecting any file */
[openpanel setAllowedFileTypes:nil];
+ } else {
+ NSMutableArray *allowedtypes = [filterInfo.fileTypeExtensions objectAtIndex:filterInfo.fileTypeIndex];
+ [openpanel setAllowedFileTypes:allowedtypes];
+ [openpanel setAllowsOtherFileTypes:NO];
}
+
filterInfo.userHasSelectedFilter = true;
}
- (void)saveFormat:(id)sender {
- NSPopUpButton *button = (NSPopUpButton *)sender;
- filterInfo.fileTypeIndex = [button indexOfSelectedItem];
-#ifdef __clang__
- NSMutableArray *allowedtypes = filterInfo.fileTypeExtensions[filterInfo.fileTypeIndex];
-#else
- NSMutableArray *allowedtypes = nil;
-#endif
- if (allowedtypes && [allowedtypes count] > 0) {
- [savepanel setAllowedFileTypes:allowedtypes];
- } else {
+ NSPopUpButton *button = (NSPopUpButton *)sender;
+ filterInfo.fileTypeIndex = [button indexOfSelectedItem];
+
+ if ([[filterInfo.fileTypeAllowsAll objectAtIndex:filterInfo.fileTypeIndex] boolValue]) {
+ [savepanel setAllowsOtherFileTypes:YES];
[savepanel setAllowedFileTypes:nil];
+ } else {
+ NSMutableArray *allowedtypes = [filterInfo.fileTypeExtensions objectAtIndex:filterInfo.fileTypeIndex];
+ [savepanel setAllowedFileTypes:allowedtypes];
+ [savepanel setAllowsOtherFileTypes:NO];
}
+
filterInfo.userHasSelectedFilter = true;
}
@@ -435,7 +443,10 @@ int parseFileFilters(Tcl_Interp *interp, Tcl_Obj *fileTypesPtr, Tcl_Obj *typeVar
filterInfo.fileTypeExtensions = [NSMutableArray array];
filterInfo.fileTypeNames = [NSMutableArray array];
filterInfo.fileTypeLabels = [NSMutableArray array];
- filterInfo.allAllowedExtensions = [NSMutableArray array];
+ filterInfo.fileTypeAllowsAll = [NSMutableArray array];
+
+ filterInfo.allowedExtensions = [NSMutableArray array];
+ filterInfo.allowedExtensionsAllowAll = NO;
if (filterInfo.doFileTypes) {
for (FileFilter *filterPtr = fl.filters; filterPtr;
@@ -445,9 +456,11 @@ int parseFileFilters(Tcl_Interp *interp, Tcl_Obj *fileTypesPtr, Tcl_Obj *typeVar
[name release];
NSMutableArray * clauseextensions = [NSMutableArray array];
NSMutableArray * displayextensions = [NSMutableArray array];
+ bool allowsAll = NO;
for (FileFilterClause *clausePtr = filterPtr->clauses; clausePtr;
clausePtr = clausePtr->next) {
+
for (GlobPattern *globPtr = clausePtr->patterns; globPtr;
globPtr = globPtr->next) {
const char *str = globPtr->pattern;
@@ -456,18 +469,24 @@ int parseFileFilters(Tcl_Interp *interp, Tcl_Obj *fileTypesPtr, Tcl_Obj *typeVar
}
if (*str) {
NSString *extension = [[NSString alloc] initWithUTF8String:str];
- if (![filterInfo.allAllowedExtensions containsObject:extension]) {
- [filterInfo.allAllowedExtensions addObject:extension];
+ if (![filterInfo.allowedExtensions containsObject:extension]) {
+ [filterInfo.allowedExtensions addObject:extension];
}
[clauseextensions addObject:extension];
[displayextensions addObject:[@"." stringByAppendingString:extension]];
[extension release];
+ } else {
+ // it is the all pattern (*, .* or *.*)
+ allowsAll = YES;
+ filterInfo.allowedExtensionsAllowAll = YES;
+ [displayextensions addObject:@"*"];
}
}
}
[filterInfo.fileTypeExtensions addObject:clauseextensions];
+ [filterInfo.fileTypeAllowsAll addObject:[NSNumber numberWithBool:allowsAll]];
NSMutableString * label = [[NSMutableString alloc] initWithString:name];
[label appendString:@" ("];
@@ -504,6 +523,17 @@ int parseFileFilters(Tcl_Interp *interp, Tcl_Obj *fileTypesPtr, Tcl_Obj *typeVar
return TCL_OK;
}
+bool filterCompatible(NSString *extension, int filterIndex) {
+ NSMutableArray *allowedExtensions = [filterInfo.fileTypeExtensions objectAtIndex: filterIndex];
+
+ /* If this contains the all pattern, accept any extension */
+ if ([[filterInfo.fileTypeAllowsAll objectAtIndex:filterIndex] boolValue]) {
+ return true;
+ }
+
+ return [allowedExtensions containsObject: extension];
+}
+
/*
*----------------------------------------------------------------------
@@ -634,15 +664,15 @@ Tk_GetOpenFileObjCmd(
}
if (filterInfo.doFileTypes) {
- NSView *accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 200, 32.0)];
+ NSView *accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 300, 32.0)];
NSTextField *label = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 60, 22)];
[label setEditable:NO];
- [label setStringValue:@"Enable:"];
+ [label setStringValue:@"Filter:"];
[label setBordered:NO];
[label setBezeled:NO];
[label setDrawsBackground:NO];
- NSPopUpButton *popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 140, 22.0) pullsDown:NO];
+ NSPopUpButton *popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 240, 22.0) pullsDown:NO];
[popupButton addItemsWithTitles:filterInfo.fileTypeLabels];
[popupButton setAction:@selector(selectFormat:)];
@@ -656,12 +686,16 @@ Tk_GetOpenFileObjCmd(
/* 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];
+ [openpanel setAllowedFileTypes:filterInfo.allowedExtensions];
} else {
- [openpanel setAllowedFileTypes:filterInfo.allAllowedExtensions];
+ [openpanel setAllowedFileTypes:filterInfo.allowedExtensions];
}
- [openpanel setAllowsOtherFileTypes:NO];
+ if (filterInfo.allowedExtensionsAllowAll) {
+ [openpanel setAllowsOtherFileTypes:YES];
+ } else {
+ [openpanel setAllowsOtherFileTypes:NO];
+ }
[openpanel setAccessoryView:accessoryView];
} else {
@@ -726,18 +760,52 @@ Tk_GetOpenFileObjCmd(
}
if ((typeVariablePtr && (modalReturnCode == NSOKButton)) &&
- filterInfo.doFileTypes && filterInfo.userHasSelectedFilter) {
+ 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
- #ifdef __clang__
- NSString * selectedFilter = filterInfo.fileTypeNames[filterInfo.fileTypeIndex];
- #else
- NSString * selectedFilter = [NSString string];
- #endif
+ NSInteger selectedFilterIndex = filterInfo.fileTypeIndex;
+ NSString *selectedFilter = NULL;
+ if (filterInfo.userHasSelectedFilter) {
+ selectedFilterIndex = filterInfo.fileTypeIndex;
+ selectedFilter = [filterInfo.fileTypeNames objectAtIndex:selectedFilterIndex];
+ } else {
+ /* Difficult case: the user has not touched the filter settings, but we must
+ * return something in the typevariable. First check if the preselected type is compatible
+ * with the selected file, otherwise choose the first compatible type from the list,
+ * finally fall back to the empty string */
+ NSURL *selectedFile;
+ if (multiple) {
+ // Use the first file in the case of multiple selection
+ // Anyway it is not overly useful here
+ selectedFile = [[openpanel URLs] objectAtIndex:0];
+ } else {
+ selectedFile = [openpanel URL];
+ }
+
+ NSString *extension = [selectedFile pathExtension];
+ if (filterInfo.preselectFilter &&
+ filterCompatible(extension, filterInfo.fileTypeIndex)) {
+ selectedFilterIndex = filterInfo.fileTypeIndex; // The preselection from the typevariable
+ selectedFilter = [filterInfo.fileTypeNames objectAtIndex:selectedFilterIndex];
+ } else {
+ // scan the list
+ int i;
+ for (i = 0; i < [filterInfo.fileTypeNames count]; i++) {
+ if (filterCompatible(extension, i)) {
+ selectedFilterIndex = i;
+ break;
+ }
+ }
+ if (i == selectedFilterIndex) {
+ selectedFilter = [filterInfo.fileTypeNames objectAtIndex:selectedFilterIndex];
+ } else {
+ selectedFilter = @"";
+ }
+
+ }
+ }
+
Tcl_ObjSetVar2(interp, typeVariablePtr, NULL,
Tcl_NewStringObj([selectedFilter UTF8String], -1), TCL_GLOBAL_ONLY);
}
@@ -886,7 +954,7 @@ Tk_GetSaveFileObjCmd(
}
if (filterInfo.doFileTypes) {
- NSView *accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 200, 32.0)];
+ NSView *accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 300, 32.0)];
NSTextField *label = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 60, 22)];
[label setEditable:NO];
[label setStringValue:NSLocalizedString(@"Format:", nil)];
@@ -894,7 +962,7 @@ Tk_GetSaveFileObjCmd(
[label setBezeled:NO];
[label setDrawsBackground:NO];
- NSPopUpButton *popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 140, 22.0) pullsDown:NO];
+ NSPopUpButton *popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 340, 22.0) pullsDown:NO];
[popupButton addItemsWithTitles:filterInfo.fileTypeLabels];
[popupButton selectItemAtIndex:filterInfo.fileTypeIndex];
[popupButton setAction:@selector(saveFormat:)];
@@ -904,10 +972,8 @@ Tk_GetSaveFileObjCmd(
[savepanel setAccessoryView:accessoryView];
- #ifdef __clang__
- [savepanel setAllowedFileTypes:filterInfo.fileTypeExtensions[filterInfo.fileTypeIndex]];
- [savepanel setAllowsOtherFileTypes:NO];
- #endif
+ [savepanel setAllowedFileTypes:[filterInfo.fileTypeExtensions objectAtIndex:filterInfo.fileTypeIndex]];
+ [savepanel setAllowsOtherFileTypes:filterInfo.allowedExtensionsAllowAll];
} else if (defaultType) {
/* If no filetypes are given, defaultextension is an alternative way
* to specify the attached extension. Just propose this extension,
@@ -974,9 +1040,6 @@ Tk_GetSaveFileObjCmd(
[savepanel setNameFieldStringValue:@""];
}
modalReturnCode = [savepanel runModal];
- #if 0
- NSLog(@"modal: %li", modalReturnCode);
- #endif
#endif
[NSApp tkFilePanelDidEnd:savepanel returnCode:modalReturnCode
contextInfo:callbackInfo];
@@ -990,14 +1053,7 @@ Tk_GetSaveFileObjCmd(
/*
* 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
- #ifdef __clang__
- NSString * selectedFilter = filterInfo.fileTypeNames[filterInfo.fileTypeIndex];
- #else
- NSString * selectedFilter = [NSString string];
- #endif
+ NSString * selectedFilter = [filterInfo.fileTypeNames objectAtIndex:filterInfo.fileTypeIndex];
Tcl_ObjSetVar2(interp, typeVariablePtr, NULL,
Tcl_NewStringObj([selectedFilter UTF8String], -1), TCL_GLOBAL_ONLY);
}