diff options
Diffstat (limited to 'win')
-rw-r--r-- | win/tkWinDialog.c | 118 |
1 files changed, 89 insertions, 29 deletions
diff --git a/win/tkWinDialog.c b/win/tkWinDialog.c index 2e85cb6..b3203fd 100644 --- a/win/tkWinDialog.c +++ b/win/tkWinDialog.c @@ -8,7 +8,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkWinDialog.c,v 1.46 2007/09/08 16:13:45 dkf Exp $ + * RCS: @(#) $Id: tkWinDialog.c,v 1.47 2007/10/25 21:44:23 hobbs Exp $ * */ @@ -189,7 +189,8 @@ static int GetFileNameW(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int isOpen); static int MakeFilter(Tcl_Interp *interp, Tcl_Obj *valuePtr, - Tcl_DString *dsPtr); + Tcl_DString *dsPtr, Tcl_Obj *initialPtr, + int *index); static UINT APIENTRY OFNHookProc(HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam); static UINT APIENTRY OFNHookProcW(HWND hdlg, UINT uMsg, WPARAM wParam, @@ -575,10 +576,11 @@ GetFileNameW( { OPENFILENAMEW ofn; WCHAR file[TK_MULTI_MAX_PATH]; - int result, winCode, oldMode, i, multi = 0; + int filterIndex, result, winCode, oldMode, i, multi = 0; char *extension, *filter, *title; Tk_Window tkwin; HWND hWnd; + Tcl_Obj *filterObj, *initialTypeObj, *typeVariableObj; Tcl_DString utfFilterString, utfDirString; Tcl_DString extString, filterString, dirString, titleString; Tcl_Encoding unicodeEncoding = TkWinGetUnicodeEncoding(); @@ -586,17 +588,17 @@ GetFileNameW( Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); static CONST char *saveOptionStrings[] = { "-defaultextension", "-filetypes", "-initialdir", "-initialfile", - "-parent", "-title", NULL + "-parent", "-title", "-typevariable", NULL }; static CONST char *openOptionStrings[] = { "-defaultextension", "-filetypes", "-initialdir", "-initialfile", - "-multiple", "-parent", "-title", NULL + "-multiple", "-parent", "-title", "-typevariable", NULL }; CONST char **optionStrings; enum options { FILE_DEFAULT, FILE_TYPES, FILE_INITDIR, FILE_INITFILE, - FILE_MULTIPLE, FILE_PARENT, FILE_TITLE + FILE_MULTIPLE, FILE_PARENT, FILE_TITLE, FILE_TYPEVARIABLE }; result = TCL_ERROR; @@ -612,6 +614,9 @@ GetFileNameW( Tcl_DStringInit(&utfDirString); tkwin = (Tk_Window) clientData; title = NULL; + filterObj = NULL; + typeVariableObj = NULL; + initialTypeObj = NULL; if (open) { optionStrings = openOptionStrings; @@ -663,11 +668,7 @@ GetFileNameW( extension = string; break; case FILE_TYPES: - Tcl_DStringFree(&utfFilterString); - if (MakeFilter(interp, valuePtr, &utfFilterString) != TCL_OK) { - goto end; - } - filter = Tcl_DStringValue(&utfFilterString); + filterObj = valuePtr; break; case FILE_INITDIR: Tcl_DStringFree(&utfDirString); @@ -702,14 +703,18 @@ GetFileNameW( case FILE_TITLE: title = string; break; + case FILE_TYPEVARIABLE: + typeVariableObj = valuePtr; + initialTypeObj = Tcl_ObjGetVar2(interp, typeVariableObj, NULL, 0); + break; } } - if (filter == NULL) { - if (MakeFilter(interp, NULL, &utfFilterString) != TCL_OK) { - goto end; - } + if (MakeFilter(interp, filterObj, &utfFilterString, initialTypeObj, + &filterIndex) != TCL_OK) { + goto end; } + filter = Tcl_DStringValue(&utfFilterString); Tk_MakeWindowExist(tkwin); hWnd = Tk_GetHWND(Tk_WindowId(tkwin)); @@ -748,6 +753,7 @@ GetFileNameW( Tcl_DStringValue(&utfFilterString), Tcl_DStringLength(&utfFilterString), &filterString); ofn.lpstrFilter = (WCHAR *) Tcl_DStringValue(&filterString); + ofn.nFilterIndex = filterIndex; if (Tcl_DStringValue(&utfDirString)[0] != '\0') { Tcl_UtfToExternalDString(unicodeEncoding, @@ -878,6 +884,23 @@ GetFileNameW( (char *) ofn.lpstrFile, &ds), NULL); Tcl_DStringFree(&ds); } + if ((ofn.nFilterIndex > 0) && + Tcl_GetCharLength(Tcl_GetObjResult(interp)) > 0 && + typeVariableObj && filterObj) { + int listObjc, count; + Tcl_Obj **listObjv = NULL; + Tcl_Obj **typeInfo = NULL; + if (Tcl_ListObjGetElements(interp, filterObj, + &listObjc, &listObjv) != TCL_OK) { + result = TCL_ERROR; + } else if (Tcl_ListObjGetElements(interp, + listObjv[ofn.nFilterIndex - 1], + &count, &typeInfo) != TCL_OK) { + result = TCL_ERROR; + } else { + Tcl_ObjSetVar2(interp, typeVariableObj, NULL, typeInfo[0], 0); + } + } result = TCL_OK; } else { /* @@ -997,27 +1020,28 @@ GetFileNameA( { OPENFILENAME ofn; TCHAR file[TK_MULTI_MAX_PATH], savePath[MAX_PATH]; - int result, winCode, oldMode, i, multi = 0; + int filterIndex, result, winCode, oldMode, i, multi = 0; char *extension, *filter, *title; Tk_Window tkwin; HWND hWnd; + Tcl_Obj *filterObj, *initialTypeObj, *typeVariableObj; Tcl_DString utfFilterString, utfDirString; Tcl_DString extString, filterString, dirString, titleString; ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); static CONST char *saveOptionStrings[] = { "-defaultextension", "-filetypes", "-initialdir", "-initialfile", - "-parent", "-title", NULL + "-parent", "-title", "-typevariable", NULL }; static CONST char *openOptionStrings[] = { "-defaultextension", "-filetypes", "-initialdir", "-initialfile", - "-multiple", "-parent", "-title", NULL + "-multiple", "-parent", "-title", "-typevariable", NULL }; CONST char **optionStrings; enum options { FILE_DEFAULT, FILE_TYPES, FILE_INITDIR, FILE_INITFILE, - FILE_MULTIPLE, FILE_PARENT, FILE_TITLE + FILE_MULTIPLE, FILE_PARENT, FILE_TITLE, FILE_TYPEVARIABLE }; result = TCL_ERROR; @@ -1033,6 +1057,9 @@ GetFileNameA( Tcl_DStringInit(&utfDirString); tkwin = (Tk_Window) clientData; title = NULL; + filterObj = NULL; + typeVariableObj = NULL; + initialTypeObj = NULL; if (open) { optionStrings = openOptionStrings; @@ -1084,11 +1111,7 @@ GetFileNameA( extension = string; break; case FILE_TYPES: - Tcl_DStringFree(&utfFilterString); - if (MakeFilter(interp, valuePtr, &utfFilterString) != TCL_OK) { - goto end; - } - filter = Tcl_DStringValue(&utfFilterString); + filterObj = valuePtr; break; case FILE_INITDIR: Tcl_DStringFree(&utfDirString); @@ -1122,14 +1145,18 @@ GetFileNameA( case FILE_TITLE: title = string; break; + case FILE_TYPEVARIABLE: + typeVariableObj = valuePtr; + initialTypeObj = Tcl_ObjGetVar2(interp, typeVariableObj, NULL, 0); + break; } } - if (filter == NULL) { - if (MakeFilter(interp, NULL, &utfFilterString) != TCL_OK) { - goto end; - } + if (MakeFilter(interp, filterObj, &utfFilterString, initialTypeObj, + &filterIndex) != TCL_OK) { + goto end; } + filter = Tcl_DStringValue(&utfFilterString); Tk_MakeWindowExist(tkwin); hWnd = Tk_GetHWND(Tk_WindowId(tkwin)); @@ -1306,6 +1333,23 @@ GetFileNameA( (char *) ofn.lpstrFile, &ds), NULL); Tcl_DStringFree(&ds); } + if ((ofn.nFilterIndex > 0) && + (Tcl_GetCharLength(Tcl_GetObjResult(interp)) > 0) && + typeVariableObj && filterObj) { + int listObjc, count; + Tcl_Obj **listObjv = NULL; + Tcl_Obj **typeInfo = NULL; + if (Tcl_ListObjGetElements(interp, filterObj, + &listObjc, &listObjv) != TCL_OK) { + result = TCL_ERROR; + } else if (Tcl_ListObjGetElements(interp, + listObjv[ofn.nFilterIndex - 1], + &count, &typeInfo) != TCL_OK) { + result = TCL_ERROR; + } else { + Tcl_ObjSetVar2(interp, typeVariableObj, NULL, typeInfo[0], 0); + } + } result = TCL_OK; } else { /* @@ -1422,14 +1466,21 @@ static int MakeFilter( Tcl_Interp *interp, /* Current interpreter. */ Tcl_Obj *valuePtr, /* Value of the -filetypes option */ - Tcl_DString *dsPtr) /* Filled with windows filter string. */ + Tcl_DString *dsPtr, /* Filled with windows filter string. */ + Tcl_Obj *initialPtr, /* Initial type name */ + int *index) /* Index of initial type in filter string */ { char *filterStr; char *p; + char *initial = NULL; int pass; + int ix = 0; /* index counter */ FileFilterList flist; FileFilter *filterPtr; + if (initialPtr) { + initial = Tcl_GetStringFromObj(initialPtr, NULL); + } TkInitFileFilters(&flist); if (TkGetFileFilters(interp, &flist, valuePtr, 1) != TCL_OK) { return TCL_ERROR; @@ -1485,6 +1536,15 @@ MakeFilter( FileFilterClause *clausePtr; /* + * Check initial index for match, set index. + * Filter index is 1 based so increment first + */ + ix++; + if (index && initial && (strcmp(initial, filterPtr->name) == 0)) { + *index = ix; + } + + /* * First, put in the name of the file type. */ |