Index: doc/getOpenFile.n ================================================================== --- doc/getOpenFile.n +++ doc/getOpenFile.n @@ -33,10 +33,16 @@ whether the existing file should be overwritten or not. .PP The following \fIoption\-value\fR pairs are possible as command line arguments to these two commands: .TP +\fB\-confirmoverwrite\fR \fIboolean\fR +Configures how the Save dialog reacts when the selected file already +exists, and saving would overwrite it. A true value requests a +confirmation dialog be presented to the user. A false value requests +that the overwrite take place without confirmation. Default value is true. +.TP \fB\-defaultextension\fR \fIextension\fR Specifies a string that will be appended to the filename if the user enters a filename without an extension. The default value is the empty string, which means no extension will be appended to the filename in any case. This option is ignored on Mac OS X, which Index: library/tkfbox.tcl ================================================================== --- library/tkfbox.tcl +++ library/tkfbox.tcl @@ -980,10 +980,16 @@ # The "-multiple" option is only available for the "open" file dialog. # if {$type eq "open"} { lappend specs {-multiple "" "" "0"} } + + # The "-confirmoverwrite" option is only for the "save" file dialog. + # + if {$type eq "save"} { + lappend specs {-confirmoverwrite "" "" "1"} + } # 2: default values depending on the type of the dialog # if {![info exists data(selectPath)]} { # first time the dialog has been popped up @@ -1857,11 +1863,11 @@ } set Priv(selectFile) $data(selectFile) set Priv(selectPath) $data(selectPath) - if {($data(type) eq "save") && [file exists $selectFilePath]} { + if {($data(type) eq "save") && $data(-confirmoverwrite) && [file exists $selectFilePath]} { set reply [tk_messageBox -icon warning -type yesno -parent $w \ -message [mc "File \"%1\$s\" already exists.\nDo you want\ to overwrite it?" $selectFilePath]] if {$reply eq "no"} { return Index: macosx/tkMacOSXDialog.c ================================================================== --- macosx/tkMacOSXDialog.c +++ macosx/tkMacOSXDialog.c @@ -82,11 +82,12 @@ static void InitFileDialogs(void); static int NavServicesGetFile(Tcl_Interp *interp, OpenFileData *ofd, AEDesc *initialDescPtr, char *initialFile, AEDescList *selectDescPtr, CFStringRef title, CFStringRef message, - const char *initialType, int multiple, int isOpen, + const char *initialType, int multiple, + int confirmOverwrite, int isOpen, Tk_Window parent); static int HandleInitialDirectory(Tcl_Interp *interp, char *initialFile, char *initialDir, FSRef *dirRef, AEDescList *selectDescPtr, AEDesc *dirDescPtr); @@ -364,11 +365,11 @@ if (typeVariablePtr) { initialtype = Tcl_GetVar(interp, Tcl_GetString(typeVariablePtr), TCL_GLOBAL_ONLY); } result = NavServicesGetFile(interp, &ofd, initialPtr, NULL, &selectDesc, - title, message, initialtype, multiple, OPEN_FILE, parent); + title, message, initialtype, multiple, false, OPEN_FILE, parent); if (typeVariablePtr) { FileFilter *filterPtr = ofd.fl.filters; int i = ofd.curType; @@ -420,24 +421,27 @@ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *CONST objv[]) /* Argument objects. */ { int i, result = TCL_ERROR; + int confirmOverwrite = 1; char *initialFile = NULL; Tk_Window parent = NULL; AEDesc initialDesc = {typeNull, NULL}; AEDesc *initialPtr = NULL; FSRef dirRef; CFStringRef title = NULL, message = NULL; OpenFileData ofd; static const char *saveOptionStrings[] = { "-defaultextension", "-filetypes", "-initialdir", "-initialfile", - "-message", "-parent", "-title", "-typevariable", NULL + "-message", "-parent", "-title", "-typevariable", + "-confirmoverwrite", NULL }; enum saveOptions { SAVE_DEFAULT, SAVE_FILETYPES, SAVE_INITDIR, SAVE_INITFILE, SAVE_MESSAGE, SAVE_PARENT, SAVE_TITLE, SAVE_TYPEVARIABLE, + SAVE_CONFIRMOW }; if (!fileDlgInited) { InitFileDialogs(); } @@ -506,18 +510,24 @@ CFRelease(title); } title = CFStringCreateWithBytes(NULL, (unsigned char *) choice, choiceLen, kCFStringEncodingUTF8, false); break; + case SAVE_CONFIRMOW: + if (Tcl_GetBooleanFromObj(interp, objv[i + 1], &confirmOverwrite) + != TCL_OK) { + return TCL_ERROR; + } + break; } } if (initialDesc.descriptorType == typeFSRef) { initialPtr = &initialDesc; } result = NavServicesGetFile(interp, &ofd, initialPtr, initialFile, NULL, - title, message, NULL, false, SAVE_FILE, parent); + title, message, NULL, false, confirmOverwrite, SAVE_FILE, parent); TkFreeFileFilters(&ofd.fl); end: if (initialDesc.dataHandle) { ChkErr(AEDisposeDesc, &initialDesc); } @@ -625,11 +635,11 @@ ofd.usePopup = 0; if (initialDesc.descriptorType == typeFSRef) { initialPtr = &initialDesc; } result = NavServicesGetFile(interp, &ofd, initialPtr, NULL, NULL, title, - message, NULL, false, CHOOSE_FOLDER, parent); + message, NULL, false, false, CHOOSE_FOLDER, parent); TkFreeFileFilters(&ofd.fl); end: if (initialDesc.dataHandle) { ChkErr(AEDisposeDesc, &initialDesc); } @@ -776,10 +786,11 @@ AEDescList *selectDescPtr, CFStringRef title, CFStringRef message, const char *initialtype, int multiple, + int confirmOverwrite, int isOpen, Tk_Window parent) { NavHandlerUserData data; NavDialogCreationOptions options; @@ -797,10 +808,13 @@ options.optionFlags = kNavDontAutoTranslate | kNavDontAddTranslateItems | kNavSupportPackages | kNavAllFilesInPopup; if (multiple) { options.optionFlags |= kNavAllowMultipleFiles; } + if (!confirmOverwrite) { + options.optionFlags |= kNavDontConfirmReplacement; + } options.modality = kWindowModalityAppModal; if (parent && ((TkWindow *) parent)->window != None && TkMacOSXHostToplevelExists(parent)) { options.parentWindow = TkMacOSXDrawableWindow(Tk_WindowId(parent)); TK_IF_HI_TOOLBOX (5, Index: win/tkWinDialog.c ================================================================== --- win/tkWinDialog.c +++ win/tkWinDialog.c @@ -590,10 +590,11 @@ OPENFILENAMEW ofn; WCHAR file[TK_MULTI_MAX_PATH]; OFNData ofnData; int cdlgerr; int filterIndex = 0, result = TCL_ERROR, winCode, oldMode, i, multi = 0; + int inValue, confirmOverwrite = 1; char *extension = NULL, *title = NULL; Tk_Window tkwin = (Tk_Window) clientData; HWND hWnd; Tcl_Obj *filterObj = NULL, *initialTypeObj = NULL, *typeVariableObj = NULL; Tcl_DString utfFilterString, utfDirString, ds; @@ -601,66 +602,45 @@ Tcl_Encoding unicodeEncoding = TkWinGetUnicodeEncoding(); ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); static CONST char *saveOptionStrings[] = { "-defaultextension", "-filetypes", "-initialdir", "-initialfile", - "-parent", "-title", "-typevariable", NULL + "-parent", "-title", "-typevariable", + "-confirmoverwrite", + NULL }; static CONST char *openOptionStrings[] = { "-defaultextension", "-filetypes", "-initialdir", "-initialfile", - "-multiple", "-parent", "-title", "-typevariable", NULL + "-parent", "-title", "-typevariable", + "-multiple", + NULL }; - CONST char **optionStrings; - enum options { - FILE_DEFAULT, FILE_TYPES, FILE_INITDIR, FILE_INITFILE, - FILE_MULTIPLE, FILE_PARENT, FILE_TITLE, FILE_TYPEVARIABLE + FILE_DEFAULT, FILE_TYPES, FILE_INITDIR, FILE_INITFILE, + FILE_PARENT, FILE_TITLE, FILE_TYPEVARIABLE, + FILE_MULTIPLE_OR_CONFIRMOW }; file[0] = '\0'; ZeroMemory(&ofnData, sizeof(OFNData)); Tcl_DStringInit(&utfFilterString); Tcl_DStringInit(&utfDirString); - /* - * Parse the arguments. - */ - - if (open) { - optionStrings = openOptionStrings; - } else { - optionStrings = saveOptionStrings; - } - for (i = 1; i < objc; i += 2) { int index; char *string; Tcl_Obj *optionPtr, *valuePtr; optionPtr = objv[i]; valuePtr = objv[i + 1]; - if (Tcl_GetIndexFromObj(interp, optionPtr, optionStrings, + if (Tcl_GetIndexFromObj(interp, optionPtr, + open ? openOptionStrings : saveOptionStrings, "option", 0, &index) != TCL_OK) { goto end; } - /* - * We want to maximize code sharing between the open and save file - * dialog implementations; in particular, the switch statement below. - * We use different sets of option strings from the GetIndexFromObj - * call above, but a single enumeration for both. The save file dialog - * doesn't support -multiple, but it falls in the middle of the - * enumeration. Ultimately, this means that when the index found by - * GetIndexFromObj is >= FILE_MULTIPLE, when doing a save file dialog, - * we have to increment the index, so that it matches the open file - * dialog enumeration. - */ - - if (!open && index >= FILE_MULTIPLE) { - index++; - } if (i + 1 == objc) { string = Tcl_GetString(optionPtr); Tcl_AppendResult(interp, "value for \"", string, "\" missing", NULL); goto end; @@ -690,15 +670,10 @@ } Tcl_UtfToExternal(NULL, unicodeEncoding, Tcl_DStringValue(&ds), Tcl_DStringLength(&ds), 0, NULL, (char *) file, sizeof(file), NULL, NULL, NULL); Tcl_DStringFree(&ds); - break; - case FILE_MULTIPLE: - if (Tcl_GetBooleanFromObj(interp, valuePtr, &multi) != TCL_OK) { - return TCL_ERROR; - } break; case FILE_PARENT: tkwin = Tk_NameToWindow(interp, string, tkwin); if (tkwin == NULL) { goto end; @@ -709,10 +684,20 @@ break; case FILE_TYPEVARIABLE: typeVariableObj = valuePtr; initialTypeObj = Tcl_ObjGetVar2(interp, typeVariableObj, NULL, TCL_GLOBAL_ONLY); + break; + case FILE_MULTIPLE_OR_CONFIRMOW: + if (Tcl_GetBooleanFromObj(interp, valuePtr, &inValue) != TCL_OK) { + return TCL_ERROR; + } + if (open) { + multi = inValue; + } else { + confirmOverwrite = inValue; + } break; } } if (MakeFilter(interp, filterObj, &utfFilterString, initialTypeObj, @@ -738,11 +723,11 @@ ofn.lpfnHook = (LPOFNHOOKPROC) OFNHookProcW; ofn.lCustData = (LPARAM) &ofnData; if (open != 0) { ofn.Flags |= OFN_FILEMUSTEXIST; - } else { + } else if (confirmOverwrite) { ofn.Flags |= OFN_OVERWRITEPROMPT; } if (tsdPtr->debugFlag != 0) { ofnData.interp = interp; }