diff options
author | Lars Knoll <lars.knoll@nokia.com> | 2009-03-23 09:34:13 (GMT) |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2009-03-23 09:34:13 (GMT) |
commit | 67ad0519fd165acee4a4d2a94fa502e9e4847bd0 (patch) | |
tree | 1dbf50b3dff8d5ca7e9344733968c72704eb15ff /src/qt3support/dialogs/q3filedialog_win.cpp | |
download | Qt-67ad0519fd165acee4a4d2a94fa502e9e4847bd0.zip Qt-67ad0519fd165acee4a4d2a94fa502e9e4847bd0.tar.gz Qt-67ad0519fd165acee4a4d2a94fa502e9e4847bd0.tar.bz2 |
Long live Qt!
Diffstat (limited to 'src/qt3support/dialogs/q3filedialog_win.cpp')
-rw-r--r-- | src/qt3support/dialogs/q3filedialog_win.cpp | 749 |
1 files changed, 749 insertions, 0 deletions
diff --git a/src/qt3support/dialogs/q3filedialog_win.cpp b/src/qt3support/dialogs/q3filedialog_win.cpp new file mode 100644 index 0000000..1be797a --- /dev/null +++ b/src/qt3support/dialogs/q3filedialog_win.cpp @@ -0,0 +1,749 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "q3filedialog.h" + +#ifndef QT_NO_FILEDIALOG + +#include "qapplication.h" +#include "private/qapplication_p.h" +#include "qt_windows.h" +#include "qregexp.h" +#include "qbuffer.h" +#include "qdir.h" +#include "qstringlist.h" +#include "qlibrary.h" + +#ifndef QT_NO_THREAD +# include "private/qmutexpool_p.h" +#endif + +#include <shlobj.h> + +#ifdef Q_OS_WINCE +#include <commdlg.h> +#endif + +QT_BEGIN_NAMESPACE + +// Don't remove the lines below! +// +// resolving the W methods manually is needed, because Windows 95 doesn't include +// these methods in Shell32.lib (not even stubs!), so you'd get an unresolved symbol +// when Qt calls getEsistingDirectory(), etc. +typedef LPITEMIDLIST (WINAPI *PtrSHBrowseForFolder)(BROWSEINFO*); +static PtrSHBrowseForFolder ptrSHBrowseForFolder = 0; +typedef BOOL (WINAPI *PtrSHGetPathFromIDList)(LPITEMIDLIST,LPWSTR); +static PtrSHGetPathFromIDList ptrSHGetPathFromIDList = 0; + +static void resolveLibs() +{ +#ifndef Q_OS_WINCE + static bool triedResolve = false; + + if (!triedResolve) { +#ifndef QT_NO_THREAD + // protect initialization + QMutexLocker locker(QMutexPool::globalInstanceGet(&triedResolve)); + // check triedResolve again, since another thread may have already + // done the initialization + if (triedResolve) { + // another thread did initialize the security function pointers, + // so we shouldn't do it again. + return; + } +#endif + + triedResolve = true; + if (qt_winUnicode()) { + QLibrary lib(QLatin1String("shell32")); + ptrSHBrowseForFolder = (PtrSHBrowseForFolder) lib.resolve("SHBrowseForFolderW"); + ptrSHGetPathFromIDList = (PtrSHGetPathFromIDList) lib.resolve("SHGetPathFromIDListW"); + } + } +#endif +} +#ifdef Q_OS_WINCE +#define PtrSHBrowseForFolder SHBrowseForFolder ; +#define PtrSHGetPathFromIDList SHGetPathFromIDList; +#endif + + +extern const char qt3_file_dialog_filter_reg_exp[]; // defined in qfiledialog.cpp + +const int maxNameLen = 1023; +const int maxMultiLen = 65535; + +// Returns the wildcard part of a filter. +static QString extractFilter(const QString& rawFilter) +{ + QString result = rawFilter; + QRegExp r(QString::fromLatin1(qt3_file_dialog_filter_reg_exp)); + int index = r.indexIn(result); + if (index >= 0) + result = r.cap(2); + return result.replace(QLatin1Char(' '), QLatin1Char(';')); +} + +// Makes a list of filters from ;;-separated text. +static QStringList makeFiltersList(const QString &filter) +{ + QString f(filter); + + if (f.isEmpty()) + f = Q3FileDialog::tr("All Files (*.*)"); + + if (f.isEmpty()) + return QStringList(); + + int i = f.find(QLatin1String(";;"), 0); + QString sep(QLatin1String(";;")); + if (i == -1) { + if (f.find(QLatin1String("\n"), 0) != -1) { + sep = QLatin1String("\n"); + i = f.find(sep, 0); + } + } + + return QStringList::split(sep, f ); +} + +// Makes a NUL-oriented Windows filter from a Qt filter. +static QString winFilter(const QString& filter) +{ + QStringList filterLst = makeFiltersList(filter); + QStringList::Iterator it = filterLst.begin(); + QString winfilters; + for (; it != filterLst.end(); ++it) { + winfilters += *it; + winfilters += QChar::null; + winfilters += extractFilter(*it); + winfilters += QChar::null; + } + winfilters += QChar::null; + return winfilters; +} + +static QString selFilter(const QString& filter, DWORD idx) +{ + QStringList filterLst = makeFiltersList(filter); + return filterLst[(int)idx - 1]; +} + +#ifndef Q_OS_WINCE +// Static vars for OFNA funcs: +static QByteArray aInitDir; +static QByteArray aInitSel; +static QByteArray aTitle; +static QByteArray aFilter; +// Use ANSI strings and API + +// If you change this, then make sure you change makeOFN (below) too +static +OPENFILENAMEA* makeOFNA(QWidget* parent, + const QString& initialSelection, + const QString& initialDirectory, + const QString& title, + const QString& filters, + Q3FileDialog::Mode mode) +{ + if (parent) + parent = parent->window(); + else + parent = qApp->activeWindow(); + + aTitle = title.local8Bit(); + aInitDir = QDir::toNativeSeparators(initialDirectory).local8Bit(); + if (initialSelection.isEmpty()) + aInitSel = ""; + else + aInitSel = QDir::toNativeSeparators(initialSelection).local8Bit(); + int maxLen = mode == Q3FileDialog::ExistingFiles ? maxMultiLen : maxNameLen; + aInitSel.resize(maxLen + 1); // make room for return value + aFilter = filters.local8Bit(); + + OPENFILENAMEA* ofn = new OPENFILENAMEA; + memset(ofn, 0, sizeof(OPENFILENAMEA)); + +#if defined(Q_CC_BOR) && (WINVER >= 0x0500) && (_WIN32_WINNT >= 0x0500) + // according to the MSDN, this should also be necessary for MSVC, but + // OPENFILENAME_SIZE_VERSION_400A is in not Microsoft header, as it seems + if (QApplication::winVersion()==Qt::WV_NT || QApplication::winVersion()&Qt::WV_DOS_based) { + ofn->lStructSize= OPENFILENAME_SIZE_VERSION_400A; + } else { + ofn->lStructSize= sizeof(OPENFILENAMEA); + } +#else + ofn->lStructSize = sizeof(OPENFILENAMEA); +#endif + ofn->hwndOwner = parent ? parent->winId() : 0; + ofn->lpstrFilter = aFilter; + ofn->lpstrFile = aInitSel.data(); + ofn->nMaxFile = maxLen; + ofn->lpstrInitialDir = aInitDir.data(); + ofn->lpstrTitle = aTitle.data(); + ofn->Flags = (OFN_NOCHANGEDIR | OFN_HIDEREADONLY); + + if (mode == Q3FileDialog::ExistingFile || + mode == Q3FileDialog::ExistingFiles) + ofn->Flags |= (OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST); + if (mode == Q3FileDialog::ExistingFiles) + ofn->Flags |= (OFN_ALLOWMULTISELECT | OFN_EXPLORER); + + return ofn; +} + +static void cleanUpOFNA(OPENFILENAMEA** ofn) +{ + delete *ofn; + *ofn = 0; +} +#endif + +static QString tFilters, tTitle, tInitDir; + +#ifdef UNICODE +// If you change this, then make sure you change makeOFNA (above) too +static +OPENFILENAME* makeOFN(QWidget* parent, + const QString& initialSelection, + const QString& initialDirectory, + const QString& title, + const QString& filters, + Q3FileDialog::Mode mode) +{ + if (parent) + parent = parent->window(); + else + parent = qApp->activeWindow(); + + tInitDir = QDir::toNativeSeparators(initialDirectory); + tFilters = filters; + tTitle = title; + QString initSel = QDir::toNativeSeparators(initialSelection); + + int maxLen = mode == Q3FileDialog::ExistingFiles ? maxMultiLen : maxNameLen; + TCHAR *tInitSel = new TCHAR[maxLen+1]; + if (initSel.length() > 0 && initSel.length() <= maxLen) + memcpy(tInitSel, initSel.ucs2(), (initSel.length()+1)*sizeof(QChar)); + else + tInitSel[0] = 0; + + OPENFILENAME* ofn = new OPENFILENAME; + memset(ofn, 0, sizeof(OPENFILENAME)); + +#if defined(Q_CC_BOR) && (WINVER >= 0x0500) && (_WIN32_WINNT >= 0x0500) + // according to the MSDN, this should also be necessary for MSVC, but + // OPENFILENAME_SIZE_VERSION_400 is in not Microsoft header, as it seems + if (QApplication::winVersion()==Qt::WV_NT || QApplication::winVersion()&Qt::WV_DOS_based) { + ofn->lStructSize= OPENFILENAME_SIZE_VERSION_400; + } else { + ofn->lStructSize = sizeof(OPENFILENAME); + } +#else + ofn->lStructSize = sizeof(OPENFILENAME); +#endif + ofn->hwndOwner = parent ? parent->winId() : 0; + ofn->lpstrFilter = (TCHAR *)tFilters.ucs2(); + ofn->lpstrFile = tInitSel; + ofn->nMaxFile = maxLen; + ofn->lpstrInitialDir = (TCHAR *)tInitDir.ucs2(); + ofn->lpstrTitle = (TCHAR *)tTitle.ucs2(); + ofn->Flags = (OFN_NOCHANGEDIR | OFN_HIDEREADONLY); + + if (mode == Q3FileDialog::ExistingFile || + mode == Q3FileDialog::ExistingFiles) + ofn->Flags |= (OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST); + if (mode == Q3FileDialog::ExistingFiles) + ofn->Flags |= (OFN_ALLOWMULTISELECT | OFN_EXPLORER); + + return ofn; +} + + +static void cleanUpOFN(OPENFILENAME** ofn) +{ + delete (*ofn)->lpstrFile; + delete *ofn; + *ofn = 0; +} + +#endif // UNICODE + +QString Q3FileDialog::winGetOpenFileName(const QString &initialSelection, + const QString &filter, + QString* initialDirectory, + QWidget *parent, const char* /*name*/, + const QString& caption, + QString* selectedFilter) +{ + QString result; + + QString isel = initialSelection; + + if (initialDirectory && initialDirectory->left(5) == QLatin1String("file:")) + initialDirectory->remove(0, 5); + QFileInfo fi(*initialDirectory); + + if (initialDirectory && !fi.isDir()) { + *initialDirectory = fi.dirPath(true); + if (isel.isEmpty()) + isel = fi.fileName(); + } + + if (!fi.exists()) + *initialDirectory = QDir::homeDirPath(); + + QString title = caption; + if (title.isNull()) + title = tr("Open"); + + DWORD selFilIdx = 0; + + int idx = 0; + if (selectedFilter && !selectedFilter->isEmpty()) { + QStringList filterLst = makeFiltersList(filter); + idx = filterLst.findIndex(*selectedFilter); + } + + if (parent) { + QEvent e(QEvent::WindowBlocked); + QApplication::sendEvent(parent, &e); + QApplicationPrivate::enterModal(parent); + } + QT_WA({ + // Use Unicode strings and API + OPENFILENAME* ofn = makeOFN(parent, isel, + *initialDirectory, title, + winFilter(filter), ExistingFile); + if (idx) + ofn->nFilterIndex = idx + 1; + if (GetOpenFileName(ofn)) { + result = QString::fromUcs2((ushort*)ofn->lpstrFile); + selFilIdx = ofn->nFilterIndex; + } + cleanUpOFN(&ofn); + } , { + // Use ANSI strings and API + OPENFILENAMEA* ofn = makeOFNA(parent, isel, + *initialDirectory, title, + winFilter(filter), ExistingFile); + if (idx) + ofn->nFilterIndex = idx + 1; + if (GetOpenFileNameA(ofn)) { + result = QString::fromLocal8Bit(ofn->lpstrFile); + selFilIdx = ofn->nFilterIndex; + } + cleanUpOFNA(&ofn); + }); + if (parent) { + QApplicationPrivate::leaveModal(parent); + QEvent e(QEvent::WindowUnblocked); + QApplication::sendEvent(parent, &e); + } + + if (result.isEmpty()) { + return result; + } + else { + QFileInfo fi(result); + *initialDirectory = fi.dirPath(); + if (selectedFilter) + *selectedFilter = selFilter(filter, selFilIdx); + return fi.absFilePath(); + } +} + + +QString Q3FileDialog::winGetSaveFileName(const QString &initialSelection, + const QString &filter, + QString* initialDirectory, + QWidget *parent, const char* /*name*/, + const QString& caption, + QString* selectedFilter) +{ + QString result; + + QString isel = initialSelection; + if (initialDirectory && initialDirectory->left(5) == QLatin1String("file:")) + initialDirectory->remove(0, 5); + QFileInfo fi(*initialDirectory); + + if (initialDirectory && !fi.isDir()) { + *initialDirectory = fi.dirPath(true); + if (isel.isEmpty()) + isel = fi.fileName(); + } + + if (!fi.exists()) + *initialDirectory = QDir::homeDirPath(); + + QString title = caption; + if (title.isNull()) + title = tr("Save As"); + + DWORD selFilIdx = 0; + + int idx = 0; + if (selectedFilter && !selectedFilter->isEmpty()) { + QStringList filterLst = makeFiltersList(filter); + idx = filterLst.findIndex(*selectedFilter); + } + + if (parent) { + QEvent e(QEvent::WindowBlocked); + QApplication::sendEvent(parent, &e); + QApplicationPrivate::enterModal(parent); + } + QT_WA({ + // Use Unicode strings and API + OPENFILENAME* ofn = makeOFN(parent, isel, + *initialDirectory, title, + winFilter(filter), AnyFile); + if (idx) + ofn->nFilterIndex = idx + 1; + if (GetSaveFileName(ofn)) { + result = QString::fromUcs2((ushort*)ofn->lpstrFile); + selFilIdx = ofn->nFilterIndex; + } + cleanUpOFN(&ofn); + } , { + // Use ANSI strings and API + OPENFILENAMEA* ofn = makeOFNA(parent, isel, + *initialDirectory, title, + winFilter(filter), AnyFile); + if (idx) + ofn->nFilterIndex = idx + 1; + if (GetSaveFileNameA(ofn)) { + result = QString::fromLocal8Bit(ofn->lpstrFile); + selFilIdx = ofn->nFilterIndex; + } + cleanUpOFNA(&ofn); + }); + if (parent) { + QApplicationPrivate::leaveModal(parent); + QEvent e(QEvent::WindowUnblocked); + QApplication::sendEvent(parent, &e); + } + + if (result.isEmpty()) { + return result; + } + else { + QFileInfo fi(result); + *initialDirectory = fi.dirPath(); + if (selectedFilter) + *selectedFilter = selFilter(filter, selFilIdx); + return fi.absFilePath(); + } +} + + + +QStringList Q3FileDialog::winGetOpenFileNames(const QString &filter, + QString* initialDirectory, + QWidget *parent, + const char* /*name*/, + const QString& caption, + QString* selectedFilter) +{ + QStringList result; + QFileInfo fi; + QDir dir; + QString isel; + + if (initialDirectory && initialDirectory->left(5) == QLatin1String("file:")) + initialDirectory->remove(0, 5); + fi = QFileInfo(*initialDirectory); + + if (initialDirectory && !fi.isDir()) { + *initialDirectory = fi.dirPath(true); + isel = fi.fileName(); + } + + if (!fi.exists()) + *initialDirectory = QDir::homeDirPath(); + + QString title = caption; + if (title.isNull()) + title = tr("Open "); + + DWORD selFilIdx = 0; + + int idx = 0; + if (selectedFilter && !selectedFilter->isEmpty()) { + QStringList filterLst = makeFiltersList(filter); + idx = filterLst.findIndex(*selectedFilter); + } + + if (parent) { + QEvent e(QEvent::WindowBlocked); + QApplication::sendEvent(parent, &e); + QApplicationPrivate::enterModal(parent); + } + QT_WA({ + OPENFILENAME* ofn = makeOFN(parent, isel, + *initialDirectory, title, + winFilter(filter), ExistingFiles); + if (idx) + ofn->nFilterIndex = idx + 1; + if (GetOpenFileName(ofn)) { + QString fileOrDir = QString::fromUcs2((ushort*)ofn->lpstrFile); + selFilIdx = ofn->nFilterIndex; + int offset = fileOrDir.length() + 1; + if (ofn->lpstrFile[offset] == 0) { + // Only one file selected; has full path + fi.setFile(fileOrDir); + QString res = fi.absFilePath(); + if (!res.isEmpty()) + result.append(res); + } + else { + // Several files selected; first string is path + dir.setPath(fileOrDir); + QString f; + while(!(f = QString::fromUcs2((ushort*)ofn->lpstrFile+offset)).isEmpty()) { + fi.setFile(dir, f); + QString res = fi.absFilePath(); + if (!res.isEmpty()) + result.append(res); + offset += f.length() + 1; + } + } + } + cleanUpOFN(&ofn); + } , { + OPENFILENAMEA* ofn = makeOFNA(parent, isel, + *initialDirectory, title, + winFilter(filter), ExistingFiles); + if (idx) + ofn->nFilterIndex = idx + 1; + if (GetOpenFileNameA(ofn)) { + QByteArray fileOrDir(ofn->lpstrFile); + selFilIdx = ofn->nFilterIndex; + int offset = fileOrDir.length() + 1; + if (ofn->lpstrFile[offset] == '\0') { + // Only one file selected; has full path + fi.setFile(QString::fromLocal8Bit(fileOrDir)); + QString res = fi.absFilePath(); + if (!res.isEmpty()) + result.append(res); + } + else { + // Several files selected; first string is path + dir.setPath(QString::fromLocal8Bit(fileOrDir)); + QByteArray f; + while(!(f = QByteArray(ofn->lpstrFile + offset)).isEmpty()) { + fi.setFile(dir, QString::fromLocal8Bit(f)); + QString res = fi.absFilePath(); + if (!res.isEmpty()) + result.append(res); + offset += f.length() + 1; + } + } + cleanUpOFNA(&ofn); + } + }); + if (parent) { + QApplicationPrivate::leaveModal(parent); + QEvent e(QEvent::WindowUnblocked); + QApplication::sendEvent(parent, &e); + } + + if (!result.isEmpty()) { + *initialDirectory = fi.dirPath(); // only save the path if there is a result + if (selectedFilter) + *selectedFilter = selFilter(filter, selFilIdx); + } + return result; +} + +// MFC Directory Dialog. Contrib: Steve Williams (minor parts from Scott Powers) + +static int __stdcall winGetExistDirCallbackProc(HWND hwnd, + UINT uMsg, + LPARAM lParam, + LPARAM lpData) +{ +#ifndef Q_OS_WINCE + if (uMsg == BFFM_INITIALIZED && lpData != 0) { + QString *initDir = (QString *)(lpData); + if (!initDir->isEmpty()) { + // ### Lars asks: is this correct for the A version???? + QT_WA({ + SendMessage(hwnd, BFFM_SETSELECTION, TRUE, Q_ULONG(initDir->ucs2())); + } , { + SendMessageA(hwnd, BFFM_SETSELECTION, TRUE, Q_ULONG(initDir->ucs2())); + }); + } + } else if (uMsg == BFFM_SELCHANGED) { + QT_WA({ + resolveLibs(); + TCHAR path[MAX_PATH]; + ptrSHGetPathFromIDList(LPITEMIDLIST(lParam), path); + QString tmpStr = QString::fromUcs2((ushort*)path); + if (!tmpStr.isEmpty()) + SendMessage(hwnd, BFFM_ENABLEOK, 1, 1); + else + SendMessage(hwnd, BFFM_ENABLEOK, 0, 0); + SendMessage(hwnd, BFFM_SETSTATUSTEXT, 1, Q_ULONG(path)); + } , { + char path[MAX_PATH]; + SHGetPathFromIDListA(LPITEMIDLIST(lParam), path); + QString tmpStr = QString::fromLocal8Bit(path); + if (!tmpStr.isEmpty()) + SendMessageA(hwnd, BFFM_ENABLEOK, 1, 1); + else + SendMessageA(hwnd, BFFM_ENABLEOK, 0, 0); + SendMessageA(hwnd, BFFM_SETSTATUSTEXT, 1, Q_ULONG(path)); + }); + } +#endif + return 0; +} + +#ifndef BIF_NEWDIALOGSTYLE +#define BIF_NEWDIALOGSTYLE 0x0040 // Use the new dialog layout with the ability to resize +#endif + + +QString Q3FileDialog::winGetExistingDirectory(const QString& initialDirectory, + QWidget *parent, + const char* /*name*/, + const QString& caption) +{ +#ifndef Q_OS_WINCE + QString currentDir = QDir::currentDirPath(); + QString result; + if (parent) + parent = parent->window(); + else + parent = qApp->activeWindow(); + QString title = caption; + if (title.isNull()) + title = tr("Select a Directory"); + + if (parent) { + QEvent e(QEvent::WindowBlocked); + QApplication::sendEvent(parent, &e); + QApplicationPrivate::enterModal(parent); + } + QT_WA({ + resolveLibs(); + QString initDir = QDir::toNativeSeparators(initialDirectory); + TCHAR path[MAX_PATH]; + TCHAR initPath[MAX_PATH]; + initPath[0] = 0; + path[0] = 0; + tTitle = title; + BROWSEINFO bi; + bi.hwndOwner = (parent ? parent->winId() : 0); + bi.pidlRoot = NULL; + bi.lpszTitle = (TCHAR*)tTitle.ucs2(); + bi.pszDisplayName = initPath; + bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT | BIF_NEWDIALOGSTYLE; + bi.lpfn = winGetExistDirCallbackProc; + bi.lParam = Q_ULONG(&initDir); + LPITEMIDLIST pItemIDList = ptrSHBrowseForFolder(&bi); + if (pItemIDList) { + ptrSHGetPathFromIDList(pItemIDList, path); + IMalloc *pMalloc; + if (SHGetMalloc(&pMalloc) != NOERROR) + result.clear(); + else { + pMalloc->Free(pItemIDList); + pMalloc->Release(); + result = QString::fromUcs2((ushort*)path); + } + } else + result.clear(); + tTitle.clear(); + } , { + QString initDir = QDir::toNativeSeparators(initialDirectory); + char path[MAX_PATH]; + char initPath[MAX_PATH]; + QByteArray ctitle = title.toLocal8Bit(); + initPath[0]=0; + path[0]=0; + BROWSEINFOA bi; + bi.hwndOwner = (parent ? parent->winId() : 0); + bi.pidlRoot = NULL; + bi.lpszTitle = ctitle; + bi.pszDisplayName = initPath; + bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT | BIF_NEWDIALOGSTYLE; + bi.lpfn = winGetExistDirCallbackProc; + bi.lParam = Q_ULONG(&initDir); + LPITEMIDLIST pItemIDList = SHBrowseForFolderA(&bi); + if (pItemIDList) { + SHGetPathFromIDListA(pItemIDList, path); + IMalloc *pMalloc; + if (SHGetMalloc(&pMalloc) != NOERROR) + result.clear(); + else { + pMalloc->Free(pItemIDList); + pMalloc->Release(); + result = QString::fromLocal8Bit(path); + } + } else + result.clear(); + }); + if (parent) { + QApplicationPrivate::leaveModal(parent); + QEvent e(QEvent::WindowUnblocked); + QApplication::sendEvent(parent, &e); + } + + // Due to a bug on Windows Me, we need to reset the current + // directory + if ((qWinVersion() == Qt::WV_98 || qWinVersion() == Qt::WV_Me) && QDir::currentDirPath() != currentDir) + QDir::setCurrent(currentDir); + + if (!result.isEmpty()) + result.replace(QLatin1String("\\"), QLatin1String("/")); + return result; +#else + return QString(); +#endif +} + +QT_END_NAMESPACE + +#endif |