📄 tkmacdialog.c
字号:
CustomGetFile(openFilter, (short) -1, NULL, &reply, myDataPtr->dialogId, mypoint, openHook, NULL, NULL, NULL, (void*)myDataPtr); } else { StandardGetFile(NULL, -1, NULL, &reply); } } else { Str255 prompt, def; strcpy((char*)prompt+1, "Save as"); prompt[0] = strlen("Save as"); if (myDataPtr->initialFile) { strncpy((char*)def+1, myDataPtr->initialFile, 254); def[0] = strlen(myDataPtr->initialFile); } else { def[0] = 0; } if (myDataPtr->usePopup) { /* * Currently this never gets called because we don't use * popup for the save dialog. */ CustomPutFile(prompt, def, &reply, myDataPtr->dialogId, mypoint, saveHook, NULL, NULL, NULL, myDataPtr); } else { StandardPutFile(prompt, def, &reply); } } Tcl_ResetResult(interp); if (reply.sfGood) { int length; Handle pathHandle = NULL; char * pathName = NULL; FSpPathFromLocation(&reply.sfFile, &length, &pathHandle); if (pathHandle != NULL) { HLock(pathHandle); pathName = (char *) ckalloc((unsigned) (length + 1)); strcpy(pathName, *pathHandle); HUnlock(pathHandle); DisposeHandle(pathHandle); /* * Return the full pathname of the selected file */ Tcl_SetResult(interp, pathName, TCL_DYNAMIC); } } done: TkFreeFileFilters(&myDataPtr->fl); return code;}/* *---------------------------------------------------------------------- * * ParseFileDlgArgs -- * * Parses the arguments passed to tk_getOpenFile and tk_getSaveFile. * * Results: * A standard TCL return value. * * Side effects: * The OpenFileData structure is initialized and modified according * to the arguments. * *---------------------------------------------------------------------- */static intParseFileDlgArgs( Tcl_Interp * interp, /* Current interpreter. */ OpenFileData * myDataPtr, /* Information about the file dialog */ int argc, /* Number of arguments */ char ** argv, /* Argument strings */ int isOpen) /* TRUE if this is an "open" dialog */{ int i; myDataPtr->interp = interp; myDataPtr->initialFile = NULL; myDataPtr->curType = 0; TkInitFileFilters(&myDataPtr->fl); if (isOpen) { myDataPtr->isOpen = 1; myDataPtr->usePopup = 1; myDataPtr->menu = GetMenu(OPEN_MENU); myDataPtr->dialogId = OPEN_BOX; myDataPtr->popupId = OPEN_POPUP; myDataPtr->popupItem = OPEN_POPUP_ITEM; if (myDataPtr->menu == NULL) { Debugger(); } } else { myDataPtr->isOpen = 0; myDataPtr->usePopup = 0; } for (i=1; i<argc; i+=2) { int v = i+1; int len = strlen(argv[i]); if (strncmp(argv[i], "-defaultextension", len)==0) { if (v==argc) {goto arg_missing;} myDataPtr->defExt = argv[v]; } else if (strncmp(argv[i], "-filetypes", len)==0) { if (v==argc) {goto arg_missing;} if (TkGetFileFilters(interp, &myDataPtr->fl,argv[v],0) != TCL_OK) { return TCL_ERROR; } } else if (strncmp(argv[i], "-initialdir", len)==0) { FSSpec dirSpec; char * dirName; Tcl_DString dstring; long dirID; OSErr err; Boolean isDirectory; if (v==argc) {goto arg_missing;} if (Tcl_TranslateFileName(interp, argv[v], &dstring) == NULL) { return TCL_ERROR; } dirName = dstring.string; if (FSpLocationFromPath(strlen(dirName), dirName, &dirSpec) != noErr) { Tcl_AppendResult(interp, "bad directory \"", argv[v], "\"", NULL); return TCL_ERROR; } err = FSpGetDirectoryID(&dirSpec, &dirID, &isDirectory); if ((err != noErr) || !isDirectory) { Tcl_AppendResult(interp, "bad directory \"", argv[v], "\"", NULL); return TCL_ERROR; } /* * Make sure you negate -dirSpec.vRefNum because the standard file * package wants it that way ! */ LMSetSFSaveDisk(-dirSpec.vRefNum); LMSetCurDirStore(dirID); Tcl_DStringFree(&dstring); } else if (strncmp(argv[i], "-initialfile", len)==0) { if (v==argc) {goto arg_missing;} myDataPtr->initialFile = argv[v]; } else if (strncmp(argv[i], "-parent", len)==0) { /* * Ignored on the Mac, but make sure that it's a valid window * pathname */ Tk_Window parent; if (v==argc) {goto arg_missing;} parent=Tk_NameToWindow(interp, argv[v], Tk_MainWindow(interp)); if (parent == NULL) { return TCL_ERROR; } } else if (strncmp(argv[i], "-title", len)==0) { if (v==argc) {goto arg_missing;} /* * This option is ignored on the Mac because the Mac file * dialog do not support titles. */ } else { Tcl_AppendResult(interp, "unknown option \"", argv[i], "\", must be -defaultextension, ", "-filetypes, -initialdir, -initialfile, -parent or -title", NULL); return TCL_ERROR; } } return TCL_OK; arg_missing: Tcl_AppendResult(interp, "value for \"", argv[argc-1], "\" missing", NULL); return TCL_ERROR;}/* *---------------------------------------------------------------------- * * OpenHookProc -- * * Gets called for various events that occur in the file dialog box. * Initializes the popup menu or rebuild the file list depending on * the type of the event. * * Results: * A standard result understood by the Mac file dialog event dispatcher. * * Side effects: * The contents in the file dialog may be changed depending on * the type of the event. *---------------------------------------------------------------------- */static pascal shortOpenHookProc( short item, /* Event description. */ DialogPtr theDialog, /* The dialog where the event occurs. */ OpenFileData * myDataPtr) /* Information about the file dialog. */{ short ignore; Rect rect; Handle handle; int newType; switch (item) { case sfHookFirstCall: if (myDataPtr->usePopup) { /* * Set the popup list to display the selected type. */ GetDialogItem(theDialog, myDataPtr->popupItem, &ignore, &handle, &rect); SetControlValue((ControlRef) handle, myDataPtr->curType + 1); } return sfHookNullEvent; case OPEN_POPUP_ITEM: if (myDataPtr->usePopup) { GetDialogItem(theDialog, myDataPtr->popupItem, &ignore, &handle, &rect); newType = GetCtlValue((ControlRef) handle) - 1; if (myDataPtr->curType != newType) { if (newType<0 || newType>myDataPtr->fl.numFilters) { /* * Sanity check. Looks like the user selected an * non-existent menu item?? Don't do anything. */ } else { myDataPtr->curType = newType; } return sfHookRebuildList; } } break; } return item;}/* *---------------------------------------------------------------------- * * FileFilterProc -- * * Filters files according to file types. Get called whenever the * file list needs to be updated inside the dialog box. * * Results: * Returns MATCHED if the file should be shown in the listbox, returns * UNMATCHED otherwise. * * Side effects: * If MATCHED is returned, the file is shown in the listbox. * *---------------------------------------------------------------------- */static pascal BooleanFileFilterProc( CInfoPBPtr pb, /* Information about the file */ void *myData) /* Client data for this file dialog */{ int i; OpenFileData * myDataPtr = (OpenFileData*)myData; FileFilter * filterPtr; if (myDataPtr->fl.numFilters == 0) { /* * No types have been specified. List all files by default */ return MATCHED; } if (pb->dirInfo.ioFlAttrib & 0x10) { /* * This is a directory: always show it */ return MATCHED; } if (myDataPtr->usePopup) { i = myDataPtr->curType; for (filterPtr=myDataPtr->fl.filters; filterPtr && i>0; i--) { filterPtr = filterPtr->next; } if (filterPtr) { return MatchOneType(pb, myDataPtr, filterPtr); } else { return UNMATCHED; } } else { /* * We are not using the popup menu. In this case, the file is * considered matched if it matches any of the file filters. */ for (filterPtr=myDataPtr->fl.filters; filterPtr; filterPtr=filterPtr->next) { if (MatchOneType(pb, myDataPtr, filterPtr) == MATCHED) { return MATCHED; } } return UNMATCHED; }}/* *---------------------------------------------------------------------- * * MatchOneType -- * * Match a file with one file type in the list of file types. * * Results: * Returns MATCHED if the file matches with the file type; returns * UNMATCHED otherwise. * * Side effects: * None * *---------------------------------------------------------------------- */static BooleanMatchOneType( CInfoPBPtr pb, /* Information about the file */ OpenFileData * myDataPtr, /* Information about this file dialog */ FileFilter * filterPtr) /* Match the file described by pb against * this filter */{ FileFilterClause * clausePtr; /* * A file matches with a file type if it matches with at least one * clause of the type. * * If the clause has both glob patterns and ostypes, the file must * match with at least one pattern AND at least one ostype. * * If the clause has glob patterns only, the file must match with at least * one pattern. * * If the clause has mac types only, the file must match with at least * one mac type. * * If the clause has neither glob patterns nor mac types, it's * considered an error. */ for (clausePtr=filterPtr->clauses; clausePtr; clausePtr=clausePtr->next) { int macMatched = 0; int globMatched = 0; GlobPattern * globPtr; MacFileType * mfPtr; if (clausePtr->patterns == NULL) { globMatched = 1; } if (clausePtr->macTypes == NULL) { macMatched = 1; } for (globPtr=clausePtr->patterns; globPtr; globPtr=globPtr->next) { char filename[256]; int len; char * p, *q, *ext; if (pb->hFileInfo.ioNamePtr == NULL) { continue; } p = (char*)(pb->hFileInfo.ioNamePtr); len = p[0]; strncpy(filename, p+1, len); filename[len] = '\0'; ext = globPtr->pattern; if (ext[0] == '\0') { /* * We don't want any extensions: OK if the filename doesn't * have "." in it */ for (q=filename; *q; q++) { if (*q == '.') { goto glob_unmatched; } } goto glob_matched; } if (Tcl_StringMatch(filename, ext)) { goto glob_matched; } else { goto glob_unmatched; } glob_unmatched: continue; glob_matched: globMatched = 1; break; } for (mfPtr=clausePtr->macTypes; mfPtr; mfPtr=mfPtr->next) { if (pb->hFileInfo.ioFlFndrInfo.fdType == mfPtr->type) { macMatched = 1; break; } } if (globMatched && macMatched) { return MATCHED; } } return UNMATCHED;}/* *---------------------------------------------------------------------- * * Tk_MessageBoxCmd -- * * This procedure implements the MessageBox window for the * Mac platform. See the user documentation for details on what * it does. * * Results: * A standard Tcl result. * * Side effects: * See user documentation. * *---------------------------------------------------------------------- */intTk_MessageBoxCmd( ClientData clientData, /* Main window associated with interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int argc, /* Number of arguments. */ char **argv) /* Argument strings. */{ return EvalArgv(interp, "tkMessageBox", argc, argv);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -