From 72dd2a5e005531353bb97b9c9c35529610ebab9d Mon Sep 17 00:00:00 2001 From: John Brooks Date: Mon, 15 Mar 2010 15:29:01 +0100 Subject: Use the vista-style native dialog for QFileDialog::getExistingDirectory Use IFileOpenDialog with FOS_PICKFOLDERS instead of SHBrowseForFolder as the native directory browse dialog on Vista. This provides a much better UI and is consistent with Vista UX. Old behavior is retained for pre-vista systems. Merge-request: 488 Reviewed-by: Denis Dzyubenko --- src/gui/dialogs/qfiledialog_win.cpp | 62 +++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/gui/dialogs/qfiledialog_win.cpp b/src/gui/dialogs/qfiledialog_win.cpp index 3120938..afeed8e 100644 --- a/src/gui/dialogs/qfiledialog_win.cpp +++ b/src/gui/dialogs/qfiledialog_win.cpp @@ -583,6 +583,63 @@ static QStringList qt_win_CID_get_open_file_names(const QFileDialogArgs &args, return result; } +QString qt_win_CID_get_existing_directory(const QFileDialogArgs &args) +{ + QString result; + QDialog modal_widget; + modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true); + modal_widget.setParent(args.parent, Qt::Window); + QApplicationPrivate::enterModal(&modal_widget); + + IFileOpenDialog *pfd = 0; + HRESULT hr = CoCreateInstance(QT_CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, + QT_IID_IFileOpenDialog, reinterpret_cast(&pfd)); + + if (SUCCEEDED(hr)) { + qt_win_set_IFileDialogOptions(pfd, args.selection, + args.directory, args.caption, + QStringList(), QFileDialog::ExistingFiles, + args.options); + + // Set the FOS_PICKFOLDERS flag + DWORD newOptions; + hr = pfd->GetOptions(&newOptions); + newOptions |= FOS_PICKFOLDERS; + if (SUCCEEDED(hr) && SUCCEEDED((hr = pfd->SetOptions(newOptions)))) { + QWidget *parentWindow = args.parent; + if (parentWindow) + parentWindow = parentWindow->window(); + else + parentWindow = QApplication::activeWindow(); + + // Show the file dialog. + hr = pfd->Show(parentWindow ? parentWindow->winId() : 0); + if (SUCCEEDED(hr)) { + // Retrieve the result + IShellItem *psi = 0; + hr = pfd->GetResult(&psi); + if (SUCCEEDED(hr)) { + // Retrieve the file name from shell item. + wchar_t *pszPath; + hr = psi->GetDisplayName(SIGDN_FILESYSPATH, &pszPath); + if (SUCCEEDED(hr)) { + result = QString::fromWCharArray(pszPath); + CoTaskMemFree(pszPath); + } + psi->Release(); // Free the current item. + } + } + } + } + QApplicationPrivate::leaveModal(&modal_widget); + + qt_win_eatMouseMove(); + + if (pfd) + pfd->Release(); + return result; +} + #endif QStringList qt_win_get_open_file_names(const QFileDialogArgs &args, @@ -701,6 +758,11 @@ static int __stdcall winGetExistDirCallbackProc(HWND hwnd, QString qt_win_get_existing_directory(const QFileDialogArgs &args) { +#ifndef Q_WS_WINCE + if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) + return qt_win_CID_get_existing_directory(args); +#endif + QString currentDir = QDir::currentPath(); QString result; QWidget *parent = args.parent; -- cgit v0.12