Fix speed regression in wxFileHistory::AddFileToHistory().

Avoid full normalization including wxPATH_NORM_LONG when adding files to
wxFileHistory as this can take a very long time when using network paths under
Windows.

Closes #13915.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@70503 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2012-02-03 17:27:13 +00:00
parent 9d05b85deb
commit 406a0ab32c
2 changed files with 28 additions and 2 deletions

View File

@ -23,6 +23,7 @@
class WXDLLIMPEXP_FWD_CORE wxMenu;
class WXDLLIMPEXP_FWD_BASE wxConfigBase;
class WXDLLIMPEXP_FWD_BASE wxFileName;
// ----------------------------------------------------------------------------
// File history management
@ -79,6 +80,10 @@ private:
// The ID of the first history menu item (Doesn't have to be wxID_FILE1)
wxWindowID m_idBase;
// Normalize a file name to canonical form. We have a special function for
// this to ensure the same normalization is used everywhere.
static wxString NormalizeFileName(const wxFileName& filename);
wxDECLARE_NO_COPY_CLASS(wxFileHistoryBase);
};

View File

@ -68,15 +68,36 @@ wxFileHistoryBase::wxFileHistoryBase(size_t maxFiles, wxWindowID idBase)
m_idBase = idBase;
}
/* static */
wxString wxFileHistoryBase::NormalizeFileName(const wxFileName& fn)
{
// We specifically exclude wxPATH_NORM_LONG here as it can take a long time
// (several seconds) for network file paths under MSW, resulting in huge
// delays when opening a program using wxFileHistory. We also exclude
// wxPATH_NORM_ENV_VARS as the file names here are supposed to be "real"
// file names and not have any environment variables in them.
wxFileName fnNorm(fn);
fnNorm.Normalize(wxPATH_NORM_DOTS |
wxPATH_NORM_TILDE |
wxPATH_NORM_CASE |
wxPATH_NORM_ABSOLUTE);
return fnNorm.GetFullPath();
}
void wxFileHistoryBase::AddFileToHistory(const wxString& file)
{
// check if we don't already have this file
// Check if we don't already have this file. Notice that we avoid
// wxFileName::operator==(wxString) here as it converts the string to
// wxFileName and then normalizes it using all normalizations which is too
// slow (see the comment above), so we use our own quick normalization
// functions and a string comparison.
const wxFileName fnNew(file);
const wxString newFile = NormalizeFileName(fnNew);
size_t i,
numFiles = m_fileHistory.size();
for ( i = 0; i < numFiles; i++ )
{
if ( fnNew == m_fileHistory[i] )
if ( newFile == NormalizeFileName(m_fileHistory[i]) )
{
// we do have it, move it to the top of the history
RemoveFileFromHistory(i);