diff options
author | William Joye <wjoye@cfa.harvard.edu> | 2018-01-02 20:34:49 (GMT) |
---|---|---|
committer | William Joye <wjoye@cfa.harvard.edu> | 2018-01-02 20:34:49 (GMT) |
commit | 89c1ac99d375fbd73892aa659f06ef5e2c5ea56e (patch) | |
tree | e76ce80d68d11f1ea137bc33a42f71a1d1f32028 /tk8.6/macosx/tkMacOSXDialog.c | |
parent | 01e4cd2ef2ff59418766b2259fbc99771646aba6 (diff) | |
download | blt-89c1ac99d375fbd73892aa659f06ef5e2c5ea56e.zip blt-89c1ac99d375fbd73892aa659f06ef5e2c5ea56e.tar.gz blt-89c1ac99d375fbd73892aa659f06ef5e2c5ea56e.tar.bz2 |
upgrade to tcl/tk 8.6.8
Diffstat (limited to 'tk8.6/macosx/tkMacOSXDialog.c')
-rw-r--r-- | tk8.6/macosx/tkMacOSXDialog.c | 1996 |
1 files changed, 0 insertions, 1996 deletions
diff --git a/tk8.6/macosx/tkMacOSXDialog.c b/tk8.6/macosx/tkMacOSXDialog.c deleted file mode 100644 index 3bcbf1f..0000000 --- a/tk8.6/macosx/tkMacOSXDialog.c +++ /dev/null @@ -1,1996 +0,0 @@ -/* - * tkMacOSXDialog.c -- - * - * Contains the Mac implementation of the common dialog boxes. - * - * 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. - */ - -#include "tkMacOSXPrivate.h" -#include "tkFileFilter.h" -#include "tkMacOSXConstants.h" - -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1090 -#define modalOK NSOKButton -#define modalCancel NSCancelButton -#else -#define modalOK NSModalResponseOK -#define modalCancel NSModalResponseCancel -#endif -#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 -}; -enum colorOptions { - COLOR_INITIAL, COLOR_PARENT, COLOR_TITLE -}; - -static const char *const openOptionStrings[] = { - "-defaultextension", "-filetypes", "-initialdir", "-initialfile", - "-message", "-multiple", "-parent", "-title", "-typevariable", - "-command", NULL -}; -enum openOptions { - OPEN_DEFAULT, OPEN_FILETYPES, OPEN_INITDIR, OPEN_INITFILE, - OPEN_MESSAGE, OPEN_MULTIPLE, OPEN_PARENT, OPEN_TITLE, - OPEN_TYPEVARIABLE, OPEN_COMMAND, -}; -static const char *const saveOptionStrings[] = { - "-defaultextension", "-filetypes", "-initialdir", "-initialfile", - "-message", "-parent", "-title", "-typevariable", "-command", - "-confirmoverwrite", NULL -}; -enum saveOptions { - SAVE_DEFAULT, SAVE_FILETYPES, SAVE_INITDIR, SAVE_INITFILE, - SAVE_MESSAGE, SAVE_PARENT, SAVE_TITLE, SAVE_TYPEVARIABLE, SAVE_COMMAND, - SAVE_CONFIRMOW -}; -static const char *const chooseOptionStrings[] = { - "-initialdir", "-message", "-mustexist", "-parent", "-title", "-command", - NULL -}; -enum chooseOptions { - CHOOSE_INITDIR, CHOOSE_MESSAGE, CHOOSE_MUSTEXIST, CHOOSE_PARENT, - CHOOSE_TITLE, CHOOSE_COMMAND, -}; -typedef struct { - Tcl_Interp *interp; - Tcl_Obj *cmdObj; - int multiple; -} FilePanelCallbackInfo; - -static const char *const alertOptionStrings[] = { - "-default", "-detail", "-icon", "-message", "-parent", "-title", - "-type", "-command", NULL -}; -enum alertOptions { - ALERT_DEFAULT, ALERT_DETAIL, ALERT_ICON, ALERT_MESSAGE, ALERT_PARENT, - ALERT_TITLE, ALERT_TYPE, ALERT_COMMAND, -}; -typedef struct { - Tcl_Interp *interp; - Tcl_Obj *cmdObj; - int typeIndex; -} AlertCallbackInfo; -static const char *const alertTypeStrings[] = { - "abortretryignore", "ok", "okcancel", "retrycancel", "yesno", - "yesnocancel", NULL -}; -enum alertTypeOptions { - TYPE_ABORTRETRYIGNORE, TYPE_OK, TYPE_OKCANCEL, TYPE_RETRYCANCEL, - TYPE_YESNO, TYPE_YESNOCANCEL -}; -static const char *const alertIconStrings[] = { - "error", "info", "question", "warning", NULL -}; -enum alertIconOptions { - ICON_ERROR, ICON_INFO, ICON_QUESTION, ICON_WARNING -}; -static const char *const alertButtonStrings[] = { - "abort", "retry", "ignore", "ok", "cancel", "yes", "no", NULL -}; - -static const NSString *const alertButtonNames[][3] = { - [TYPE_ABORTRETRYIGNORE] = {@"Abort", @"Retry", @"Ignore"}, - [TYPE_OK] = {@"OK"}, - [TYPE_OKCANCEL] = {@"OK", @"Cancel"}, - [TYPE_RETRYCANCEL] = {@"Retry", @"Cancel"}, - [TYPE_YESNO] = {@"Yes", @"No"}, - [TYPE_YESNOCANCEL] = {@"Yes", @"No", @"Cancel"}, -}; -static const NSAlertStyle alertStyles[] = { - [ICON_ERROR] = NSWarningAlertStyle, - [ICON_INFO] = NSInformationalAlertStyle, - [ICON_QUESTION] = NSWarningAlertStyle, - [ICON_WARNING] = NSCriticalAlertStyle, -}; - -/* - * Need to map from 'alertButtonStrings' and its corresponding integer, index - * to the native button index, which is 1, 2, 3, from right to left. This is - * necessary to do for each separate '-type' of button sets. - */ - -static const short alertButtonIndexAndTypeToNativeButtonIndex[][7] = { - /* abort retry ignore ok cancel yes no */ - [TYPE_ABORTRETRYIGNORE] = {1, 2, 3, 0, 0, 0, 0}, - [TYPE_OK] = {0, 0, 0, 1, 0, 0, 0}, - [TYPE_OKCANCEL] = {0, 0, 0, 1, 2, 0, 0}, - [TYPE_RETRYCANCEL] = {0, 1, 0, 0, 2, 0, 0}, - [TYPE_YESNO] = {0, 0, 0, 0, 0, 1, 2}, - [TYPE_YESNOCANCEL] = {0, 0, 0, 0, 3, 1, 2}, -}; - -/* - * Need also the inverse mapping, from NSAlertFirstButtonReturn etc to the - * descriptive button text string index. - */ - -static const short alertNativeButtonIndexAndTypeToButtonIndex[][3] = { - [TYPE_ABORTRETRYIGNORE] = {0, 1, 2}, - [TYPE_OK] = {3, 0, 0}, - [TYPE_OKCANCEL] = {3, 4, 0}, - [TYPE_RETRYCANCEL] = {1, 4, 0}, - [TYPE_YESNO] = {5, 6, 0}, - [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 isDirectory:YES]; - } - if (filename) { - url = [NSURL URLWithString:filename relativeToURL:url]; - } - return url; -} -#endif - -#pragma mark TKApplication(TKDialog) - -@interface NSColorPanel(TKDialog) -- (void) _setUseModalAppearance: (BOOL) flag; -@end - -@implementation TKApplication(TKDialog) - -- (void) tkFilePanelDidEnd: (NSSavePanel *) panel - returnCode: (NSInteger) returnCode contextInfo: (void *) contextInfo -{ - FilePanelCallbackInfo *callbackInfo = contextInfo; - - if (returnCode == modalOK) { - Tcl_Obj *resultObj; - - if (callbackInfo->multiple) { - resultObj = Tcl_NewListObj(0, NULL); - for (NSURL *url in [(NSOpenPanel*)panel URLs]) { - Tcl_ListObjAppendElement(callbackInfo->interp, resultObj, - Tcl_NewStringObj([[url path] UTF8String], -1)); - } - } else { - resultObj = Tcl_NewStringObj([[[panel URL]path] UTF8String], -1); - } - if (callbackInfo->cmdObj) { - Tcl_Obj **objv, **tmpv; - int objc, result = Tcl_ListObjGetElements(callbackInfo->interp, - callbackInfo->cmdObj, &objc, &objv); - - if (result == TCL_OK && objc) { - tmpv = ckalloc(sizeof(Tcl_Obj *) * (objc + 2)); - memcpy(tmpv, objv, sizeof(Tcl_Obj *) * objc); - tmpv[objc] = resultObj; - TkBackgroundEvalObjv(callbackInfo->interp, objc + 1, tmpv, - TCL_EVAL_GLOBAL); - ckfree(tmpv); - } - } else { - Tcl_SetObjResult(callbackInfo->interp, resultObj); - } - } else if (returnCode == modalCancel) { - Tcl_ResetResult(callbackInfo->interp); - } - if (panel == [NSApp modalWindow]) { - [NSApp stopModalWithCode:returnCode]; - } - if (callbackInfo->cmdObj) { - Tcl_DecrRefCount(callbackInfo->cmdObj); - ckfree(callbackInfo); - } -} - - -- (void) tkAlertDidEnd: (NSAlert *) alert returnCode: (NSInteger) returnCode - contextInfo: (void *) contextInfo -{ - AlertCallbackInfo *callbackInfo = contextInfo; - - if (returnCode >= NSAlertFirstButtonReturn) { - Tcl_Obj *resultObj = Tcl_NewStringObj(alertButtonStrings[ - alertNativeButtonIndexAndTypeToButtonIndex[callbackInfo-> - typeIndex][returnCode - NSAlertFirstButtonReturn]], -1); - - if (callbackInfo->cmdObj) { - Tcl_Obj **objv, **tmpv; - int objc, result = Tcl_ListObjGetElements(callbackInfo->interp, - callbackInfo->cmdObj, &objc, &objv); - - if (result == TCL_OK && objc) { - tmpv = ckalloc(sizeof(Tcl_Obj *) * (objc + 2)); - memcpy(tmpv, objv, sizeof(Tcl_Obj *) * objc); - tmpv[objc] = resultObj; - TkBackgroundEvalObjv(callbackInfo->interp, objc + 1, tmpv, - TCL_EVAL_GLOBAL); - ckfree(tmpv); - } - } else { - Tcl_SetObjResult(callbackInfo->interp, resultObj); - } - } - if ([alert window] == [NSApp modalWindow]) { - [NSApp stopModalWithCode:returnCode]; - } - if (callbackInfo->cmdObj) { - Tcl_DecrRefCount(callbackInfo->cmdObj); - 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 - - -/* - *---------------------------------------------------------------------- - * - * Tk_ChooseColorObjCmd -- - * - * This procedure implements the color dialog box for the Mac platform. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -int -Tk_ChooseColorObjCmd( - ClientData clientData, /* Main window associated with interpreter. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - int result = TCL_ERROR; - Tk_Window parent, tkwin = clientData; - const char *title = NULL; - int i; - NSColor *color = nil, *initialColor = nil; - NSColorPanel *colorPanel; - NSInteger returnCode, numberOfComponents = 0; - - for (i = 1; i < objc; i += 2) { - int index; - const char *value; - - if (Tcl_GetIndexFromObjStruct(interp, objv[i], colorOptionStrings, - sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) { - goto end; - } - if (i + 1 == objc) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "value for \"%s\" missing", Tcl_GetString(objv[i]))); - Tcl_SetErrorCode(interp, "TK", "COLORDIALOG", "VALUE", NULL); - goto end; - } - value = Tcl_GetString(objv[i + 1]); - - switch (index) { - case COLOR_INITIAL: { - XColor *colorPtr; - - colorPtr = Tk_GetColor(interp, tkwin, value); - if (colorPtr == NULL) { - goto end; - } - initialColor = TkMacOSXGetNSColor(NULL, colorPtr->pixel); - Tk_FreeColor(colorPtr); - break; - } - case COLOR_PARENT: - parent = Tk_NameToWindow(interp, value, tkwin); - if (parent == NULL) { - goto end; - } - break; - case COLOR_TITLE: - title = value; - break; - } - } - colorPanel = [NSColorPanel sharedColorPanel]; - [colorPanel orderOut:NSApp]; - [colorPanel setContinuous:NO]; - [colorPanel setBecomesKeyOnlyIfNeeded:NO]; - [colorPanel setShowsAlpha: NO]; - [colorPanel _setUseModalAppearance:YES]; - if (title) { - NSString *s = [[NSString alloc] initWithUTF8String:title]; - [colorPanel setTitle:s]; - [s release]; - } - if (initialColor) { - [colorPanel setColor:initialColor]; - } - returnCode = [NSApp runModalForWindow:colorPanel]; - if (returnCode == modalOK) { - color = [[colorPanel color] colorUsingColorSpace: - [NSColorSpace deviceRGBColorSpace]]; - numberOfComponents = [color numberOfComponents]; - } - if (color && numberOfComponents >= 3 && numberOfComponents <= 4) { - CGFloat components[4]; - char colorstr[8]; - - [color getComponents:components]; - snprintf(colorstr, 8, "#%02x%02x%02x", - (short)(components[0] * 255), - (short)(components[1] * 255), - (short)(components[2] * 255)); - Tcl_SetObjResult(interp, Tcl_NewStringObj(colorstr, 7)); - } else { - Tcl_ResetResult(interp); - } - result = TCL_OK; - -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; -} - - -/* - *---------------------------------------------------------------------- - * - * Tk_GetOpenFileObjCmd -- - * - * This procedure implements the "open file" dialog box for the Mac - * platform. See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See user documentation. - *---------------------------------------------------------------------- - */ - -int -Tk_GetOpenFileObjCmd( - ClientData clientData, /* Main window associated with interpreter. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - Tk_Window tkwin = clientData; - char *str; - int i, result = TCL_ERROR, haveParentOption = 0; - int index, len, multiple = 0; - Tcl_Obj *cmdObj = NULL, *typeVariablePtr = NULL, *fileTypesPtr = NULL; - FilePanelCallbackInfo callbackInfoStruct; - FilePanelCallbackInfo *callbackInfo = &callbackInfoStruct; - NSString *directory = nil, *filename = nil; - NSString *message = nil, *title = nil; - NSWindow *parent; - openpanel = [NSOpenPanel openPanel]; - NSInteger modalReturnCode = modalError; - BOOL parentIsKey = NO; - - for (i = 1; i < objc; i += 2) { - if (Tcl_GetIndexFromObjStruct(interp, objv[i], openOptionStrings, - sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) { - goto end; - } - if (i + 1 == objc) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "value for \"%s\" missing", Tcl_GetString(objv[i]))); - Tcl_SetErrorCode(interp, "TK", "FILEDIALOG", "VALUE", NULL); - goto end; - } - switch (index) { - case OPEN_DEFAULT: - break; - case OPEN_FILETYPES: - fileTypesPtr = objv[i + 1]; - break; - case OPEN_INITDIR: - str = Tcl_GetStringFromObj(objv[i + 1], &len); - if (len) { - directory = [[[NSString alloc] initWithUTF8String:str] - autorelease]; - } - break; - case OPEN_INITFILE: - str = Tcl_GetStringFromObj(objv[i + 1], &len); - if (len) { - filename = [[[NSString alloc] initWithUTF8String:str] - autorelease]; - } - break; - case OPEN_MESSAGE: - message = [[NSString alloc] initWithUTF8String: - Tcl_GetString(objv[i + 1])]; - break; - case OPEN_MULTIPLE: - if (Tcl_GetBooleanFromObj(interp, objv[i + 1], - &multiple) != TCL_OK) { - goto end; - } - break; - case OPEN_PARENT: - str = Tcl_GetStringFromObj(objv[i + 1], &len); - tkwin = Tk_NameToWindow(interp, str, tkwin); - if (!tkwin) { - goto end; - } - haveParentOption = 1; - break; - case OPEN_TITLE: - title = [[NSString alloc] initWithUTF8String: - Tcl_GetString(objv[i + 1])]; - break; - case OPEN_TYPEVARIABLE: - typeVariablePtr = objv[i + 1]; - break; - case OPEN_COMMAND: - cmdObj = objv[i+1]; - break; - } - } - - if (title) { - [openpanel setTitle:title]; - - /* From OSX 10.11, the title string is silently ignored in the open panel. - * Prepend the title to the message in this case - * NOTE should be conditional on OSX version, but - * -mmacosx-version-min does not revert this behaviour*/ - - 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]; - } - - if (cmdObj) { - callbackInfo = ckalloc(sizeof(FilePanelCallbackInfo)); - if (Tcl_IsShared(cmdObj)) { - cmdObj = Tcl_DuplicateObj(cmdObj); - } - Tcl_IncrRefCount(cmdObj); - } - - callbackInfo->cmdObj = cmdObj; - callbackInfo->interp = interp; - callbackInfo->multiple = multiple; - parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window); - if (haveParentOption && parent && ![parent attachedSheet]) { - parentIsKey = [parent isKeyWindow]; -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - [openpanel beginSheetForDirectory:directory - file:filename - types:openFileTypes - modalForWindow:parent - modalDelegate:NSApp - didEndSelector: - @selector(tkFilePanelDidEnd:returnCode:contextInfo:) - contextInfo:callbackInfo]; -#else - if (directory || filename ) { - NSURL * fileURL = getFileURL(directory, filename); - [openpanel setDirectoryURL:fileURL]; - } - - [openpanel beginSheetModalForWindow:parent - completionHandler:^(NSInteger returnCode) - { [NSApp tkFilePanelDidEnd:openpanel - returnCode:returnCode - contextInfo:callbackInfo ]; } ]; -#endif - modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:openpanel]; - } else { -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - modalReturnCode = [openpanel runModalForDirectory:directory - file:filename]; -#else - if (directory || filename ) { - NSURL * fileURL = getFileURL(directory, filename); - [openpanel setDirectoryURL:fileURL]; - } - - modalReturnCode = [openpanel runModal]; -#endif - [NSApp tkFilePanelDidEnd:openpanel returnCode:modalReturnCode - contextInfo:callbackInfo]; - } - result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR; - if (parentIsKey) { - [parent makeKeyWindow]; - } - - if ((typeVariablePtr && (modalReturnCode == NSOKButton)) && - filterInfo.doFileTypes && filterInfo.userHasSelectedFilter) { - /* - * 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: - return result; -} - - -/* - *---------------------------------------------------------------------- - * - * Tk_GetSaveFileObjCmd -- - * - * This procedure implements the "save file" dialog box for the Mac - * platform. See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See user documentation. - *---------------------------------------------------------------------- - */ - -int -Tk_GetSaveFileObjCmd( - ClientData clientData, /* Main window associated with interpreter. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - Tk_Window tkwin = clientData; - char *str; - int i, result = TCL_ERROR, haveParentOption = 0; - int confirmOverwrite = 1; - int index, len; - Tcl_Obj *cmdObj = NULL, *typeVariablePtr = NULL, *fileTypesPtr = NULL; - FilePanelCallbackInfo callbackInfoStruct; - FilePanelCallbackInfo *callbackInfo = &callbackInfoStruct; - NSString *directory = nil, *filename = nil, *defaultType = nil; - NSString *message = nil, *title = nil; - NSWindow *parent; - savepanel = [NSSavePanel savePanel]; - NSInteger modalReturnCode = modalError; - BOOL parentIsKey = NO; - - for (i = 1; i < objc; i += 2) { - if (Tcl_GetIndexFromObjStruct(interp, objv[i], saveOptionStrings, - sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) { - goto end; - } - if (i + 1 == objc) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "value for \"%s\" missing", Tcl_GetString(objv[i]))); - Tcl_SetErrorCode(interp, "TK", "FILEDIALOG", "VALUE", NULL); - 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: - 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]; - - /* From OSX 10.11, the title string is silently ignored, if the save panel is a sheet. - * Prepend the title to the message in this case - * NOTE should be conditional on OSX version, but - * -mmacosx-version-min does not revert this behaviour*/ - if (haveParentOption) { - if (message) { - NSString *fullmessage = [[NSString alloc] initWithFormat:@"%@\n%@",title,message]; - [message release]; - [title release]; - message = fullmessage; - } else { - message = title; - } - } - } - - if (message) { - [savepanel setMessage:message]; - [message release]; - } - - 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: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)) { - cmdObj = Tcl_DuplicateObj(cmdObj); - } - Tcl_IncrRefCount(cmdObj); - } - 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 - [savepanel beginSheetForDirectory:directory - file:filename - modalForWindow:parent - modalDelegate:NSApp - didEndSelector: - @selector(tkFilePanelDidEnd:returnCode:contextInfo:) - contextInfo:callbackInfo]; -#else - if (directory) { - [savepanel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]]; - } - /*check for file name, otherwise set to empty string; crashes with uncaught exception if set to nil*/ - if (filename) { - [savepanel setNameFieldStringValue:filename]; - } else { - [savepanel setNameFieldStringValue:@""]; - } - [savepanel beginSheetModalForWindow:parent - completionHandler:^(NSInteger returnCode) - { [NSApp tkFilePanelDidEnd:savepanel - returnCode:returnCode - contextInfo:callbackInfo ]; } ]; -#endif - modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:savepanel]; - } else { -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - modalReturnCode = [savepanel runModalForDirectory:directory file:filename]; -#else - if (directory) { - [savepanel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]]; - } - /*check for file name, otherwise set to empty string; crashes with uncaught exception if set to nil*/ - if (filename) { - [savepanel setNameFieldStringValue:filename]; - } else { - [savepanel setNameFieldStringValue:@""]; - } - modalReturnCode = [savepanel runModal]; - #if 0 - NSLog(@"modal: %li", modalReturnCode); - #endif -#endif - [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: - return result; -} - -/* - *---------------------------------------------------------------------- - * - * Tk_ChooseDirectoryObjCmd -- - * - * This procedure implements the "tk_chooseDirectory" dialog box for the - * MacOS X platform. See the user documentation for details on what it - * does. - * - * Results: - * See user documentation. - * - * Side effects: - * A modal dialog window is created. - * - *---------------------------------------------------------------------- - */ - -int -Tk_ChooseDirectoryObjCmd( - ClientData clientData, /* Main window associated with interpreter. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - Tk_Window tkwin = clientData; - char *str; - int i, result = TCL_ERROR, haveParentOption = 0; - int index, len, mustexist = 0; - Tcl_Obj *cmdObj = NULL; - FilePanelCallbackInfo callbackInfoStruct; - FilePanelCallbackInfo *callbackInfo = &callbackInfoStruct; - NSString *directory = nil; - NSString *message, *title; - NSWindow *parent; - NSOpenPanel *panel = [NSOpenPanel openPanel]; - NSInteger modalReturnCode = modalError; - BOOL parentIsKey = NO; - - for (i = 1; i < objc; i += 2) { - if (Tcl_GetIndexFromObjStruct(interp, objv[i], chooseOptionStrings, - sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) { - goto end; - } - if (i + 1 == objc) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "value for \"%s\" missing", Tcl_GetString(objv[i]))); - Tcl_SetErrorCode(interp, "TK", "DIRDIALOG", "VALUE", NULL); - goto end; - } - switch (index) { - case CHOOSE_INITDIR: - str = Tcl_GetStringFromObj(objv[i + 1], &len); - if (len) { - directory = [[[NSString alloc] initWithUTF8String:str] - autorelease]; - } - break; - case CHOOSE_MESSAGE: - message = [[NSString alloc] initWithUTF8String: - Tcl_GetString(objv[i + 1])]; - [panel setMessage:message]; - [message release]; - break; - case CHOOSE_MUSTEXIST: - if (Tcl_GetBooleanFromObj(interp, objv[i + 1], - &mustexist) != TCL_OK) { - goto end; - } - break; - case CHOOSE_PARENT: - str = Tcl_GetStringFromObj(objv[i + 1], &len); - tkwin = Tk_NameToWindow(interp, str, tkwin); - if (!tkwin) { - goto end; - } - haveParentOption = 1; - break; - case CHOOSE_TITLE: - title = [[NSString alloc] initWithUTF8String: - Tcl_GetString(objv[i + 1])]; - [panel setTitle:title]; - [title release]; - break; - case CHOOSE_COMMAND: - cmdObj = objv[i+1]; - break; - } - } - [panel setPrompt:@"Choose"]; - [panel setCanChooseFiles:NO]; - [panel setCanChooseDirectories:YES]; - [panel setCanCreateDirectories:!mustexist]; - if (cmdObj) { - callbackInfo = ckalloc(sizeof(FilePanelCallbackInfo)); - if (Tcl_IsShared(cmdObj)) { - cmdObj = Tcl_DuplicateObj(cmdObj); - } - Tcl_IncrRefCount(cmdObj); - } - callbackInfo->cmdObj = cmdObj; - callbackInfo->interp = interp; - callbackInfo->multiple = 0; - /*check for directory value, set to root if not specified; otherwise crashes with exception because of nil string parameter*/ - if (!directory) { - directory = @"/"; - } - parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window); - if (haveParentOption && parent && ![parent attachedSheet]) { - parentIsKey = [parent isKeyWindow]; -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - [panel beginSheetForDirectory:directory - file:nil - modalForWindow:parent - modalDelegate:NSApp - didEndSelector: @selector(tkFilePanelDidEnd:returnCode:contextInfo:) - contextInfo:callbackInfo]; -#else - [panel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]]; - [panel beginSheetModalForWindow:parent - completionHandler:^(NSInteger returnCode) - { [NSApp tkFilePanelDidEnd:panel - returnCode:returnCode - contextInfo:callbackInfo ]; } ]; -#endif - modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:panel]; - } else { -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - modalReturnCode = [panel runModalForDirectory:directory file:nil]; -#else - [panel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]]; - modalReturnCode = [panel runModal]; -#endif - [NSApp tkFilePanelDidEnd:panel returnCode:modalReturnCode - contextInfo:callbackInfo]; - } - result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR; - if (parentIsKey) { - [parent makeKeyWindow]; - } - end: - return result; -} - -/* - *---------------------------------------------------------------------- - * - * TkAboutDlg -- - * - * Displays the default Tk About box. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -TkAboutDlg(void) -{ - NSImage *image; - NSString *path = [NSApp tkFrameworkImagePath: @"Tk.tiff"]; - - if (path) { - image = [[[NSImage alloc] initWithContentsOfFile:path] autorelease]; - } else { - image = [NSApp applicationIconImage]; - } - - NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; - - [dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4]; - [dateFormatter setDateFormat:@"Y"]; - - NSString *year = [dateFormatter stringFromDate:[NSDate date]]; - - [dateFormatter release]; - - NSMutableParagraphStyle *style = - [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] - autorelease]; - - [style setAlignment:NSCenterTextAlignment]; - - NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: - @"Tcl & Tk", @"ApplicationName", - @"Tcl " TCL_VERSION " & Tk " TK_VERSION, @"ApplicationVersion", - @TK_PATCH_LEVEL, @"Version", - image, @"ApplicationIcon", - [NSString stringWithFormat:@"Copyright %1$C 1987-%2$@.", 0xA9, - year], @"Copyright", - [[[NSAttributedString alloc] initWithString: - [NSString stringWithFormat: - @"%1$C 1987-%2$@ Tcl Core Team." "\n\n" - "%1$C 1989-%2$@ Contributors." "\n\n" - "%1$C 2011-%2$@ Kevin Walzer/WordTech Communications LLC." "\n\n" - "%1$C 2014-%2$@ Marc Culler." "\n\n" - "%1$C 2002-%2$@ Daniel A. Steffen." "\n\n" - "%1$C 2001-2009 Apple Inc." "\n\n" - "%1$C 2001-2002 Jim Ingham & Ian Reid" "\n\n" - "%1$C 1998-2000 Jim Ingham & Ray Johnson" "\n\n" - "%1$C 1998-2000 Scriptics Inc." "\n\n" - "%1$C 1996-1997 Sun Microsystems Inc.", 0xA9, year] attributes: - [NSDictionary dictionaryWithObject:style - forKey:NSParagraphStyleAttributeName]] autorelease], @"Credits", - nil]; - [NSApp orderFrontStandardAboutPanelWithOptions:options]; -} - -/* - *---------------------------------------------------------------------- - * - * TkMacOSXStandardAboutPanelObjCmd -- - * - * Implements the ::tk::mac::standardAboutPanel command. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * none - * - *---------------------------------------------------------------------- - */ - -int -TkMacOSXStandardAboutPanelObjCmd( - ClientData clientData, /* Unused. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - if (objc > 1) { - Tcl_WrongNumArgs(interp, 1, objv, NULL); - return TCL_ERROR; - } - [NSApp orderFrontStandardAboutPanelWithOptions:[NSDictionary dictionary]]; - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * Tk_MessageBoxObjCmd -- - * - * Implements the tk_messageBox in native Mac OS X style. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * none - * - *---------------------------------------------------------------------- - */ - -int -Tk_MessageBoxObjCmd( - ClientData clientData, /* Main window associated with interpreter. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - Tk_Window tkwin = clientData; - char *str; - int i, result = TCL_ERROR, haveParentOption = 0; - int index, typeIndex, iconIndex, indexDefaultOption = 0; - int defaultNativeButtonIndex = 1; /* 1, 2, 3: right to left */ - Tcl_Obj *cmdObj = NULL; - AlertCallbackInfo callbackInfoStruct, *callbackInfo = &callbackInfoStruct; - NSString *message, *title; - NSWindow *parent; - NSArray *buttons; - NSAlert *alert = [NSAlert new]; - NSInteger modalReturnCode = 1; - BOOL parentIsKey = NO; - - iconIndex = ICON_INFO; - typeIndex = TYPE_OK; - for (i = 1; i < objc; i += 2) { - if (Tcl_GetIndexFromObjStruct(interp, objv[i], alertOptionStrings, - sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) { - goto end; - } - if (i + 1 == objc) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "value for \"%s\" missing", Tcl_GetString(objv[i]))); - Tcl_SetErrorCode(interp, "TK", "MSGBOX", "VALUE", NULL); - goto end; - } - switch (index) { - case ALERT_DEFAULT: - /* - * Need to postpone processing of this option until we are sure to - * know the '-type' as well. - */ - - indexDefaultOption = i; - break; - - case ALERT_DETAIL: - message = [[NSString alloc] initWithUTF8String: - Tcl_GetString(objv[i + 1])]; - [alert setInformativeText:message]; - [message release]; - break; - - case ALERT_ICON: - if (Tcl_GetIndexFromObjStruct(interp, objv[i + 1], alertIconStrings, - sizeof(char *), "value", TCL_EXACT, &iconIndex) != TCL_OK) { - goto end; - } - break; - - case ALERT_MESSAGE: - message = [[NSString alloc] initWithUTF8String: - Tcl_GetString(objv[i + 1])]; - [alert setMessageText:message]; - [message release]; - break; - - case ALERT_PARENT: - str = Tcl_GetString(objv[i + 1]); - tkwin = Tk_NameToWindow(interp, str, tkwin); - if (!tkwin) { - goto end; - } - haveParentOption = 1; - break; - - case ALERT_TITLE: - title = [[NSString alloc] initWithUTF8String: - Tcl_GetString(objv[i + 1])]; - [[alert window] setTitle:title]; - [title release]; - break; - - case ALERT_TYPE: - if (Tcl_GetIndexFromObjStruct(interp, objv[i + 1], alertTypeStrings, - sizeof(char *), "value", TCL_EXACT, &typeIndex) != TCL_OK) { - goto end; - } - break; - case ALERT_COMMAND: - cmdObj = objv[i+1]; - break; - } - } - if (indexDefaultOption) { - /* - * Any '-default' option needs to know the '-type' option, which is - * why we do this here. - */ - - if (Tcl_GetIndexFromObjStruct(interp, objv[indexDefaultOption + 1], - alertButtonStrings, sizeof(char *), "value", TCL_EXACT, &index) != TCL_OK) { - goto end; - } - - /* - * Need to map from "ok" etc. to 1, 2, 3, right to left. - */ - - defaultNativeButtonIndex = - alertButtonIndexAndTypeToNativeButtonIndex[typeIndex][index]; - if (!defaultNativeButtonIndex) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("Illegal default option", -1)); - Tcl_SetErrorCode(interp, "TK", "MSGBOX", "DEFAULT", NULL); - goto end; - } - } - [alert setIcon:[NSApp applicationIconImage]]; - [alert setAlertStyle:alertStyles[iconIndex]]; - i = 0; - while (i < 3 && alertButtonNames[typeIndex][i]) { - [alert addButtonWithTitle:(NSString*)alertButtonNames[typeIndex][i++]]; - } - buttons = [alert buttons]; - for (NSButton *b in buttons) { - NSString *ke = [b keyEquivalent]; - - if (([ke isEqualToString:@"\r"] || [ke isEqualToString:@"\033"]) && - ![b keyEquivalentModifierMask]) { - [b setKeyEquivalent:@""]; - } - } - [[buttons objectAtIndex: [buttons count]-1] setKeyEquivalent: @"\033"]; - [[buttons objectAtIndex: defaultNativeButtonIndex-1] - setKeyEquivalent: @"\r"]; - if (cmdObj) { - callbackInfo = ckalloc(sizeof(AlertCallbackInfo)); - if (Tcl_IsShared(cmdObj)) { - cmdObj = Tcl_DuplicateObj(cmdObj); - } - Tcl_IncrRefCount(cmdObj); - } - callbackInfo->cmdObj = cmdObj; - callbackInfo->interp = interp; - callbackInfo->typeIndex = typeIndex; - parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window); - if (haveParentOption && parent && ![parent attachedSheet]) { - parentIsKey = [parent isKeyWindow]; -#if MAC_OS_X_VERSION_MIN_REQUIRED > 1090 - [alert beginSheetModalForWindow:parent - completionHandler:^(NSModalResponse returnCode) - { [NSApp tkAlertDidEnd:alert - returnCode:returnCode - contextInfo:callbackInfo ]; } ]; -#else - [alert beginSheetModalForWindow:parent - modalDelegate:NSApp - didEndSelector:@selector(tkAlertDidEnd:returnCode:contextInfo:) - contextInfo:callbackInfo]; -#endif - modalReturnCode = cmdObj ? 0 : - [NSApp runModalForWindow:[alert window]]; - } else { - modalReturnCode = [alert runModal]; - [NSApp tkAlertDidEnd:alert returnCode:modalReturnCode - contextInfo:callbackInfo]; - } - result = (modalReturnCode >= NSAlertFirstButtonReturn) ? TCL_OK : TCL_ERROR; - end: - [alert release]; - if (parentIsKey) { - [parent makeKeyWindow]; - } - return result; -} - -/* - *---------------------------------------------------------------------- - */ -#pragma mark [tk fontchooser] implementation (TIP 324) -/* - *---------------------------------------------------------------------- - */ - -#include "tkMacOSXEvent.h" -#include "tkMacOSXFont.h" - -typedef struct FontchooserData { - Tcl_Obj *titleObj; - Tcl_Obj *cmdObj; - Tk_Window parent; -} FontchooserData; - -enum FontchooserEvent { FontchooserClosed, FontchooserSelection }; - -static void FontchooserEvent(int kind); -static Tcl_Obj * FontchooserCget(FontchooserData *fcdPtr, - int optionIndex); -static int FontchooserConfigureCmd(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int FontchooserShowCmd(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int FontchooserHideCmd(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static void FontchooserParentEventHandler(ClientData clientData, - XEvent *eventPtr); -static void DeleteFontchooserData(ClientData clientData, - Tcl_Interp *interp); - -MODULE_SCOPE const TkEnsemble tkFontchooserEnsemble[]; -const TkEnsemble tkFontchooserEnsemble[] = { - { "configure", FontchooserConfigureCmd, NULL }, - { "show", FontchooserShowCmd, NULL }, - { "hide", FontchooserHideCmd, NULL }, - { NULL, NULL, NULL } -}; - -static Tcl_Interp *fontchooserInterp = NULL; -static NSFont *fontPanelFont = nil; -static NSMutableDictionary *fontPanelFontAttributes = nil; - -static const char *const fontchooserOptionStrings[] = { - "-parent", "-title", "-font", "-command", - "-visible", NULL -}; -enum FontchooserOption { - FontchooserParent, FontchooserTitle, FontchooserFont, FontchooserCmd, - FontchooserVisible -}; - -@implementation TKApplication(TKFontPanel) - -- (void) changeFont: (id) sender -{ - NSFontManager *fm = [NSFontManager sharedFontManager]; - - if ([fm currentFontAction] == NSViaPanelFontAction) { - NSFont *font = [fm convertFont:fontPanelFont]; - - if (![fontPanelFont isEqual:font]) { - [fontPanelFont release]; - fontPanelFont = [font retain]; - FontchooserEvent(FontchooserSelection); - } - } -} - -- (void) changeAttributes: (id) sender -{ - NSDictionary *attributes = [sender convertAttributes: - fontPanelFontAttributes]; - - if (![fontPanelFontAttributes isEqual:attributes]) { - [fontPanelFontAttributes setDictionary:attributes]; - FontchooserEvent(FontchooserSelection); - } -} - -- (NSUInteger) validModesForFontPanel: (NSFontPanel *) fontPanel -{ - return (NSFontPanelStandardModesMask & ~NSFontPanelAllEffectsModeMask) | - NSFontPanelUnderlineEffectModeMask | - NSFontPanelStrikethroughEffectModeMask; -} - -- (void) windowDidOrderOffScreen: (NSNotification *) notification -{ -#ifdef TK_MAC_DEBUG_NOTIFICATIONS - TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification); -#endif - if ([[notification object] isEqual:[[NSFontManager sharedFontManager] - fontPanel:NO]]) { - FontchooserEvent(FontchooserClosed); - } -} -@end - -/* - *---------------------------------------------------------------------- - * - * FontchooserEvent -- - * - * This processes events generated by user interaction with the - * font panel. - * - * Results: - * None. - * - * Side effects: - * Additional events may be place on the Tk event queue. - * - *---------------------------------------------------------------------- - */ - -static void -FontchooserEvent( - int kind) -{ - FontchooserData *fcdPtr; - Tcl_Obj *fontObj; - - if (!fontchooserInterp) { - return; - } - fcdPtr = Tcl_GetAssocData(fontchooserInterp, "::tk::fontchooser", NULL); - switch (kind) { - case FontchooserClosed: - if (fcdPtr->parent != None) { - TkSendVirtualEvent(fcdPtr->parent, "TkFontchooserVisibility", NULL); - fontchooserInterp = NULL; - } - break; - case FontchooserSelection: - fontObj = TkMacOSXFontDescriptionForNSFontAndNSFontAttributes( - fontPanelFont, fontPanelFontAttributes); - if (fontObj) { - if (fcdPtr->cmdObj) { - int objc, result; - Tcl_Obj **objv, **tmpv; - - result = Tcl_ListObjGetElements(fontchooserInterp, - fcdPtr->cmdObj, &objc, &objv); - if (result == TCL_OK) { - tmpv = ckalloc(sizeof(Tcl_Obj *) * (objc + 2)); - memcpy(tmpv, objv, sizeof(Tcl_Obj *) * objc); - tmpv[objc] = fontObj; - TkBackgroundEvalObjv(fontchooserInterp, objc + 1, tmpv, - TCL_EVAL_GLOBAL); - ckfree(tmpv); - } - } - TkSendVirtualEvent(fcdPtr->parent, "TkFontchooserFontChanged", NULL); - } - break; - } -} - -/* - *---------------------------------------------------------------------- - * - * FontchooserCget -- - * - * Helper for the FontchooserConfigure command to return the - * current value of any of the options (which may be NULL in - * the structure) - * - * Results: - * Tcl object of option value. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static Tcl_Obj * -FontchooserCget( - FontchooserData *fcdPtr, - int optionIndex) -{ - Tcl_Obj *resObj = NULL; - - switch(optionIndex) { - case FontchooserParent: - if (fcdPtr->parent != None) { - resObj = Tcl_NewStringObj( - ((TkWindow *) fcdPtr->parent)->pathName, -1); - } else { - resObj = Tcl_NewStringObj(".", 1); - } - break; - case FontchooserTitle: - if (fcdPtr->titleObj) { - resObj = fcdPtr->titleObj; - } else { - resObj = Tcl_NewObj(); - } - break; - case FontchooserFont: - resObj = TkMacOSXFontDescriptionForNSFontAndNSFontAttributes( - fontPanelFont, fontPanelFontAttributes); - if (!resObj) { - resObj = Tcl_NewObj(); - } - break; - case FontchooserCmd: - if (fcdPtr->cmdObj) { - resObj = fcdPtr->cmdObj; - } else { - resObj = Tcl_NewObj(); - } - break; - case FontchooserVisible: - resObj = Tcl_NewBooleanObj([[[NSFontManager sharedFontManager] - fontPanel:NO] isVisible]); - break; - default: - resObj = Tcl_NewObj(); - } - return resObj; -} - -/* - * ---------------------------------------------------------------------- - * - * FontchooserConfigureCmd -- - * - * Implementation of the 'tk fontchooser configure' ensemble command. - * See the user documentation for what it does. - * - * Results: - * See the user documentation. - * - * Side effects: - * Per-interp data structure may be modified - * - * ---------------------------------------------------------------------- - */ - -static int -FontchooserConfigureCmd( - ClientData clientData, /* Main window */ - Tcl_Interp *interp, - int objc, - Tcl_Obj *const objv[]) -{ - Tk_Window tkwin = (Tk_Window)clientData; - FontchooserData *fcdPtr = Tcl_GetAssocData(interp, "::tk::fontchooser", - NULL); - int i, r = TCL_OK; - - /* - * With no arguments we return all the options in a dict - */ - - if (objc == 1) { - Tcl_Obj *keyObj, *valueObj; - Tcl_Obj *dictObj = Tcl_NewDictObj(); - - for (i = 0; r == TCL_OK && fontchooserOptionStrings[i] != NULL; ++i) { - keyObj = Tcl_NewStringObj(fontchooserOptionStrings[i], -1); - valueObj = FontchooserCget(fcdPtr, i); - r = Tcl_DictObjPut(interp, dictObj, keyObj, valueObj); - } - if (r == TCL_OK) { - Tcl_SetObjResult(interp, dictObj); - } - return r; - } - - for (i = 1; i < objc; i += 2) { - int optionIndex, len; - - if (Tcl_GetIndexFromObjStruct(interp, objv[i], fontchooserOptionStrings, - sizeof(char *), "option", 0, &optionIndex) != TCL_OK) { - return TCL_ERROR; - } - if (objc == 2) { - /* - * With one option and no arg, return the current value. - */ - - Tcl_SetObjResult(interp, FontchooserCget(fcdPtr, optionIndex)); - return TCL_OK; - } - if (i + 1 == objc) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "value for \"%s\" missing", Tcl_GetString(objv[i]))); - Tcl_SetErrorCode(interp, "TK", "FONTDIALOG", "VALUE", NULL); - return TCL_ERROR; - } - switch (optionIndex) { - case FontchooserVisible: { - const char *msg = "cannot change read-only option " - "\"-visible\": use the show or hide command"; - - Tcl_SetObjResult(interp, Tcl_NewStringObj(msg, -1)); - Tcl_SetErrorCode(interp, "TK", "FONTDIALOG", "READONLY", NULL); - return TCL_ERROR; - } - case FontchooserParent: { - Tk_Window parent = Tk_NameToWindow(interp, - Tcl_GetString(objv[i+1]), tkwin); - - if (parent == None) { - return TCL_ERROR; - } - if (fcdPtr->parent) { - Tk_DeleteEventHandler(fcdPtr->parent, StructureNotifyMask, - FontchooserParentEventHandler, fcdPtr); - } - fcdPtr->parent = parent; - Tk_CreateEventHandler(fcdPtr->parent, StructureNotifyMask, - FontchooserParentEventHandler, fcdPtr); - break; - } - case FontchooserTitle: - if (fcdPtr->titleObj) { - Tcl_DecrRefCount(fcdPtr->titleObj); - } - Tcl_GetStringFromObj(objv[i+1], &len); - if (len) { - fcdPtr->titleObj = objv[i+1]; - if (Tcl_IsShared(fcdPtr->titleObj)) { - fcdPtr->titleObj = Tcl_DuplicateObj(fcdPtr->titleObj); - } - Tcl_IncrRefCount(fcdPtr->titleObj); - } else { - fcdPtr->titleObj = NULL; - } - break; - case FontchooserFont: - Tcl_GetStringFromObj(objv[i+1], &len); - if (len) { - Tk_Font f = Tk_AllocFontFromObj(interp, tkwin, objv[i+1]); - - if (!f) { - return TCL_ERROR; - } - [fontPanelFont autorelease]; - fontPanelFont = [TkMacOSXNSFontForFont(f) retain]; - [fontPanelFontAttributes setDictionary: - TkMacOSXNSFontAttributesForFont(f)]; - [fontPanelFontAttributes removeObjectsForKeys:[NSArray - arrayWithObjects:NSFontAttributeName, - NSLigatureAttributeName, NSKernAttributeName, nil]]; - Tk_FreeFont(f); - } else { - [fontPanelFont release]; - fontPanelFont = nil; - [fontPanelFontAttributes removeAllObjects]; - } - - NSFontManager *fm = [NSFontManager sharedFontManager]; - NSFontPanel *fp = [fm fontPanel:NO]; - - [fp setPanelFont:fontPanelFont isMultiple:NO]; - [fm setSelectedFont:fontPanelFont isMultiple:NO]; - [fm setSelectedAttributes:fontPanelFontAttributes - isMultiple:NO]; - if ([fp isVisible]) { - TkSendVirtualEvent(fcdPtr->parent, "TkFontchooserFontChanged", NULL); - } - break; - case FontchooserCmd: - if (fcdPtr->cmdObj) { - Tcl_DecrRefCount(fcdPtr->cmdObj); - } - Tcl_GetStringFromObj(objv[i+1], &len); - if (len) { - fcdPtr->cmdObj = objv[i+1]; - if (Tcl_IsShared(fcdPtr->cmdObj)) { - fcdPtr->cmdObj = Tcl_DuplicateObj(fcdPtr->cmdObj); - } - Tcl_IncrRefCount(fcdPtr->cmdObj); - } else { - fcdPtr->cmdObj = NULL; - } - break; - } - } - return TCL_OK; -} - -/* - * ---------------------------------------------------------------------- - * - * FontchooserShowCmd -- - * - * Implements the 'tk fontchooser show' ensemble command. The - * per-interp configuration data for the dialog is held in an interp - * associated structure. - * - * Results: - * See the user documentation. - * - * Side effects: - * Font Panel may be shown. - * - * ---------------------------------------------------------------------- - */ - -static int -FontchooserShowCmd( - ClientData clientData, /* Main window */ - Tcl_Interp *interp, - int objc, - Tcl_Obj *const objv[]) -{ - FontchooserData *fcdPtr = Tcl_GetAssocData(interp, "::tk::fontchooser", - NULL); - - if (fcdPtr->parent == None) { - fcdPtr->parent = (Tk_Window) clientData; - Tk_CreateEventHandler(fcdPtr->parent, StructureNotifyMask, - FontchooserParentEventHandler, fcdPtr); - } - NSFontManager *fm = [NSFontManager sharedFontManager]; - NSFontPanel *fp = [fm fontPanel:YES]; - if ([fp delegate] != NSApp) { - [fp setDelegate:NSApp]; - } - if (![fp isVisible]) { - [fm orderFrontFontPanel:NSApp]; - TkSendVirtualEvent(fcdPtr->parent, "TkFontchooserVisibility", NULL); - } - fontchooserInterp = interp; - - return TCL_OK; -} - -/* - * ---------------------------------------------------------------------- - * - * FontchooserHideCmd -- - * - * Implementation of the 'tk fontchooser hide' ensemble. See the - * user documentation for details. - * - * Results: - * See the user documentation. - * - * Side effects: - * Font Panel may be hidden. - * - * ---------------------------------------------------------------------- - */ - -static int -FontchooserHideCmd( - ClientData clientData, /* Main window */ - Tcl_Interp *interp, - int objc, - Tcl_Obj *const objv[]) -{ - NSFontPanel *fp = [[NSFontManager sharedFontManager] fontPanel:NO]; - if ([fp isVisible]) { - [fp orderOut:NSApp]; - } - return TCL_OK; -} - -/* - * ---------------------------------------------------------------------- - * - * FontchooserParentEventHandler -- - * - * Event handler for StructureNotify events on the font chooser's parent - * window. - * - * Results: - * None. - * - * Side effects: - * Font chooser parent info is cleared and font panel is hidden. - * - * ---------------------------------------------------------------------- - */ - -static void -FontchooserParentEventHandler( - ClientData clientData, - XEvent *eventPtr) -{ - FontchooserData *fcdPtr = clientData; - - if (eventPtr->type == DestroyNotify) { - Tk_DeleteEventHandler(fcdPtr->parent, StructureNotifyMask, - FontchooserParentEventHandler, fcdPtr); - fcdPtr->parent = None; - FontchooserHideCmd(NULL, NULL, 0, NULL); - } -} - -/* - * ---------------------------------------------------------------------- - * - * DeleteFontchooserData -- - * - * Clean up the font chooser configuration data when the interp is - * destroyed. - * - * Results: - * None. - * - * Side effects: - * per-interp configuration data is destroyed. - * - * ---------------------------------------------------------------------- - */ - -static void -DeleteFontchooserData( - ClientData clientData, - Tcl_Interp *interp) -{ - FontchooserData *fcdPtr = clientData; - - if (fcdPtr->titleObj) { - Tcl_DecrRefCount(fcdPtr->titleObj); - } - if (fcdPtr->cmdObj) { - Tcl_DecrRefCount(fcdPtr->cmdObj); - } - ckfree(fcdPtr); - - if (fontchooserInterp == interp) { - fontchooserInterp = NULL; - } -} - -/* - * ---------------------------------------------------------------------- - * - * TkInitFontchooser -- - * - * Associate the font chooser configuration data with the Tcl - * interpreter. There is one font chooser per interp. - * - * Results: - * None. - * - * Side effects: - * per-interp configuration data is destroyed. - * - * ---------------------------------------------------------------------- - */ - -MODULE_SCOPE int -TkInitFontchooser( - Tcl_Interp *interp, - ClientData clientData) -{ - FontchooserData *fcdPtr = ckalloc(sizeof(FontchooserData)); - - bzero(fcdPtr, sizeof(FontchooserData)); - Tcl_SetAssocData(interp, "::tk::fontchooser", DeleteFontchooserData, - fcdPtr); - if (!fontPanelFontAttributes) { - fontPanelFontAttributes = [NSMutableDictionary new]; - } - return TCL_OK; -} - -/* - * Local Variables: - * mode: objc - * c-basic-offset: 4 - * fill-column: 79 - * coding: utf-8 - * End: - */ |