diff options
author | culler <culler> | 2017-11-25 21:08:45 (GMT) |
---|---|---|
committer | culler <culler> | 2017-11-25 21:08:45 (GMT) |
commit | 35d2c42c649984e5ba5d5b31d52c6fef3b450417 (patch) | |
tree | 13164dd0d1579b6fa396a6e5d08ab30667dcb22f | |
parent | 945ce561d3f680c8fea5981211b8afd2a2dc255d (diff) | |
download | tk-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.c | 170 |
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); } |