Check that files returned from wxDir::FindXXX() match the filter.
Native Windows functions used by wxDir check the filter against both the short and the long name resulting in unexpected results, e.g. searching for "foo.baz" would find "foo.bazaar". Fix this by explicitly rechecking that we have a valid match ourselves. Closes #3432. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@73790 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
6f58f3d7e0
commit
4daceaacbd
@ -658,6 +658,7 @@ wxMSW:
|
||||
- Improve wxCURSOR_RIGHT_ARROW appearance (DoltAlya).
|
||||
- Generate menu highlight events for popup menus in wxDialog (Sam Partington).
|
||||
- Return more native shell icons from wxArtProvider (Markus Juergens).
|
||||
- Fix filter checks in wxDir::FindFirst/Next() (Catalin Raceanu).
|
||||
|
||||
wxOSX/Cocoa:
|
||||
|
||||
|
@ -64,22 +64,62 @@ inline void FreeFindData(FIND_DATA fd)
|
||||
}
|
||||
}
|
||||
|
||||
inline FIND_DATA FindFirst(const wxString& spec,
|
||||
FIND_STRUCT *finddata)
|
||||
{
|
||||
return ::FindFirstFile(spec.t_str(), finddata);
|
||||
}
|
||||
|
||||
inline bool FindNext(FIND_DATA fd, FIND_STRUCT *finddata)
|
||||
{
|
||||
return ::FindNextFile(fd, finddata) != 0;
|
||||
}
|
||||
|
||||
const wxChar *GetNameFromFindData(FIND_STRUCT *finddata)
|
||||
const wxChar *GetNameFromFindData(const FIND_STRUCT *finddata)
|
||||
{
|
||||
return finddata->cFileName;
|
||||
}
|
||||
|
||||
// Helper function checking that the contents of the given FIND_STRUCT really
|
||||
// match our filter. We need to do it ourselves as native Windows functions
|
||||
// apply the filter to both the long and the short names of the file, so
|
||||
// something like "*.bar" matches "foo.bar.baz" too and not only "foo.bar", so
|
||||
// we have to double check that we have a real match.
|
||||
inline bool
|
||||
CheckFoundMatch(const FIND_STRUCT* finddata, const wxString& filter)
|
||||
{
|
||||
return filter.empty() ||
|
||||
wxString(GetNameFromFindData(finddata)).Matches(filter);
|
||||
}
|
||||
|
||||
inline bool
|
||||
FindNext(FIND_DATA fd, const wxString& filter, FIND_STRUCT *finddata)
|
||||
{
|
||||
for ( ;; )
|
||||
{
|
||||
if ( !::FindNextFile(fd, finddata) )
|
||||
return false;
|
||||
|
||||
// If we did find something, check that it really matches.
|
||||
if ( CheckFoundMatch(finddata, filter) )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
inline FIND_DATA
|
||||
FindFirst(const wxString& spec,
|
||||
const wxString& filter,
|
||||
FIND_STRUCT *finddata)
|
||||
{
|
||||
FIND_DATA fd = ::FindFirstFile(spec.t_str(), finddata);
|
||||
|
||||
// As in FindNext() above, we need to check that the file name we found
|
||||
// really matches our filter and look for the next match if it doesn't.
|
||||
if ( IsFindDataOk(fd) && !CheckFoundMatch(finddata, filter) )
|
||||
{
|
||||
if ( !FindNext(fd, filter, finddata) )
|
||||
{
|
||||
// As we return the invalid handle from here to indicate that we
|
||||
// didn't find anything, close the one we initially received
|
||||
// ourselves.
|
||||
FreeFindData(fd);
|
||||
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
inline FIND_ATTR GetAttrFromFindData(FIND_STRUCT *finddata)
|
||||
{
|
||||
return finddata->dwFileAttributes;
|
||||
@ -196,7 +236,7 @@ bool wxDirData::Read(wxString *filename)
|
||||
else
|
||||
filespec += m_filespec;
|
||||
|
||||
m_finddata = FindFirst(filespec, PTR_TO_FINDDATA);
|
||||
m_finddata = FindFirst(filespec, m_filespec, PTR_TO_FINDDATA);
|
||||
|
||||
first = true;
|
||||
}
|
||||
@ -228,7 +268,7 @@ bool wxDirData::Read(wxString *filename)
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !FindNext(m_finddata, PTR_TO_FINDDATA) )
|
||||
if ( !FindNext(m_finddata, m_filespec, PTR_TO_FINDDATA) )
|
||||
{
|
||||
#ifdef __WIN32__
|
||||
DWORD err = ::GetLastError();
|
||||
@ -400,7 +440,7 @@ wxGetDirectoryTimes(const wxString& dirname,
|
||||
#endif
|
||||
|
||||
FIND_STRUCT fs;
|
||||
FIND_DATA fd = FindFirst(dirname, &fs);
|
||||
FIND_DATA fd = FindFirst(dirname, wxEmptyString, &fs);
|
||||
if ( !IsFindDataOk(fd) )
|
||||
{
|
||||
return false;
|
||||
|
Loading…
Reference in New Issue
Block a user