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)

This commit is contained in:
Kovid Goyal 2016-11-05 13:11:14 +05:30
parent b0b0b865e9
commit ca43551cd9
2 changed files with 19 additions and 5 deletions

View File

@ -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 REPORTERR(hr, x) { print_com_error(hr, x); ret = 1; goto error; }
#define CALLCOM(x, err) hr = x; if(FAILED(hr)) REPORTERR(hr, err) #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; int ret = 0, name_sz = 0;
IFileDialog *pfd = NULL; IFileDialog *pfd = NULL;
IShellItemArray *items = 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 (filename != NULL) pfd->SetFileName(filename); // Failure is not critical
if (!(options & FOS_PICKFOLDERS) && file_types != NULL && num_file_types > 0) { 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->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); hr = pfd->Show(parent);
if (hr == HRESULT_FROM_WIN32(ERROR_CANCELLED)) goto error; 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; HWND parent = NULL;
bool save_dialog = false, multiselect = false, confirm_overwrite = false, only_dirs = false, no_symlinks = false; bool save_dialog = false, multiselect = false, confirm_overwrite = false, only_dirs = false, no_symlinks = false;
unsigned short len = 0; 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; COMDLG_FILTERSPEC *file_types = NULL;
UINT num_file_types = 0; UINT num_file_types = 0;
HANDLE pipe = INVALID_HANDLE_VALUE; 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("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 if CHECK_KEY("ECHO") { READSTR(echo) }
else { else {
@ -324,5 +330,5 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine
return write_bytes(pipe, echo_sz, echo_buf) ? 0 : 1; return write_bytes(pipe, echo_sz, echo_buf) ? 0 : 1;
} }
set_dpi_aware(); 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);
} }

View File

@ -121,7 +121,7 @@ def select_initial_dir(q):
def run_file_dialog( def run_file_dialog(
parent=None, title=None, initial_folder=None, filename=None, save_path=None, 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, 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 from calibre.gui2 import sanitize_env_vars
secret = os.urandom(32).replace(b'\0', b' ') secret = os.urandom(32).replace(b'\0', b' ')
@ -166,6 +166,8 @@ def run_file_dialog(
file_types = [(_('All files'), ('*',))] file_types = [(_('All files'), ('*',))]
if file_types: if file_types:
data.append(serialize_file_types(file_types)) data.append(serialize_file_types(file_types))
if default_ext:
data.append(serialize_string('DEFAULT_EXTENSION', default_ext))
loop = Loop() loop = Loop()
server = PipeServer(pipename) server = PipeServer(pipename)
with sanitize_env_vars(): 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) file_types = list(filters)
if all_files: if all_files:
file_types.append((_('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) 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: if ans:
ans = ans[0] ans = ans[0]
if not no_save_dir: if not no_save_dir: