summaryrefslogtreecommitdiffstats
path: root/macosx
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
parent452ee6a6849e04a6a94bc7488e935129614041f8 (diff)
parentfd3fd3d844d9ff5f83c3fd26ee88f2c02892c180 (diff)
downloadtk-fbac4859a673c9a5f0c8936ed8d18ea9e9145304.zip
tk-fbac4859a673c9a5f0c8936ed8d18ea9e9145304.tar.gz
tk-fbac4859a673c9a5f0c8936ed8d18ea9e9145304.tar.bz2
merge trunk
Diffstat (limited to 'macosx')
-rw-r--r--macosx/tkMacOSXDialog.c555
-rw-r--r--macosx/tkMacOSXFont.c2
-rw-r--r--macosx/tkMacOSXScrlbr.c81
-rw-r--r--macosx/tkMacOSXWm.c5
-rw-r--r--macosx/tkMacOSXWm.h4
-rw-r--r--macosx/tkMacOSXXStubs.c6
6 files changed, 432 insertions, 221 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
diff --git a/macosx/tkMacOSXFont.c b/macosx/tkMacOSXFont.c
index b5ae1a3..fd4c19a 100644
--- a/macosx/tkMacOSXFont.c
+++ b/macosx/tkMacOSXFont.c
@@ -515,7 +515,7 @@ TkpGetFontFromAttributes(
/* Set of attributes to match. */
{
MacFont *fontPtr;
- int points = TkFontGetPoints(tkwin, faPtr->size);
+ int points = (int)(TkFontGetPoints(tkwin, faPtr->size) + 0.5);
NSFontTraitMask traits = GetNSFontTraitsFromTkFontAttributes(faPtr);
NSInteger weight = (faPtr->weight == TK_FW_BOLD ? 9 : 5);
NSFont *nsFont;
diff --git a/macosx/tkMacOSXScrlbr.c b/macosx/tkMacOSXScrlbr.c
index 91cf112..49ba999 100644
--- a/macosx/tkMacOSXScrlbr.c
+++ b/macosx/tkMacOSXScrlbr.c
@@ -19,6 +19,13 @@
#define MIN_SCROLLBAR_VALUE 0
+/*
+ * Minimum slider length, in pixels (designed to make sure that the slider is
+ * always easy to grab with the mouse).
+ */
+
+#define MIN_SLIDER_LENGTH 5
+
/*Borrowed from ttkMacOSXTheme.c to provide appropriate scaling of scrollbar values.*/
#ifdef __LP64__
#define RangeToFactor(maximum) (((double) (INT_MAX >> 1)) / (maximum))
@@ -60,16 +67,14 @@ typedef struct ScrollbarMetrics {
} ScrollbarMetrics;
static ScrollbarMetrics metrics[2] = {
- {15, 54, 26, 14, 14, NSRegularControlSize}, /* kThemeScrollBarMedium */
- {11, 40, 20, 10, 10, NSSmallControlSize}, /* kThemeScrollBarSmall */
+ {15, 54, 26, 14, 14, kControlSizeNormal}, /* kThemeScrollBarMedium */
+ {11, 40, 20, 10, 10, kControlSizeSmall}, /* kThemeScrollBarSmall */
};
-
HIThemeTrackDrawInfo info = {
.version = 0,
.min = 0.0,
.max = 100.0,
.attributes = kThemeTrackShowThumb,
- .kind = kThemeScrollBarMedium,
};
@@ -107,7 +112,7 @@ TkpCreateScrollbar(
scrollPtr->troughGC = None;
scrollPtr->copyGC = None;
- Tk_CreateEventHandler(tkwin,ExposureMask|StructureNotifyMask|FocusChangeMask|ButtonPressMask|VisibilityChangeMask, ScrollbarEventProc, scrollPtr);
+ Tk_CreateEventHandler(tkwin,ExposureMask|StructureNotifyMask|FocusChangeMask|ButtonPressMask|ButtonReleaseMask|EnterWindowMask|LeaveWindowMask|VisibilityChangeMask, ScrollbarEventProc, scrollPtr);
return (TkScrollbar *) scrollPtr;
}
@@ -212,7 +217,8 @@ TkpDisplayScrollbar(
*----------------------------------------------------------------------
*/
-extern void
+
+ extern void
TkpComputeScrollbarGeometry(
register TkScrollbar *scrollPtr)
/* Scrollbar whose geometry may have
@@ -259,14 +265,12 @@ TkpComputeScrollbarGeometry(
if (scrollPtr->sliderLast > fieldLength) {
scrollPtr->sliderLast = fieldLength;
}
- if (!(MOUNTAIN_LION_STYLE)) {
- scrollPtr->sliderFirst += scrollPtr->inset +
- metrics[variant].topArrowHeight;
- scrollPtr->sliderLast += scrollPtr->inset +
- metrics[variant].bottomArrowHeight;
- }
- /*
- * Register the desired geometry for the window (leave enough space
+
+ scrollPtr->sliderFirst += scrollPtr->arrowLength + scrollPtr->inset;
+ scrollPtr->sliderLast += scrollPtr->arrowLength + scrollPtr->inset;
+
+
+ /* Register the desired geometry for the window (leave enough space
* for the two arrows plus a minimum-size slider, plus border around
* the whole window, if any). Then arrange for the window to be
* redisplayed.
@@ -281,6 +285,9 @@ TkpComputeScrollbarGeometry(
}
+
+
+
/*
*----------------------------------------------------------------------
*
@@ -376,21 +383,22 @@ TkpScrollbarPosition(
register const int arrowSize = scrollPtr->arrowLength + inset;
if (scrollPtr->vertical) {
- length = Tk_Height(scrollPtr->tkwin);
- fieldlength = length - 2 * arrowSize;
- width = Tk_Width(scrollPtr->tkwin);
+ length = Tk_Height(scrollPtr->tkwin);
+ fieldlength = length - 2 * arrowSize;
+ width = Tk_Width(scrollPtr->tkwin);
} else {
- tmp = x;
- x = y;
- y = tmp;
- length = Tk_Width(scrollPtr->tkwin);
- fieldlength = length - 2 * arrowSize;
- width = Tk_Height(scrollPtr->tkwin);
+ tmp = x;
+ x = y;
+ y = tmp;
+ length = Tk_Width(scrollPtr->tkwin);
+ fieldlength = length - 2 * arrowSize;
+ width = Tk_Height(scrollPtr->tkwin);
}
+
fieldlength = fieldlength < 0 ? 0 : fieldlength;
if (x<inset || x>=width-inset || y<inset || y>=length-inset) {
- return OUTSIDE;
+ return OUTSIDE;
}
/*
@@ -399,18 +407,19 @@ TkpScrollbarPosition(
*/
if (y < scrollPtr->sliderFirst) {
- return TOP_GAP;
+ return TOP_GAP;
}
if (y < scrollPtr->sliderLast) {
- return SLIDER;
+ return SLIDER;
}
if (y < fieldlength){
- return BOTTOM_GAP;
+ return BOTTOM_GAP;
}
if (y < fieldlength + arrowSize) {
- return TOP_ARROW;
+ return TOP_ARROW;
}
return BOTTOM_ARROW;
+
}
/*
@@ -458,7 +467,7 @@ UpdateControlValues(
width = contrlRect.size.width;
height = contrlRect.size.height;
- variant = contrlRect.size.width < metrics[0].width ? 1 : 0;
+ variant = contrlRect.size.width < metrics[0].width ? 1 : 0;
/*
* Ensure we set scrollbar control bounds only once all size adjustments
@@ -514,8 +523,8 @@ UpdateControlValues(
*
* ScrollbarPress --
*
- * This procedure is invoked in response to <ButtonPress> events.
- * Enters a modal loop to handle scrollbar interactions.
+ * This procedure is invoked in response to <ButtonPress>, <ButtonRelease>,
+ * <EnterNotify>, and <LeaveNotify> events. Scrollbar appearance is modified.
*
*--------------------------------------------------------------
*/
@@ -526,6 +535,13 @@ ScrollbarPress(TkScrollbar *scrollPtr, XEvent *eventPtr)
if (eventPtr->type == ButtonPress) {
UpdateControlValues(scrollPtr);
+ info.trackInfo.scrollbar.pressState = 1;
+ }
+ if (eventPtr->type == EnterNotify) {
+ info.trackInfo.scrollbar.pressState = 1;
+ }
+ if (eventPtr->type == ButtonRelease || eventPtr->type == LeaveNotify) {
+ info.trackInfo.scrollbar.pressState = 0;
}
return TCL_OK;
}
@@ -566,6 +582,9 @@ ScrollbarEventProc(
TkScrollbarEventuallyRedraw(scrollPtr);
break;
case ButtonPress:
+ case ButtonRelease:
+ case EnterNotify:
+ case LeaveNotify:
ScrollbarPress(clientData, eventPtr);
break;
default:
diff --git a/macosx/tkMacOSXWm.c b/macosx/tkMacOSXWm.c
index 39990e6..75473bf 100644
--- a/macosx/tkMacOSXWm.c
+++ b/macosx/tkMacOSXWm.c
@@ -2893,17 +2893,20 @@ WmProtocolCmd(
} else {
prevPtr->nextPtr = protPtr->nextPtr;
}
+ if (protPtr->command)
+ ckfree(protPtr->command);
Tcl_EventuallyFree(protPtr, TCL_DYNAMIC);
break;
}
}
cmd = Tcl_GetStringFromObj(objv[4], &cmdLength);
if (cmdLength > 0) {
- protPtr = ckalloc(HANDLER_SIZE(cmdLength));
+ protPtr = ckalloc(sizeof(ProtocolHandler));
protPtr->protocol = protocol;
protPtr->nextPtr = wmPtr->protPtr;
wmPtr->protPtr = protPtr;
protPtr->interp = interp;
+ protPtr->command = ckalloc(cmdLength+1);
strcpy(protPtr->command, cmd);
}
return TCL_OK;
diff --git a/macosx/tkMacOSXWm.h b/macosx/tkMacOSXWm.h
index 0a128ef..e904f50 100644
--- a/macosx/tkMacOSXWm.h
+++ b/macosx/tkMacOSXWm.h
@@ -29,15 +29,13 @@ typedef struct ProtocolHandler {
* same top-level window, or NULL for end of
* list. */
Tcl_Interp *interp; /* Interpreter in which to invoke command. */
- char command[]; /* Tcl command to invoke when a client message
+ char* command; /* Tcl command to invoke when a client message
* for this protocol arrives. The actual size
* of the structure varies to accommodate the
* needs of the actual command. THIS MUST BE
* THE LAST FIELD OF THE STRUCTURE. */
} ProtocolHandler;
-#define HANDLER_SIZE(cmdLength) \
-((unsigned) (sizeof(ProtocolHandler) + cmdLength + 1))
/*
* A data structure of the following type holds window-manager-related
diff --git a/macosx/tkMacOSXXStubs.c b/macosx/tkMacOSXXStubs.c
index 2251b8f..004ac1b 100644
--- a/macosx/tkMacOSXXStubs.c
+++ b/macosx/tkMacOSXXStubs.c
@@ -882,16 +882,18 @@ XGetImage(
int bitmap_pad = 0;
int bytes_per_row = 4*width;
int size;
- MacDrawable *macDraw = (MacDrawable *) d;
+ MacDrawable *macDraw = (MacDrawable *) d; // Where is this variable used? May it be removed?
+ int scalefactor = 1;
+#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
NSWindow *win = TkMacOSXDrawableWindow(d);
/* This code assumes that backing scale factors are integers. Currently
* Retina displays use a scale factor of 2.0 and normal displays use 1.0.
* We do not support any other values here.
*/
- int scalefactor = 1;
if (win && [win respondsToSelector:@selector(backingScaleFactor)]) {
scalefactor = ([win backingScaleFactor] == 2.0) ? 2 : 1;
}
+#endif
int scaled_height = height * scalefactor;
int scaled_width = width * scalefactor;