fixed huge memory leak in wxFileDialog (closes patch 544060)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@15214 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2002-04-20 11:10:19 +00:00
parent e94ff4cbf1
commit 7a82dabcc7
2 changed files with 48 additions and 41 deletions

View File

@ -201,8 +201,8 @@ wxGTK:
- support for more SGI hardware (12-bit mode among others)
- fixed wxDC::Blit() to honour source DC's logical coordinates
- implemented wxIdleEvent::RequestMore() for simple background tasks
(unlike thread work)
- implemented wxChoice::Delete()
- fixed bad memory leak in wxFileDialog (Chris Elliott)
wxHTML:

View File

@ -67,17 +67,16 @@
#include <direct.h>
#endif
# include <time.h>
#include <time.h>
#include <unistd.h>
//-----------------------------------------------------------------------------
// wxFileData
//-----------------------------------------------------------------------------
class wxFileData : public wxObject
class wxFileData
{
public:
wxFileData() { }
wxFileData( const wxString &name, const wxString &fname );
wxString GetName() const;
wxString GetFullName() const;
@ -103,8 +102,6 @@ private:
bool m_isDir;
bool m_isLink;
bool m_isExe;
DECLARE_DYNAMIC_CLASS(wxFileData);
};
//-----------------------------------------------------------------------------
@ -124,6 +121,8 @@ public:
long style = wxLC_LIST,
const wxValidator &validator = wxDefaultValidator,
const wxString &name = wxT("filelist") );
virtual ~wxFileCtrl();
void ChangeToListMode();
void ChangeToReportMode();
void ChangeToIconMode();
@ -138,9 +137,8 @@ public:
void SetWild( const wxString &wild );
void GetDir( wxString &dir );
void OnListDeleteItem( wxListEvent &event );
void OnListDeleteAllItems( wxListEvent &event );
void OnListEndLabelEdit( wxListEvent &event );
// Associate commonly used UI controls with wxFileCtrl so that they can be
// disabled when they cannot be used (e.g. can't go to parent directory
// if wxFileCtrl already is in the root dir):
@ -148,10 +146,13 @@ public:
void SetNewDirControl(wxWindow *ctrl) { m_newDirControl = ctrl; }
private:
void FreeItemData(const wxListItem& item);
void FreeAllItemsData();
wxString m_dirName;
bool m_showHidden;
wxString m_wild;
wxWindow *m_goToParentControl;
wxWindow *m_newDirControl;
@ -199,7 +200,7 @@ wxFileIconsTable::wxFileIconsTable() :
// FI_FOLDER:
m_ImageList.Add(wxArtProvider::GetBitmap(wxART_FOLDER, wxART_CMN_DIALOG));
// FI_UNKNOWN:
m_ImageList.Add(wxArtProvider::GetBitmap(wxART_NORMAL_FILE, wxART_CMN_DIALOG));
m_ImageList.Add(wxArtProvider::GetBitmap(wxART_NORMAL_FILE, wxART_CMN_DIALOG));
// FI_EXECUTABLE:
if (GetIconID(wxEmptyString, _T("application/x-executable")) == FI_UNKNOWN)
{
@ -391,13 +392,11 @@ extern bool wxIsDriveAvailable(const wxString& dirName);
// wxFileData
//-----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxFileData,wxObject);
wxFileData::wxFileData( const wxString &name, const wxString &fname )
{
m_name = name;
m_fileName = fname;
#if defined(__DOS__) || defined(__WINDOWS__)
// VS: In case the file is root directory of a volume (e.g. "C:"),
// we don't want it stat()ed, since the drive may not be in:
@ -584,7 +583,6 @@ IMPLEMENT_DYNAMIC_CLASS(wxFileCtrl,wxListCtrl);
BEGIN_EVENT_TABLE(wxFileCtrl,wxListCtrl)
EVT_LIST_DELETE_ITEM(-1, wxFileCtrl::OnListDeleteItem)
EVT_LIST_DELETE_ALL_ITEMS(-1, wxFileCtrl::OnListDeleteAllItems)
EVT_LIST_END_LABEL_EDIT(-1, wxFileCtrl::OnListEndLabelEdit)
END_EVENT_TABLE()
@ -602,11 +600,11 @@ wxFileCtrl::wxFileCtrl()
wxFileCtrl::wxFileCtrl(wxWindow *win, wxWindowID id,
const wxString &dirName, const wxString &wild,
const wxPoint &pos, const wxSize &size,
long style, const wxValidator &validator,
long style, const wxValidator &validator,
const wxString &name)
: wxListCtrl(win, id, pos, size, style, validator, name)
{
if (! g_IconsTable)
if (! g_IconsTable)
g_IconsTable = new wxFileIconsTable;
wxImageList *imageList = g_IconsTable->GetImageList();
@ -658,7 +656,7 @@ long wxFileCtrl::Add( wxFileData *fd, wxListItem &item )
const int noEntries = 4;
#endif
ret = InsertItem( item );
for (int i = 1; i < noEntries; i++)
for (int i = 1; i < noEntries; i++)
SetItem( item.m_itemId, i, fd->GetEntry( i) );
}
else if (my_style & wxLC_LIST)
@ -671,7 +669,7 @@ long wxFileCtrl::Add( wxFileData *fd, wxListItem &item )
void wxFileCtrl::UpdateFiles()
{
wxBusyCursor bcur; // this may take a while...
long my_style = GetWindowStyleFlag();
int name_col_width = 0;
if (my_style & wxLC_REPORT)
@ -680,7 +678,9 @@ void wxFileCtrl::UpdateFiles()
name_col_width = GetColumnWidth( 0 );
}
FreeAllItemsData();
ClearAll();
if (my_style & wxLC_REPORT)
{
if (name_col_width < 140) name_col_width = 140;
@ -699,7 +699,7 @@ void wxFileCtrl::UpdateFiles()
#if defined(__DOS__) || defined(__WINDOWS__)
if ( IsTopMostDir(m_dirName) )
{
{
// Pseudo-directory with all available drives listed...
for (int drive = 1; drive <= 26; drive++)
{
@ -740,7 +740,7 @@ void wxFileCtrl::UpdateFiles()
{
wxString dirPrefix(dirname + wxFILE_SEP_PATH);
int hiddenFlag = m_showHidden ? wxDIR_HIDDEN : 0;
bool cont;
wxString f;
@ -754,12 +754,12 @@ void wxFileCtrl::UpdateFiles()
cont = dir.GetNext(&f);
}
// Tokenize the wildcard string, so we can handle more than 1
// Tokenize the wildcard string, so we can handle more than 1
// search pattern in a wildcard.
wxStringTokenizer tokenWild(m_wild, wxT(";"));
while ( tokenWild.HasMoreTokens() )
{
cont = dir.GetFirst(&f, tokenWild.GetNextToken(),
cont = dir.GetFirst(&f, tokenWild.GetNextToken(),
wxDIR_FILES | hiddenFlag);
while (cont)
{
@ -780,7 +780,7 @@ void wxFileCtrl::UpdateFiles()
SetColumnWidth(2, wxLIST_AUTOSIZE);
SetColumnWidth(3, wxLIST_AUTOSIZE);
}
// Finally, enable/disable context-dependent controls:
if ( m_goToParentControl )
m_goToParentControl->Enable(!IsTopMostDir(m_dirName));
@ -852,7 +852,7 @@ void wxFileCtrl::GoToParentDir()
wxString fname( wxFileNameFromPath(m_dirName) );
m_dirName = wxPathOnly( m_dirName );
#ifdef __UNIX__
if (m_dirName.IsEmpty())
if (m_dirName.IsEmpty())
m_dirName = wxT("/");
#endif
UpdateFiles();
@ -884,13 +884,18 @@ void wxFileCtrl::GetDir( wxString &dir )
dir = m_dirName;
}
void wxFileCtrl::OnListDeleteItem( wxListEvent &event )
void wxFileCtrl::FreeItemData(const wxListItem& item)
{
wxFileData *fd = (wxFileData*)event.m_item.m_data;
wxFileData *fd = (wxFileData*)item.m_data;
delete fd;
}
void wxFileCtrl::OnListDeleteAllItems( wxListEvent &WXUNUSED(event) )
void wxFileCtrl::OnListDeleteItem( wxListEvent &event )
{
FreeItemData(event.m_item);
}
void wxFileCtrl::FreeAllItemsData()
{
wxListItem item;
item.m_mask = wxLIST_MASK_DATA;
@ -899,10 +904,7 @@ void wxFileCtrl::OnListDeleteAllItems( wxListEvent &WXUNUSED(event) )
while ( item.m_itemId != -1 )
{
GetItem( item );
wxFileData *fd = (wxFileData*)item.m_data;
delete fd;
item.m_data = 0;
SetItem( item );
FreeItemData(item);
item.m_itemId = GetNextItem( item.m_itemId, wxLIST_NEXT_ALL );
}
}
@ -950,6 +952,11 @@ void wxFileCtrl::OnListEndLabelEdit( wxListEvent &event )
}
}
wxFileCtrl::~wxFileCtrl()
{
FreeAllItemsData();
}
//-----------------------------------------------------------------------------
// wxFileDialog
//-----------------------------------------------------------------------------
@ -997,9 +1004,9 @@ wxFileDialog::wxFileDialog(wxWindow *parent,
if (wxConfig::Get(FALSE))
{
wxConfig::Get()->Read(wxT("/wxWindows/wxFileDialog/ViewStyle"),
wxConfig::Get()->Read(wxT("/wxWindows/wxFileDialog/ViewStyle"),
&s_lastViewStyle);
wxConfig::Get()->Read(wxT("/wxWindows/wxFileDialog/ShowHidden"),
wxConfig::Get()->Read(wxT("/wxWindows/wxFileDialog/ShowHidden"),
&s_lastShowHidden);
}
@ -1015,7 +1022,7 @@ wxFileDialog::wxFileDialog(wxWindow *parent,
{
m_dir = wxGetCwd();
}
size_t len = m_dir.Len();
if ((len > 1) && (m_dir[len-1] == wxFILE_SEP_PATH))
m_dir.Remove( len-1, 1 );
@ -1059,7 +1066,7 @@ wxFileDialog::wxFileDialog(wxWindow *parent,
wxBitmapButton *but;
but = new wxBitmapButton(this, ID_LIST_MODE,
but = new wxBitmapButton(this, ID_LIST_MODE,
wxArtProvider::GetBitmap(wxART_LIST_VIEW, wxART_CMN_DIALOG));
#if wxUSE_TOOLTIPS
but->SetToolTip( _("View files as a list view") );
@ -1075,7 +1082,7 @@ wxFileDialog::wxFileDialog(wxWindow *parent,
buttonsizer->Add( 30, 5, 1 );
wxWindow *butDirUp =
wxWindow *butDirUp =
new wxBitmapButton(this, ID_UP_DIR,
wxArtProvider::GetBitmap(wxART_GO_DIR_UP, wxART_CMN_DIALOG));
#if wxUSE_TOOLTIPS
@ -1094,7 +1101,7 @@ wxFileDialog::wxFileDialog(wxWindow *parent,
buttonsizer->Add( 20, 20 );
#endif //!__DOS__
wxWindow *butNewDir =
wxWindow *butNewDir =
new wxBitmapButton(this, ID_NEW_DIR,
wxArtProvider::GetBitmap(wxART_NEW_DIR, wxART_CMN_DIALOG));
#if wxUSE_TOOLTIPS
@ -1134,7 +1141,7 @@ wxFileDialog::wxFileDialog(wxWindow *parent,
m_choice = new wxChoice( this, ID_CHOICE );
choicesizer->Add( m_choice, 1, wxCENTER|wxALL, 5 );
mainsizer->Add( choicesizer, 0, wxEXPAND );
wxBoxSizer *textsizer = new wxBoxSizer( wxHORIZONTAL );
m_text = new wxTextCtrl( this, ID_TEXT, m_fileName, wxDefaultPosition, wxDefaultSize, wxPROCESS_ENTER );
textsizer->Add( m_text, 1, wxCENTER | wxALL, 5 );
@ -1143,7 +1150,7 @@ wxFileDialog::wxFileDialog(wxWindow *parent,
m_check = new wxCheckBox( this, ID_CHECK, _("Show hidden files") );
m_check->SetValue( s_lastShowHidden );
textsizer->Add( m_check, 0, wxCENTER|wxALL, 5 );
buttonsizer = new wxBoxSizer( wxHORIZONTAL );
buttonsizer->Add( new wxButton( this, wxID_OK, _("OK") ), 0, wxCENTER | wxALL, 5 );
buttonsizer->Add( new wxButton( this, wxID_CANCEL, _("Cancel") ), 0, wxCENTER | wxALL, 5 );
@ -1403,7 +1410,7 @@ void wxFileDialog::OnHome( wxCommandEvent &WXUNUSED(event) )
wxString dir;
m_list->GetDir( dir );
m_static->SetLabel( dir );
m_text->SetFocus();
}
@ -1442,7 +1449,7 @@ void wxFileDialog::GetPaths( wxArrayString& paths ) const
wxString dir;
m_list->GetDir( dir );
#ifdef __UNIX__
if (dir != wxT("/"))
if (dir != wxT("/"))
#endif
dir += wxFILE_SEP_PATH;