From ca43551cd9bed517110272963b1c076d93aeb3d9 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 5 Nov 2016 13:11:14 +0530 Subject: [PATCH] Windows: Fix file extension not being added automatically when missing in save dialogs. Fixes #1637353 ['SAVE AS' COVER IMAGE -Does Not Save File](https://bugs.launchpad.net/calibre/+bug/1637353) --- setup/installer/windows/file_dialogs.cpp | 12 +++++++++--- src/calibre/gui2/win_file_dialogs.py | 12 ++++++++++-- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/setup/installer/windows/file_dialogs.cpp b/setup/installer/windows/file_dialogs.cpp index c89bd5c512..d93dc842ab 100644 --- a/setup/installer/windows/file_dialogs.cpp +++ b/setup/installer/windows/file_dialogs.cpp @@ -151,7 +151,7 @@ static void print_com_error(HRESULT hr, const char *msg) { #define REPORTERR(hr, x) { print_com_error(hr, x); ret = 1; goto error; } #define CALLCOM(x, err) hr = x; if(FAILED(hr)) REPORTERR(hr, err) -int show_dialog(HANDLE pipe, char *secret, HWND parent, bool save_dialog, LPWSTR title, LPWSTR folder, LPWSTR filename, LPWSTR save_path, bool multiselect, bool confirm_overwrite, bool only_dirs, bool no_symlinks, COMDLG_FILTERSPEC *file_types, UINT num_file_types) { +int show_dialog(HANDLE pipe, char *secret, HWND parent, bool save_dialog, LPWSTR title, LPWSTR folder, LPWSTR filename, LPWSTR save_path, bool multiselect, bool confirm_overwrite, bool only_dirs, bool no_symlinks, COMDLG_FILTERSPEC *file_types, UINT num_file_types, LPWSTR default_extension) { int ret = 0, name_sz = 0; IFileDialog *pfd = NULL; IShellItemArray *items = NULL; @@ -193,6 +193,10 @@ int show_dialog(HANDLE pipe, char *secret, HWND parent, bool save_dialog, LPWSTR if (filename != NULL) pfd->SetFileName(filename); // Failure is not critical if (!(options & FOS_PICKFOLDERS) && file_types != NULL && num_file_types > 0) { CALLCOM(pfd->SetFileTypes(num_file_types, file_types), "Failed to set file types") + CALLCOM(pfd->SetFileTypeIndex(1), "Failed to set file type index") + } + if (default_extension != NULL) { + CALLCOM(pfd->SetDefaultExtension(default_extension), "Failed to set default extension") } hr = pfd->Show(parent); if (hr == HRESULT_FROM_WIN32(ERROR_CANCELLED)) goto error; @@ -255,7 +259,7 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine HWND parent = NULL; bool save_dialog = false, multiselect = false, confirm_overwrite = false, only_dirs = false, no_symlinks = false; unsigned short len = 0; - LPWSTR title = NULL, folder = NULL, filename = NULL, save_path = NULL, echo = NULL, pipename = NULL; + LPWSTR title = NULL, folder = NULL, filename = NULL, save_path = NULL, echo = NULL, pipename = NULL, default_extension = NULL; COMDLG_FILTERSPEC *file_types = NULL; UINT num_file_types = 0; HANDLE pipe = INVALID_HANDLE_VALUE; @@ -306,6 +310,8 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine else if CHECK_KEY("FILE_TYPES") { file_types = read_file_types(&num_file_types); if (file_types == NULL) return 1; } + else if CHECK_KEY("DEFAULT_EXTENSION") { READSTR(default_extension) } + else if CHECK_KEY("ECHO") { READSTR(echo) } else { @@ -324,5 +330,5 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine return write_bytes(pipe, echo_sz, echo_buf) ? 0 : 1; } set_dpi_aware(); - return show_dialog(pipe, secret, parent, save_dialog, title, folder, filename, save_path, multiselect, confirm_overwrite, only_dirs, no_symlinks, file_types, num_file_types); + return show_dialog(pipe, secret, parent, save_dialog, title, folder, filename, save_path, multiselect, confirm_overwrite, only_dirs, no_symlinks, file_types, num_file_types, default_extension); } diff --git a/src/calibre/gui2/win_file_dialogs.py b/src/calibre/gui2/win_file_dialogs.py index bbbeea9d07..f11b2087ea 100644 --- a/src/calibre/gui2/win_file_dialogs.py +++ b/src/calibre/gui2/win_file_dialogs.py @@ -121,7 +121,7 @@ def select_initial_dir(q): def run_file_dialog( parent=None, title=None, initial_folder=None, filename=None, save_path=None, allow_multiple=False, only_dirs=False, confirm_overwrite=True, save_as=False, no_symlinks=False, - file_types=() + file_types=(), default_ext=None ): from calibre.gui2 import sanitize_env_vars secret = os.urandom(32).replace(b'\0', b' ') @@ -166,6 +166,8 @@ def run_file_dialog( file_types = [(_('All files'), ('*',))] if file_types: data.append(serialize_file_types(file_types)) + if default_ext: + data.append(serialize_string('DEFAULT_EXTENSION', default_ext)) loop = Loop() server = PipeServer(pipename) with sanitize_env_vars(): @@ -263,8 +265,14 @@ def choose_save_file(window, name, title, filters=[], all_files=True, initial_pa file_types = list(filters) if all_files: file_types.append((_('All files'), ['*'])) + all_exts = [] + for _, exts in file_types: + for ext in exts: + if '*' not in ext: + all_exts.append(ext.lower()) + default_ext = all_exts[0] if all_exts else None name, initial_folder = get_initial_folder(name, title, default_dir, no_save_dir) - ans = run_file_dialog(window, title, save_as=True, initial_folder=initial_folder, filename=filename, file_types=file_types) + ans = run_file_dialog(window, title, save_as=True, initial_folder=initial_folder, filename=filename, file_types=file_types, default_ext=default_ext) if ans: ans = ans[0] if not no_save_dir: