From e133f3c1fabedacf13f2b150b1f97883a892e8f3 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 3 May 2016 23:27:46 +0530 Subject: [PATCH] Setting of initial folder --- setup/installer/windows/file_dialogs.cpp | 17 ++++++++++++----- src/calibre/gui2/win_file_dialogs.py | 20 ++++++++++++++++++-- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/setup/installer/windows/file_dialogs.cpp b/setup/installer/windows/file_dialogs.cpp index a14bc6c2b1..dc39b8be7f 100644 --- a/setup/installer/windows/file_dialogs.cpp +++ b/setup/installer/windows/file_dialogs.cpp @@ -16,10 +16,10 @@ #define REPORTERR(x) { PRINTERR(x); ret = 1; goto error; } #define CALLCOM(x, err) hr = x; if(FAILED(hr)) REPORTERR(err) -int show_dialog(HWND parent, bool save_dialog, LPWSTR title, bool multiselect, bool confirm_overwrite, bool only_dirs, bool no_symlinks) { +int show_dialog(HWND parent, bool save_dialog, LPWSTR title, LPWSTR folder, bool multiselect, bool confirm_overwrite, bool only_dirs, bool no_symlinks) { int ret = 0; IFileDialog *pfd = NULL; - IShellItem *psiResult = NULL; + IShellItem *result = NULL, *folder_item = NULL; DWORD options; HRESULT hr = S_OK; hr = CoInitialize(NULL); @@ -42,11 +42,16 @@ int show_dialog(HWND parent, bool save_dialog, LPWSTR title, bool multiselect, b } CALLCOM(pfd->SetOptions(options), "Failed to set options") if (title != NULL) { CALLCOM(pfd->SetTitle(title), "Failed to set title") } + if (folder != NULL) { + hr = SHCreateItemFromParsingName(folder, NULL, IID_IShellItem, reinterpret_cast(&folder_item)); + // Failure to set initial folder is not critical + if (SUCCEEDED(hr)) pfd->SetFolder(folder_item); + } hr = pfd->Show(parent); if (hr == HRESULT_FROM_WIN32(ERROR_CANCELLED)) goto error; if (FAILED(hr)) REPORTERR("Failed to show dialog") - CALLCOM(pfd->GetResult(&psiResult), "Failed to get dialog result") + CALLCOM(pfd->GetResult(&result), "Failed to get dialog result") error: if(pfd) pfd->Release(); @@ -99,7 +104,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; + LPWSTR title = NULL, folder = NULL; SETBINARY(stdout); SETBINARY(stdin); SETBINARY(stderr); // The calibre executables call SetDllDirectory, we unset it here just in @@ -120,6 +125,8 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine else if CHECK_KEY("TITLE") { READSTR(title) } + else if CHECK_KEY("FOLDER") { READSTR(folder) } + else if CHECK_KEY("SAVE_AS") { READBOOL(save_dialog) } else if CHECK_KEY("MULTISELECT") { READBOOL(multiselect) } @@ -136,5 +143,5 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine } } - return show_dialog(parent, save_dialog, title, multiselect, confirm_overwrite, only_dirs, no_symlinks); + return show_dialog(parent, save_dialog, title, folder, multiselect, confirm_overwrite, only_dirs, no_symlinks); } diff --git a/src/calibre/gui2/win_file_dialogs.py b/src/calibre/gui2/win_file_dialogs.py index 6dc18a2e0d..e6955121b4 100644 --- a/src/calibre/gui2/win_file_dialogs.py +++ b/src/calibre/gui2/win_file_dialogs.py @@ -13,6 +13,13 @@ is64bit = sys.maxsize > (1 << 32) base = sys.extensions_location if hasattr(sys, 'new_app_layout') else os.path.dirname(sys.executable) HELPER = os.path.join(base, 'calibre-file-dialogs.exe') +try: + from calibre.constants import filesystem_encoding + from calibre.utils.filenames import expanduser +except ImportError: + filesystem_encoding = 'utf-8' + expanduser = os.path.expanduser + def get_hwnd(widget=None): ewid = None if widget is not None: @@ -61,12 +68,21 @@ class Loop(QEventLoop): QEventLoop.__init__(self) self.dialog_closed.connect(self.exit, type=Qt.QueuedConnection) -def run_file_dialog(parent=None, title=None, allow_multiples=False, only_dirs=False, confirm_overwrite=True, save_as=False, no_symlinks=False): +def run_file_dialog( + parent=None, title=None, initial_folder=None, + allow_multiples=False, only_dirs=False, confirm_overwrite=True, save_as=False, no_symlinks=False +): data = [] if parent is not None: data.append(serialize_hwnd(get_hwnd(parent))) if title is not None: data.append(serialize_string('TITLE', title)) + if initial_folder is not None: + if isinstance(initial_folder, bytes): + initial_folder = initial_folder.decode(filesystem_encoding) + initial_folder = os.path.abspath(expanduser(initial_folder)) + if os.path.isdir(initial_folder): + data.append(serialize_string('FOLDER', initial_folder)) if no_symlinks: data.append(serialize_binary('NO_SYMLINKS', no_symlinks)) if save_as: @@ -96,7 +112,7 @@ if __name__ == '__main__': q = QMainWindow() def clicked(): - print(run_file_dialog(b, 'Testing dialogs', only_dirs=True)), sys.stdout.flush() + print(run_file_dialog(b, 'Testing dialogs', '~')), sys.stdout.flush() b = QPushButton('click me') b.clicked.connect(clicked)