source: trunk/src/qt3support/dialogs/q3filedialog_win.cpp@ 104

Last change on this file since 104 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 24.7 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the Qt3Support module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "q3filedialog.h"
43
44#ifndef QT_NO_FILEDIALOG
45
46#include "qapplication.h"
47#include "private/qapplication_p.h"
48#include "qt_windows.h"
49#include "qregexp.h"
50#include "qbuffer.h"
51#include "qdir.h"
52#include "qstringlist.h"
53#include "qlibrary.h"
54
55#ifndef QT_NO_THREAD
56# include "private/qmutexpool_p.h"
57#endif
58
59#include <shlobj.h>
60
61#ifdef Q_OS_WINCE
62#include <commdlg.h>
63#endif
64
65QT_BEGIN_NAMESPACE
66
67// Don't remove the lines below!
68//
69// resolving the W methods manually is needed, because Windows 95 doesn't include
70// these methods in Shell32.lib (not even stubs!), so you'd get an unresolved symbol
71// when Qt calls getEsistingDirectory(), etc.
72typedef LPITEMIDLIST (WINAPI *PtrSHBrowseForFolder)(BROWSEINFO*);
73static PtrSHBrowseForFolder ptrSHBrowseForFolder = 0;
74typedef BOOL (WINAPI *PtrSHGetPathFromIDList)(LPITEMIDLIST,LPWSTR);
75static PtrSHGetPathFromIDList ptrSHGetPathFromIDList = 0;
76
77static void resolveLibs()
78{
79#ifndef Q_OS_WINCE
80 static bool triedResolve = false;
81
82 if (!triedResolve) {
83#ifndef QT_NO_THREAD
84 // protect initialization
85 QMutexLocker locker(QMutexPool::globalInstanceGet(&triedResolve));
86 // check triedResolve again, since another thread may have already
87 // done the initialization
88 if (triedResolve) {
89 // another thread did initialize the security function pointers,
90 // so we shouldn't do it again.
91 return;
92 }
93#endif
94
95 triedResolve = true;
96 if (qt_winUnicode()) {
97 QLibrary lib(QLatin1String("shell32"));
98 ptrSHBrowseForFolder = (PtrSHBrowseForFolder) lib.resolve("SHBrowseForFolderW");
99 ptrSHGetPathFromIDList = (PtrSHGetPathFromIDList) lib.resolve("SHGetPathFromIDListW");
100 }
101 }
102#endif
103}
104#ifdef Q_OS_WINCE
105#define PtrSHBrowseForFolder SHBrowseForFolder ;
106#define PtrSHGetPathFromIDList SHGetPathFromIDList;
107#endif
108
109
110extern const char qt3_file_dialog_filter_reg_exp[]; // defined in qfiledialog.cpp
111
112const int maxNameLen = 1023;
113const int maxMultiLen = 65535;
114
115// Returns the wildcard part of a filter.
116static QString extractFilter(const QString& rawFilter)
117{
118 QString result = rawFilter;
119 QRegExp r(QString::fromLatin1(qt3_file_dialog_filter_reg_exp));
120 int index = r.indexIn(result);
121 if (index >= 0)
122 result = r.cap(2);
123 return result.replace(QLatin1Char(' '), QLatin1Char(';'));
124}
125
126// Makes a list of filters from ;;-separated text.
127static QStringList makeFiltersList(const QString &filter)
128{
129 QString f(filter);
130
131 if (f.isEmpty())
132 f = Q3FileDialog::tr("All Files (*.*)");
133
134 if (f.isEmpty())
135 return QStringList();
136
137 int i = f.find(QLatin1String(";;"), 0);
138 QString sep(QLatin1String(";;"));
139 if (i == -1) {
140 if (f.find(QLatin1String("\n"), 0) != -1) {
141 sep = QLatin1String("\n");
142 i = f.find(sep, 0);
143 }
144 }
145
146 return QStringList::split(sep, f );
147}
148
149// Makes a NUL-oriented Windows filter from a Qt filter.
150static QString winFilter(const QString& filter)
151{
152 QStringList filterLst = makeFiltersList(filter);
153 QStringList::Iterator it = filterLst.begin();
154 QString winfilters;
155 for (; it != filterLst.end(); ++it) {
156 winfilters += *it;
157 winfilters += QChar::null;
158 winfilters += extractFilter(*it);
159 winfilters += QChar::null;
160 }
161 winfilters += QChar::null;
162 return winfilters;
163}
164
165static QString selFilter(const QString& filter, DWORD idx)
166{
167 QStringList filterLst = makeFiltersList(filter);
168 return filterLst[(int)idx - 1];
169}
170
171#ifndef Q_OS_WINCE
172// Static vars for OFNA funcs:
173static QByteArray aInitDir;
174static QByteArray aInitSel;
175static QByteArray aTitle;
176static QByteArray aFilter;
177// Use ANSI strings and API
178
179// If you change this, then make sure you change makeOFN (below) too
180static
181OPENFILENAMEA* makeOFNA(QWidget* parent,
182 const QString& initialSelection,
183 const QString& initialDirectory,
184 const QString& title,
185 const QString& filters,
186 Q3FileDialog::Mode mode)
187{
188 if (parent)
189 parent = parent->window();
190 else
191 parent = qApp->activeWindow();
192
193 aTitle = title.local8Bit();
194 aInitDir = QDir::toNativeSeparators(initialDirectory).local8Bit();
195 if (initialSelection.isEmpty())
196 aInitSel = "";
197 else
198 aInitSel = QDir::toNativeSeparators(initialSelection).local8Bit();
199 int maxLen = mode == Q3FileDialog::ExistingFiles ? maxMultiLen : maxNameLen;
200 aInitSel.resize(maxLen + 1); // make room for return value
201 aFilter = filters.local8Bit();
202
203 OPENFILENAMEA* ofn = new OPENFILENAMEA;
204 memset(ofn, 0, sizeof(OPENFILENAMEA));
205
206#if defined(Q_CC_BOR) && (WINVER >= 0x0500) && (_WIN32_WINNT >= 0x0500)
207 // according to the MSDN, this should also be necessary for MSVC, but
208 // OPENFILENAME_SIZE_VERSION_400A is in not Microsoft header, as it seems
209 if (QApplication::winVersion()==Qt::WV_NT || QApplication::winVersion()&Qt::WV_DOS_based) {
210 ofn->lStructSize= OPENFILENAME_SIZE_VERSION_400A;
211 } else {
212 ofn->lStructSize= sizeof(OPENFILENAMEA);
213 }
214#else
215 ofn->lStructSize = sizeof(OPENFILENAMEA);
216#endif
217 ofn->hwndOwner = parent ? parent->winId() : 0;
218 ofn->lpstrFilter = aFilter;
219 ofn->lpstrFile = aInitSel.data();
220 ofn->nMaxFile = maxLen;
221 ofn->lpstrInitialDir = aInitDir.data();
222 ofn->lpstrTitle = aTitle.data();
223 ofn->Flags = (OFN_NOCHANGEDIR | OFN_HIDEREADONLY);
224
225 if (mode == Q3FileDialog::ExistingFile ||
226 mode == Q3FileDialog::ExistingFiles)
227 ofn->Flags |= (OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST);
228 if (mode == Q3FileDialog::ExistingFiles)
229 ofn->Flags |= (OFN_ALLOWMULTISELECT | OFN_EXPLORER);
230
231 return ofn;
232}
233
234static void cleanUpOFNA(OPENFILENAMEA** ofn)
235{
236 delete *ofn;
237 *ofn = 0;
238}
239#endif
240
241static QString tFilters, tTitle, tInitDir;
242
243#ifdef UNICODE
244// If you change this, then make sure you change makeOFNA (above) too
245static
246OPENFILENAME* makeOFN(QWidget* parent,
247 const QString& initialSelection,
248 const QString& initialDirectory,
249 const QString& title,
250 const QString& filters,
251 Q3FileDialog::Mode mode)
252{
253 if (parent)
254 parent = parent->window();
255 else
256 parent = qApp->activeWindow();
257
258 tInitDir = QDir::toNativeSeparators(initialDirectory);
259 tFilters = filters;
260 tTitle = title;
261 QString initSel = QDir::toNativeSeparators(initialSelection);
262
263 int maxLen = mode == Q3FileDialog::ExistingFiles ? maxMultiLen : maxNameLen;
264 TCHAR *tInitSel = new TCHAR[maxLen+1];
265 if (initSel.length() > 0 && initSel.length() <= maxLen)
266 memcpy(tInitSel, initSel.ucs2(), (initSel.length()+1)*sizeof(QChar));
267 else
268 tInitSel[0] = 0;
269
270 OPENFILENAME* ofn = new OPENFILENAME;
271 memset(ofn, 0, sizeof(OPENFILENAME));
272
273#if defined(Q_CC_BOR) && (WINVER >= 0x0500) && (_WIN32_WINNT >= 0x0500)
274 // according to the MSDN, this should also be necessary for MSVC, but
275 // OPENFILENAME_SIZE_VERSION_400 is in not Microsoft header, as it seems
276 if (QApplication::winVersion()==Qt::WV_NT || QApplication::winVersion()&Qt::WV_DOS_based) {
277 ofn->lStructSize= OPENFILENAME_SIZE_VERSION_400;
278 } else {
279 ofn->lStructSize = sizeof(OPENFILENAME);
280 }
281#else
282 ofn->lStructSize = sizeof(OPENFILENAME);
283#endif
284 ofn->hwndOwner = parent ? parent->winId() : 0;
285 ofn->lpstrFilter = (TCHAR *)tFilters.ucs2();
286 ofn->lpstrFile = tInitSel;
287 ofn->nMaxFile = maxLen;
288 ofn->lpstrInitialDir = (TCHAR *)tInitDir.ucs2();
289 ofn->lpstrTitle = (TCHAR *)tTitle.ucs2();
290 ofn->Flags = (OFN_NOCHANGEDIR | OFN_HIDEREADONLY);
291
292 if (mode == Q3FileDialog::ExistingFile ||
293 mode == Q3FileDialog::ExistingFiles)
294 ofn->Flags |= (OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST);
295 if (mode == Q3FileDialog::ExistingFiles)
296 ofn->Flags |= (OFN_ALLOWMULTISELECT | OFN_EXPLORER);
297
298 return ofn;
299}
300
301
302static void cleanUpOFN(OPENFILENAME** ofn)
303{
304 delete (*ofn)->lpstrFile;
305 delete *ofn;
306 *ofn = 0;
307}
308
309#endif // UNICODE
310
311QString Q3FileDialog::winGetOpenFileName(const QString &initialSelection,
312 const QString &filter,
313 QString* initialDirectory,
314 QWidget *parent, const char* /*name*/,
315 const QString& caption,
316 QString* selectedFilter)
317{
318 QString result;
319
320 QString isel = initialSelection;
321
322 if (initialDirectory && initialDirectory->left(5) == QLatin1String("file:"))
323 initialDirectory->remove(0, 5);
324 QFileInfo fi(*initialDirectory);
325
326 if (initialDirectory && !fi.isDir()) {
327 *initialDirectory = fi.dirPath(true);
328 if (isel.isEmpty())
329 isel = fi.fileName();
330 }
331
332 if (!fi.exists())
333 *initialDirectory = QDir::homeDirPath();
334
335 QString title = caption;
336 if (title.isNull())
337 title = tr("Open");
338
339 DWORD selFilIdx = 0;
340
341 int idx = 0;
342 if (selectedFilter && !selectedFilter->isEmpty()) {
343 QStringList filterLst = makeFiltersList(filter);
344 idx = filterLst.findIndex(*selectedFilter);
345 }
346
347 if (parent) {
348 QEvent e(QEvent::WindowBlocked);
349 QApplication::sendEvent(parent, &e);
350 QApplicationPrivate::enterModal(parent);
351 }
352 QT_WA({
353 // Use Unicode strings and API
354 OPENFILENAME* ofn = makeOFN(parent, isel,
355 *initialDirectory, title,
356 winFilter(filter), ExistingFile);
357 if (idx)
358 ofn->nFilterIndex = idx + 1;
359 if (GetOpenFileName(ofn)) {
360 result = QString::fromUcs2((ushort*)ofn->lpstrFile);
361 selFilIdx = ofn->nFilterIndex;
362 }
363 cleanUpOFN(&ofn);
364 } , {
365 // Use ANSI strings and API
366 OPENFILENAMEA* ofn = makeOFNA(parent, isel,
367 *initialDirectory, title,
368 winFilter(filter), ExistingFile);
369 if (idx)
370 ofn->nFilterIndex = idx + 1;
371 if (GetOpenFileNameA(ofn)) {
372 result = QString::fromLocal8Bit(ofn->lpstrFile);
373 selFilIdx = ofn->nFilterIndex;
374 }
375 cleanUpOFNA(&ofn);
376 });
377 if (parent) {
378 QApplicationPrivate::leaveModal(parent);
379 QEvent e(QEvent::WindowUnblocked);
380 QApplication::sendEvent(parent, &e);
381 }
382
383 if (result.isEmpty()) {
384 return result;
385 }
386 else {
387 QFileInfo fi(result);
388 *initialDirectory = fi.dirPath();
389 if (selectedFilter)
390 *selectedFilter = selFilter(filter, selFilIdx);
391 return fi.absFilePath();
392 }
393}
394
395
396QString Q3FileDialog::winGetSaveFileName(const QString &initialSelection,
397 const QString &filter,
398 QString* initialDirectory,
399 QWidget *parent, const char* /*name*/,
400 const QString& caption,
401 QString* selectedFilter)
402{
403 QString result;
404
405 QString isel = initialSelection;
406 if (initialDirectory && initialDirectory->left(5) == QLatin1String("file:"))
407 initialDirectory->remove(0, 5);
408 QFileInfo fi(*initialDirectory);
409
410 if (initialDirectory && !fi.isDir()) {
411 *initialDirectory = fi.dirPath(true);
412 if (isel.isEmpty())
413 isel = fi.fileName();
414 }
415
416 if (!fi.exists())
417 *initialDirectory = QDir::homeDirPath();
418
419 QString title = caption;
420 if (title.isNull())
421 title = tr("Save As");
422
423 DWORD selFilIdx = 0;
424
425 int idx = 0;
426 if (selectedFilter && !selectedFilter->isEmpty()) {
427 QStringList filterLst = makeFiltersList(filter);
428 idx = filterLst.findIndex(*selectedFilter);
429 }
430
431 if (parent) {
432 QEvent e(QEvent::WindowBlocked);
433 QApplication::sendEvent(parent, &e);
434 QApplicationPrivate::enterModal(parent);
435 }
436 QT_WA({
437 // Use Unicode strings and API
438 OPENFILENAME* ofn = makeOFN(parent, isel,
439 *initialDirectory, title,
440 winFilter(filter), AnyFile);
441 if (idx)
442 ofn->nFilterIndex = idx + 1;
443 if (GetSaveFileName(ofn)) {
444 result = QString::fromUcs2((ushort*)ofn->lpstrFile);
445 selFilIdx = ofn->nFilterIndex;
446 }
447 cleanUpOFN(&ofn);
448 } , {
449 // Use ANSI strings and API
450 OPENFILENAMEA* ofn = makeOFNA(parent, isel,
451 *initialDirectory, title,
452 winFilter(filter), AnyFile);
453 if (idx)
454 ofn->nFilterIndex = idx + 1;
455 if (GetSaveFileNameA(ofn)) {
456 result = QString::fromLocal8Bit(ofn->lpstrFile);
457 selFilIdx = ofn->nFilterIndex;
458 }
459 cleanUpOFNA(&ofn);
460 });
461 if (parent) {
462 QApplicationPrivate::leaveModal(parent);
463 QEvent e(QEvent::WindowUnblocked);
464 QApplication::sendEvent(parent, &e);
465 }
466
467 if (result.isEmpty()) {
468 return result;
469 }
470 else {
471 QFileInfo fi(result);
472 *initialDirectory = fi.dirPath();
473 if (selectedFilter)
474 *selectedFilter = selFilter(filter, selFilIdx);
475 return fi.absFilePath();
476 }
477}
478
479
480
481QStringList Q3FileDialog::winGetOpenFileNames(const QString &filter,
482 QString* initialDirectory,
483 QWidget *parent,
484 const char* /*name*/,
485 const QString& caption,
486 QString* selectedFilter)
487{
488 QStringList result;
489 QFileInfo fi;
490 QDir dir;
491 QString isel;
492
493 if (initialDirectory && initialDirectory->left(5) == QLatin1String("file:"))
494 initialDirectory->remove(0, 5);
495 fi = QFileInfo(*initialDirectory);
496
497 if (initialDirectory && !fi.isDir()) {
498 *initialDirectory = fi.dirPath(true);
499 isel = fi.fileName();
500 }
501
502 if (!fi.exists())
503 *initialDirectory = QDir::homeDirPath();
504
505 QString title = caption;
506 if (title.isNull())
507 title = tr("Open ");
508
509 DWORD selFilIdx = 0;
510
511 int idx = 0;
512 if (selectedFilter && !selectedFilter->isEmpty()) {
513 QStringList filterLst = makeFiltersList(filter);
514 idx = filterLst.findIndex(*selectedFilter);
515 }
516
517 if (parent) {
518 QEvent e(QEvent::WindowBlocked);
519 QApplication::sendEvent(parent, &e);
520 QApplicationPrivate::enterModal(parent);
521 }
522 QT_WA({
523 OPENFILENAME* ofn = makeOFN(parent, isel,
524 *initialDirectory, title,
525 winFilter(filter), ExistingFiles);
526 if (idx)
527 ofn->nFilterIndex = idx + 1;
528 if (GetOpenFileName(ofn)) {
529 QString fileOrDir = QString::fromUcs2((ushort*)ofn->lpstrFile);
530 selFilIdx = ofn->nFilterIndex;
531 int offset = fileOrDir.length() + 1;
532 if (ofn->lpstrFile[offset] == 0) {
533 // Only one file selected; has full path
534 fi.setFile(fileOrDir);
535 QString res = fi.absFilePath();
536 if (!res.isEmpty())
537 result.append(res);
538 }
539 else {
540 // Several files selected; first string is path
541 dir.setPath(fileOrDir);
542 QString f;
543 while(!(f = QString::fromUcs2((ushort*)ofn->lpstrFile+offset)).isEmpty()) {
544 fi.setFile(dir, f);
545 QString res = fi.absFilePath();
546 if (!res.isEmpty())
547 result.append(res);
548 offset += f.length() + 1;
549 }
550 }
551 }
552 cleanUpOFN(&ofn);
553 } , {
554 OPENFILENAMEA* ofn = makeOFNA(parent, isel,
555 *initialDirectory, title,
556 winFilter(filter), ExistingFiles);
557 if (idx)
558 ofn->nFilterIndex = idx + 1;
559 if (GetOpenFileNameA(ofn)) {
560 QByteArray fileOrDir(ofn->lpstrFile);
561 selFilIdx = ofn->nFilterIndex;
562 int offset = fileOrDir.length() + 1;
563 if (ofn->lpstrFile[offset] == '\0') {
564 // Only one file selected; has full path
565 fi.setFile(QString::fromLocal8Bit(fileOrDir));
566 QString res = fi.absFilePath();
567 if (!res.isEmpty())
568 result.append(res);
569 }
570 else {
571 // Several files selected; first string is path
572 dir.setPath(QString::fromLocal8Bit(fileOrDir));
573 QByteArray f;
574 while(!(f = QByteArray(ofn->lpstrFile + offset)).isEmpty()) {
575 fi.setFile(dir, QString::fromLocal8Bit(f));
576 QString res = fi.absFilePath();
577 if (!res.isEmpty())
578 result.append(res);
579 offset += f.length() + 1;
580 }
581 }
582 cleanUpOFNA(&ofn);
583 }
584 });
585 if (parent) {
586 QApplicationPrivate::leaveModal(parent);
587 QEvent e(QEvent::WindowUnblocked);
588 QApplication::sendEvent(parent, &e);
589 }
590
591 if (!result.isEmpty()) {
592 *initialDirectory = fi.dirPath(); // only save the path if there is a result
593 if (selectedFilter)
594 *selectedFilter = selFilter(filter, selFilIdx);
595 }
596 return result;
597}
598
599// MFC Directory Dialog. Contrib: Steve Williams (minor parts from Scott Powers)
600
601static int __stdcall winGetExistDirCallbackProc(HWND hwnd,
602 UINT uMsg,
603 LPARAM lParam,
604 LPARAM lpData)
605{
606#ifndef Q_OS_WINCE
607 if (uMsg == BFFM_INITIALIZED && lpData != 0) {
608 QString *initDir = (QString *)(lpData);
609 if (!initDir->isEmpty()) {
610 // ### Lars asks: is this correct for the A version????
611 QT_WA({
612 SendMessage(hwnd, BFFM_SETSELECTION, TRUE, Q_ULONG(initDir->ucs2()));
613 } , {
614 SendMessageA(hwnd, BFFM_SETSELECTION, TRUE, Q_ULONG(initDir->ucs2()));
615 });
616 }
617 } else if (uMsg == BFFM_SELCHANGED) {
618 QT_WA({
619 resolveLibs();
620 TCHAR path[MAX_PATH];
621 ptrSHGetPathFromIDList(LPITEMIDLIST(lParam), path);
622 QString tmpStr = QString::fromUcs2((ushort*)path);
623 if (!tmpStr.isEmpty())
624 SendMessage(hwnd, BFFM_ENABLEOK, 1, 1);
625 else
626 SendMessage(hwnd, BFFM_ENABLEOK, 0, 0);
627 SendMessage(hwnd, BFFM_SETSTATUSTEXT, 1, Q_ULONG(path));
628 } , {
629 char path[MAX_PATH];
630 SHGetPathFromIDListA(LPITEMIDLIST(lParam), path);
631 QString tmpStr = QString::fromLocal8Bit(path);
632 if (!tmpStr.isEmpty())
633 SendMessageA(hwnd, BFFM_ENABLEOK, 1, 1);
634 else
635 SendMessageA(hwnd, BFFM_ENABLEOK, 0, 0);
636 SendMessageA(hwnd, BFFM_SETSTATUSTEXT, 1, Q_ULONG(path));
637 });
638 }
639#endif
640 return 0;
641}
642
643#ifndef BIF_NEWDIALOGSTYLE
644#define BIF_NEWDIALOGSTYLE 0x0040 // Use the new dialog layout with the ability to resize
645#endif
646
647
648QString Q3FileDialog::winGetExistingDirectory(const QString& initialDirectory,
649 QWidget *parent,
650 const char* /*name*/,
651 const QString& caption)
652{
653#ifndef Q_OS_WINCE
654 QString currentDir = QDir::currentDirPath();
655 QString result;
656 if (parent)
657 parent = parent->window();
658 else
659 parent = qApp->activeWindow();
660 QString title = caption;
661 if (title.isNull())
662 title = tr("Select a Directory");
663
664 if (parent) {
665 QEvent e(QEvent::WindowBlocked);
666 QApplication::sendEvent(parent, &e);
667 QApplicationPrivate::enterModal(parent);
668 }
669 QT_WA({
670 resolveLibs();
671 QString initDir = QDir::toNativeSeparators(initialDirectory);
672 TCHAR path[MAX_PATH];
673 TCHAR initPath[MAX_PATH];
674 initPath[0] = 0;
675 path[0] = 0;
676 tTitle = title;
677 BROWSEINFO bi;
678 bi.hwndOwner = (parent ? parent->winId() : 0);
679 bi.pidlRoot = NULL;
680 bi.lpszTitle = (TCHAR*)tTitle.ucs2();
681 bi.pszDisplayName = initPath;
682 bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT | BIF_NEWDIALOGSTYLE;
683 bi.lpfn = winGetExistDirCallbackProc;
684 bi.lParam = Q_ULONG(&initDir);
685 LPITEMIDLIST pItemIDList = ptrSHBrowseForFolder(&bi);
686 if (pItemIDList) {
687 ptrSHGetPathFromIDList(pItemIDList, path);
688 IMalloc *pMalloc;
689 if (SHGetMalloc(&pMalloc) != NOERROR)
690 result.clear();
691 else {
692 pMalloc->Free(pItemIDList);
693 pMalloc->Release();
694 result = QString::fromUcs2((ushort*)path);
695 }
696 } else
697 result.clear();
698 tTitle.clear();
699 } , {
700 QString initDir = QDir::toNativeSeparators(initialDirectory);
701 char path[MAX_PATH];
702 char initPath[MAX_PATH];
703 QByteArray ctitle = title.toLocal8Bit();
704 initPath[0]=0;
705 path[0]=0;
706 BROWSEINFOA bi;
707 bi.hwndOwner = (parent ? parent->winId() : 0);
708 bi.pidlRoot = NULL;
709 bi.lpszTitle = ctitle;
710 bi.pszDisplayName = initPath;
711 bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT | BIF_NEWDIALOGSTYLE;
712 bi.lpfn = winGetExistDirCallbackProc;
713 bi.lParam = Q_ULONG(&initDir);
714 LPITEMIDLIST pItemIDList = SHBrowseForFolderA(&bi);
715 if (pItemIDList) {
716 SHGetPathFromIDListA(pItemIDList, path);
717 IMalloc *pMalloc;
718 if (SHGetMalloc(&pMalloc) != NOERROR)
719 result.clear();
720 else {
721 pMalloc->Free(pItemIDList);
722 pMalloc->Release();
723 result = QString::fromLocal8Bit(path);
724 }
725 } else
726 result.clear();
727 });
728 if (parent) {
729 QApplicationPrivate::leaveModal(parent);
730 QEvent e(QEvent::WindowUnblocked);
731 QApplication::sendEvent(parent, &e);
732 }
733
734 // Due to a bug on Windows Me, we need to reset the current
735 // directory
736 if ((qWinVersion() == Qt::WV_98 || qWinVersion() == Qt::WV_Me) && QDir::currentDirPath() != currentDir)
737 QDir::setCurrent(currentDir);
738
739 if (!result.isEmpty())
740 result.replace(QLatin1String("\\"), QLatin1String("/"));
741 return result;
742#else
743 return QString();
744#endif
745}
746
747QT_END_NAMESPACE
748
749#endif
Note: See TracBrowser for help on using the repository browser.