[PATCH] QFileDialog::getExistingDirectory()

Sami Kyostila skyostil at kempele.fi
Tue Feb 22 17:44:31 CET 2005


Hi,

Here's a patch that (mostly) fixes the defunct
QFileDialog::getExistingDirectory() function. Two issues are addressed:

1. The old code takes the selected path from the pszDisplayName member
of the LPITEMIDLIST structure. That member only contains the string shown
to the user in the dialog rather than the full path, making the result
useless.
  This patch extracts the resulting path from the value returned by
SHBrowseForFolder().

2. The old code initializes the pidlRoot member of the LPITEMIDLIST
structure to point to the initial directory given to the function. This is
incorrect because this actually restricts the file dialog namespace to
directories below the initial one. That is, if you start at c:\foo\bar,
you can't go up to c:\foo or even c:\.
  As far as I can see, there is no way to directly specify the initial
directory for SHBrowseForFolder(), so this patch just removes the
namespace root assignment.

Regards,
Sami Kyöstilä

----

Changelog:

2005-02-22  Sami Kyöstilä  <skyostil at kempele.fi>

* src/dialogs/qfiledialog_win.cpp: (QFileDialog::winGetExistingDirectory):
Read the resultant path properly from the return value of
SHBrowseForFolder(). Don't restrict the browsable namespace to the given
initial directory. Use a new-style resizable dialog.
-------------- next part --------------
Index: src/dialogs/qfiledialog_win.cpp
===================================================================
RCS file: /cvsroot/kde-cygwin/qt-3/src/dialogs/Attic/qfiledialog_win.cpp,v
retrieving revision 1.1.2.1.4.8
diff -u -p -r1.1.2.1.4.8 qfiledialog_win.cpp
--- src/dialogs/qfiledialog_win.cpp	27 Jan 2005 21:36:36 -0000	1.1.2.1.4.8
+++ src/dialogs/qfiledialog_win.cpp	22 Feb 2005 16:18:47 -0000
@@ -206,7 +206,7 @@ QStringList QFileDialog::winGetOpenFileN
             while ( ( file = QString ( ( opfa.lpstrFile ) + offset ) != "" ) )
                 ret.append( QFile::decodeName( file.data() ) );
             )
-        return ret;
+                return ret;
     }
     return QStringList();
 }
@@ -259,14 +259,14 @@ QString QFileDialog::winGetOpenFileName(
         opfw.lpstrFile = ( LPWSTR ) filename;
         opfw.nMaxFile = 1024;
         if ( GetOpenFileNameW( &opfw ) )
-            return qt_winQString ( opfw.lpstrFile );
+        return qt_winQString ( opfw.lpstrFile );
         ,
         opfa.lpstrFile = ( LPSTR ) filename;
         opfa.nMaxFile = 1024;
         if ( GetOpenFileNameA( &opfa ) )
             return QFile::decodeName( opfa.lpstrFile );
         )
-    return QString::null;
+            return QString::null;
 }
 
 QString QFileDialog::winGetSaveFileName( const QString & initialSelection,
@@ -317,14 +317,14 @@ QString QFileDialog::winGetSaveFileName(
         opfw.lpstrFile = ( LPWSTR ) filename;
         opfw.nMaxFile = 1024;
         if ( GetSaveFileNameW( &opfw ) )
-            return qt_winQString ( opfw.lpstrFile );
+        return qt_winQString ( opfw.lpstrFile );
         ,
         opfa.lpstrFile = ( LPSTR ) filename;
         opfa.nMaxFile = 1024;
         if ( GetSaveFileNameA( &opfa ) )
             return QFile::decodeName( opfa.lpstrFile );
         )
-    return QString::null;
+            return QString::null;
 }
 
 /* This function is from http://www.winterdom.com/dev/ui/ishfolder.html */
@@ -340,11 +340,11 @@ bool GetItemIdListFromPath ( QString lps
 
     // convert the path to an ITEMIDLIST
     hr = pShellFolder->ParseDisplayName (
-             NULL,                       // owner window
-             NULL,                       // reserved (must be NULL)
-             ( LPWSTR ) lpszPath.ucs2(), // folder name
-             &chUsed,                    // number of chars parsed
-             lpItemIdList,               // ITEMIDLIST
+             NULL,                        // owner window
+             NULL,                        // reserved (must be NULL)
+             ( LPWSTR ) lpszPath.ucs2(),  // folder name
+             &chUsed,                     // number of chars parsed
+             lpItemIdList,                // ITEMIDLIST
              NULL );                     // attributes (can be NULL)
 
     if ( FAILED( hr ) ) {
@@ -357,10 +357,20 @@ bool GetItemIdListFromPath ( QString lps
     return true;
 }
 
+QString GetPathFromItemIdList ( LPITEMIDLIST lpItemIdList )
+{
+    WCHAR path[ MAX_PATH ];
+
+    if ( SHGetPathFromIDList ( lpItemIdList, path ) ) {
+        return QT_WA_INLINE( QString::fromUcs2( ( const unsigned short * ) path ),
+                             QString::fromLatin1( ( const char* ) path ) ) ;
+    }
+    return "";
+}
+
 QString QFileDialog::winGetExistingDirectory( const QString & initialDirectory,
         QWidget * parent, const char* /* name */, const QString & caption )
 {
-    WCHAR path[ MAX_PATH ];
     QString qPath( "" );
     LPITEMIDLIST itemlist;
     BROWSEINFOW biw;
@@ -374,24 +384,21 @@ QString QFileDialog::winGetExistingDirec
     QT_WA(
         memset( &biw, 0, sizeof( BROWSEINFOW ) );
         biw.hwndOwner = parent ? parent->winId() : 0;
-        biw.pszDisplayName = ( LPWSTR ) path;
         biw.lpszTitle = ( LPCWSTR ) caption.ucs2();
-        biw.pidlRoot = pidl;
+        biw.ulFlags = BIF_EDITBOX | BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS | BIF_VALIDATE;
 
         pidl = SHBrowseForFolderW ( &biw );
         ,
         memset( &bia, 0, sizeof( BROWSEINFOA ) );
         bia.hwndOwner = parent ? parent->winId() : 0;
-        bia.pszDisplayName = ( LPSTR ) path;
         bia.lpszTitle = ( LPCSTR ) caption.latin1();
-        bia.pidlRoot = pidl;
+        biw.ulFlags = BIF_EDITBOX | BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS | BIF_VALIDATE;
 
         pidl = SHBrowseForFolderA ( &bia );
     )
 
     if ( pidl ) {
-        qPath = QT_WA_INLINE( QString::fromUcs2( ( const unsigned short * )path ),
-                              QString::fromLatin1( ( const char* ) path ) ) ;
+        qPath = GetPathFromItemIdList( pidl );
 
         // free memory used
         IMalloc * imalloc = 0;


More information about the kde-cygwin mailing list