X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/70a7eb078d6f9d5288527be43608e22ba65a26a4..4e916e61ea24c165fb55e78172f1093bf7481b48:/src/generic/filedlgg.cpp diff --git a/src/generic/filedlgg.cpp b/src/generic/filedlgg.cpp index 3b50efa3ea..dc2719db4b 100644 --- a/src/generic/filedlgg.cpp +++ b/src/generic/filedlgg.cpp @@ -1,5 +1,5 @@ ////////////////////////////////////////////////////////////////////////////// -// Name: filedlgg.cpp +// Name: src/generic/filedlgg.cpp // Purpose: wxGenericFileDialog // Author: Robert Roebling // Modified by: @@ -9,52 +9,59 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) -#pragma implementation "filedlgg.h" -#endif - // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" #ifdef __BORLANDC__ -#pragma hdrstop + #pragma hdrstop #endif #if wxUSE_FILEDLG // NOTE : it probably also supports MAC, untested -#if !defined(__UNIX__) && !defined(__DOS__) && !defined(__WIN32__) && !defined(__OS2__) +#if !defined(__UNIX__) && !defined(__DOS__) && !defined(__WIN32__) && !defined(__OS2__) && !defined(__PALMOS__) #error wxGenericFileDialog currently only supports Unix, win32 and DOS #endif -#include "wx/checkbox.h" -#include "wx/textctrl.h" -#include "wx/choice.h" -#include "wx/checkbox.h" -#include "wx/stattext.h" -#include "wx/debug.h" -#include "wx/log.h" -#include "wx/intl.h" -#include "wx/msgdlg.h" -#include "wx/sizer.h" -#include "wx/bmpbuttn.h" -#include "wx/tokenzr.h" +#ifndef WX_PRECOMP + #ifdef __WXMSW__ + #include "wx/msw/wrapwin.h" + #endif + #include "wx/hash.h" + #include "wx/intl.h" + #include "wx/settings.h" + #include "wx/log.h" + #include "wx/msgdlg.h" + #include "wx/bmpbuttn.h" + #include "wx/checkbox.h" + #include "wx/choice.h" + #include "wx/stattext.h" + #include "wx/textctrl.h" + #include "wx/sizer.h" + #include "wx/filedlg.h" // wxFD_OPEN, wxFD_SAVE... +#endif + +#include "wx/longlong.h" #include "wx/config.h" #include "wx/imaglist.h" -#include "wx/dir.h" #include "wx/artprov.h" -#include "wx/settings.h" -#include "wx/file.h" // for wxS_IXXX constants only -#include "wx/filedlg.h" // wxOPEN, wxSAVE... +#include "wx/filefn.h" +#include "wx/filectrl.h" #include "wx/generic/filedlgg.h" -#include "wx/generic/dirctrlg.h" // for wxFileIconsTable +#include "wx/debug.h" #if wxUSE_TOOLTIPS #include "wx/tooltip.h" #endif +#if wxUSE_CONFIG + #include "wx/config.h" +#endif -#include -#include +#ifndef __WXPALMOS5__ +#ifndef __WXWINCE__ + #include + #include +#endif #ifdef __UNIX__ #include @@ -65,7 +72,6 @@ #endif #ifdef __WINDOWS__ - #include "wx/msw/wrapwin.h" #include "wx/msw/mslu.h" #endif @@ -73,798 +79,49 @@ #include #endif +#ifndef __WXWINCE__ #include +#endif + #if defined(__UNIX__) || defined(__DOS__) #include #endif +#endif // ! __WXPALMOS5__ -// ---------------------------------------------------------------------------- -// private functions -// ---------------------------------------------------------------------------- - -static -int wxCALLBACK wxFileDataNameCompare( long data1, long data2, long data) -{ - wxFileData *fd1 = (wxFileData*)data1; - wxFileData *fd2 = (wxFileData*)data2; - if (fd1->GetFileName() == wxT("..")) return -data; - if (fd2->GetFileName() == wxT("..")) return data; - if (fd1->IsDir() && !fd2->IsDir()) return -data; - if (fd2->IsDir() && !fd1->IsDir()) return data; - return data*wxStrcmp( fd1->GetFileName(), fd2->GetFileName() ); -} - -static -int wxCALLBACK wxFileDataSizeCompare( long data1, long data2, long data) -{ - wxFileData *fd1 = (wxFileData*)data1; - wxFileData *fd2 = (wxFileData*)data2; - if (fd1->GetFileName() == wxT("..")) return -data; - if (fd2->GetFileName() == wxT("..")) return data; - if (fd1->IsDir() && !fd2->IsDir()) return -data; - if (fd2->IsDir() && !fd1->IsDir()) return data; - if (fd1->IsLink() && !fd2->IsLink()) return -data; - if (fd2->IsLink() && !fd1->IsLink()) return data; - return data*(fd1->GetSize() - fd2->GetSize()); -} - -static -int wxCALLBACK wxFileDataTypeCompare( long data1, long data2, long data) -{ - wxFileData *fd1 = (wxFileData*)data1; - wxFileData *fd2 = (wxFileData*)data2; - if (fd1->GetFileName() == wxT("..")) return -data; - if (fd2->GetFileName() == wxT("..")) return data; - if (fd1->IsDir() && !fd2->IsDir()) return -data; - if (fd2->IsDir() && !fd1->IsDir()) return data; - if (fd1->IsLink() && !fd2->IsLink()) return -data; - if (fd2->IsLink() && !fd1->IsLink()) return data; - return data*wxStrcmp( fd1->GetFileType(), fd2->GetFileType() ); -} - -static -int wxCALLBACK wxFileDataTimeCompare( long data1, long data2, long data) -{ - wxFileData *fd1 = (wxFileData*)data1; - wxFileData *fd2 = (wxFileData*)data2; - if (fd1->GetFileName() == wxT("..")) return -data; - if (fd2->GetFileName() == wxT("..")) return data; - if (fd1->IsDir() && !fd2->IsDir()) return -data; - if (fd2->IsDir() && !fd1->IsDir()) return data; - - return fd1->GetDateTime().IsLaterThan(fd2->GetDateTime()) ? int(data) : -int(data); -} - -#if defined(__DOS__) || defined(__WINDOWS__) || defined (__OS2__) +#if defined(__WXWINCE__) +#define IsTopMostDir(dir) (dir == wxT("\\") || dir == wxT("/")) +#elif (defined(__DOS__) || defined(__WINDOWS__) || defined (__OS2__)) #define IsTopMostDir(dir) (dir.empty()) #else #define IsTopMostDir(dir) (dir == wxT("/")) #endif -// defined in src/generic/dirctrlg.cpp -extern size_t wxGetAvailableDrives(wxArrayString &paths, wxArrayString &names, wxArrayInt &icon_ids); - -//----------------------------------------------------------------------------- -// wxFileData -//----------------------------------------------------------------------------- - -wxFileData::wxFileData( const wxString &filePath, const wxString &fileName, fileType type, int image_id ) -{ - Init(); - m_fileName = fileName; - m_filePath = filePath; - m_type = type; - m_image = image_id; - - ReadData(); -} - -void wxFileData::Init() -{ - m_size = 0; - m_type = wxFileData::is_file; - m_image = wxFileIconsTable::file; -} - -void wxFileData::Copy( const wxFileData& fileData ) -{ - m_fileName = fileData.GetFileName(); - m_filePath = fileData.GetFilePath(); - m_size = fileData.GetSize(); - m_dateTime = fileData.GetDateTime(); - m_permissions = fileData.GetPermissions(); - m_type = fileData.GetType(); - m_image = fileData.GetImageId(); -} - -void wxFileData::ReadData() -{ - if (IsDrive()) - { - m_size = 0; - return; - } - -#if defined(__DOS__) || defined(__WINDOWS__) || defined(__OS2__) - // c:\.. is a drive don't stat it - if ((m_fileName == wxT("..")) && (m_filePath.length() <= 5)) - { - m_type = is_drive; - m_size = 0; - return; - } -#endif // __DOS__ || __WINDOWS__ - - wxStructStat buff; - -#if defined(__UNIX__) && (!defined( __OS2__ ) && !defined(__VMS)) - lstat( m_filePath.fn_str(), &buff ); - m_type |= S_ISLNK( buff.st_mode ) != 0 ? is_link : 0; -#else // no lstat() - // only translate to file charset if we don't go by our - // wxStat implementation -#ifndef wxNEED_WX_UNISTD_H - wxStat( m_filePath.fn_str() , &buff ); -#else - wxStat( m_filePath, &buff ); -#endif -#endif - - m_type |= (buff.st_mode & S_IFDIR) != 0 ? is_dir : 0; - m_type |= (buff.st_mode & wxS_IXUSR) != 0 ? is_exe : 0; - - // try to get a better icon - if (m_image == wxFileIconsTable::file) - { - if (m_fileName.Find(wxT('.'), true) != wxNOT_FOUND) - { - m_image = wxTheFileIconsTable->GetIconID( m_fileName.AfterLast(wxT('.'))); - } else if (IsExe()) - { - m_image = wxFileIconsTable::executable; - } - } - - m_size = (long)buff.st_size; - - m_dateTime = buff.st_mtime; - -#if defined(__UNIX__) - m_permissions.Printf(_T("%c%c%c%c%c%c%c%c%c"), - buff.st_mode & wxS_IRUSR ? _T('r') : _T('-'), - buff.st_mode & wxS_IWUSR ? _T('w') : _T('-'), - buff.st_mode & wxS_IXUSR ? _T('x') : _T('-'), - buff.st_mode & wxS_IRGRP ? _T('r') : _T('-'), - buff.st_mode & wxS_IWGRP ? _T('w') : _T('-'), - buff.st_mode & wxS_IXGRP ? _T('x') : _T('-'), - buff.st_mode & wxS_IROTH ? _T('r') : _T('-'), - buff.st_mode & wxS_IWOTH ? _T('w') : _T('-'), - buff.st_mode & wxS_IXOTH ? _T('x') : _T('-')); -#elif defined(__WIN32__) - DWORD attribs = GetFileAttributes(m_filePath); - if (attribs != (DWORD)-1) - { - m_permissions.Printf(_T("%c%c%c%c"), - attribs & FILE_ATTRIBUTE_ARCHIVE ? _T('A') : _T(' '), - attribs & FILE_ATTRIBUTE_READONLY ? _T('R') : _T(' '), - attribs & FILE_ATTRIBUTE_HIDDEN ? _T('H') : _T(' '), - attribs & FILE_ATTRIBUTE_SYSTEM ? _T('S') : _T(' ')); - } -#endif -} - -wxString wxFileData::GetFileType() const -{ - if (IsDir()) - return _(""); - else if (IsLink()) - return _(""); - else if (IsDrive()) - return _(""); - else if (m_fileName.Find(wxT('.'), true) != wxNOT_FOUND) - return m_fileName.AfterLast(wxT('.')); - - return wxEmptyString; -} - -wxString wxFileData::GetModificationTime() const -{ - // want time as 01:02 so they line up nicely, no %r in WIN32 - return m_dateTime.FormatDate() + wxT(" ") + m_dateTime.Format(wxT("%I:%M:%S %p")); -} - -wxString wxFileData::GetHint() const -{ - wxString s = m_filePath; - s += wxT(" "); - - if (IsDir()) - s += _(""); - else if (IsLink()) - s += _(""); - else if (IsDrive()) - s += _(""); - else // plain file - s += wxString::Format( _("%ld bytes"), m_size ); - - s += wxT(' '); - - if ( !IsDrive() ) - { - s << GetModificationTime() - << wxT(" ") - << m_permissions; - } - - return s; -}; - -wxString wxFileData::GetEntry( fileListFieldType num ) const -{ - wxString s; - switch ( num ) - { - case FileList_Name: - s = m_fileName; - break; - - case FileList_Size: - if (!IsDir() && !IsLink() && !IsDrive()) - s.Printf(_T("%ld"), m_size); - break; - - case FileList_Type: - s = GetFileType(); - break; - - case FileList_Time: - if (!IsDrive()) - s = GetModificationTime(); - break; - -#if defined(__UNIX__) || defined(__WIN32__) - case FileList_Perm: - s = m_permissions; - break; -#endif // defined(__UNIX__) || defined(__WIN32__) - - default: - wxFAIL_MSG( _T("unexpected field in wxFileData::GetEntry()") ); - } - - return s; -} - -void wxFileData::SetNewName( const wxString &filePath, const wxString &fileName ) -{ - m_fileName = fileName; - m_filePath = filePath; -} - -void wxFileData::MakeItem( wxListItem &item ) -{ - item.m_text = m_fileName; - item.ClearAttributes(); - if (IsExe()) - item.SetTextColour(*wxRED); - if (IsDir()) - item.SetTextColour(*wxBLUE); - - item.m_image = m_image; - - if (IsLink()) - { - wxColour dg = wxTheColourDatabase->Find( _T("MEDIUM GREY") ); - if ( dg.Ok() ) - item.SetTextColour(dg); - } - item.m_data = (long)this; -} - -//----------------------------------------------------------------------------- -// wxFileCtrl -//----------------------------------------------------------------------------- - -IMPLEMENT_DYNAMIC_CLASS(wxFileCtrl,wxListCtrl) - -BEGIN_EVENT_TABLE(wxFileCtrl,wxListCtrl) - EVT_LIST_DELETE_ITEM(wxID_ANY, wxFileCtrl::OnListDeleteItem) - EVT_LIST_DELETE_ALL_ITEMS(wxID_ANY, wxFileCtrl::OnListDeleteAllItems) - EVT_LIST_END_LABEL_EDIT(wxID_ANY, wxFileCtrl::OnListEndLabelEdit) - EVT_LIST_COL_CLICK(wxID_ANY, wxFileCtrl::OnListColClick) -END_EVENT_TABLE() - - -wxFileCtrl::wxFileCtrl() -{ - m_showHidden = false; - m_sort_foward = 1; - m_sort_field = wxFileData::FileList_Name; -} - -wxFileCtrl::wxFileCtrl(wxWindow *win, - wxWindowID id, - const wxString& wild, - bool showHidden, - const wxPoint& pos, - const wxSize& size, - long style, - const wxValidator &validator, - const wxString &name) - : wxListCtrl(win, id, pos, size, style, validator, name), - m_wild(wild) -{ - wxImageList *imageList = wxTheFileIconsTable->GetSmallImageList(); - - SetImageList( imageList, wxIMAGE_LIST_SMALL ); - - m_showHidden = showHidden; - - m_sort_foward = 1; - m_sort_field = wxFileData::FileList_Name; - - m_dirName = wxT("*"); - - if (style & wxLC_REPORT) - ChangeToReportMode(); -} - -void wxFileCtrl::ChangeToListMode() -{ - ClearAll(); - SetSingleStyle( wxLC_LIST ); - UpdateFiles(); -} - -void wxFileCtrl::ChangeToReportMode() -{ - ClearAll(); - SetSingleStyle( wxLC_REPORT ); - - // do this since WIN32 does mm/dd/yy UNIX does mm/dd/yyyy - // don't hardcode since mm/dd is dd/mm elsewhere - int w, h; - wxDateTime dt(22, wxDateTime::Dec, 2002, 22, 22, 22); - wxString txt = dt.FormatDate() + wxT("22") + dt.Format(wxT("%I:%M:%S %p")); - GetTextExtent(txt, &w, &h); - - InsertColumn( 0, _("Name"), wxLIST_FORMAT_LEFT, w ); - InsertColumn( 1, _("Size"), wxLIST_FORMAT_LEFT, w/2 ); - InsertColumn( 2, _("Type"), wxLIST_FORMAT_LEFT, w/2 ); - InsertColumn( 3, _("Modified"), wxLIST_FORMAT_LEFT, w ); -#if defined(__UNIX__) - GetTextExtent(wxT("Permissions 2"), &w, &h); - InsertColumn( 4, _("Permissions"), wxLIST_FORMAT_LEFT, w ); -#elif defined(__WIN32__) - GetTextExtent(wxT("Attributes 2"), &w, &h); - InsertColumn( 4, _("Attributes"), wxLIST_FORMAT_LEFT, w ); -#endif - - UpdateFiles(); -} - -void wxFileCtrl::ChangeToSmallIconMode() -{ - ClearAll(); - SetSingleStyle( wxLC_SMALL_ICON ); - UpdateFiles(); -} - -void wxFileCtrl::ShowHidden( bool show ) -{ - m_showHidden = show; - UpdateFiles(); -} - -long wxFileCtrl::Add( wxFileData *fd, wxListItem &item ) -{ - long ret = -1; - item.m_mask = wxLIST_MASK_TEXT + wxLIST_MASK_DATA + wxLIST_MASK_IMAGE; - fd->MakeItem( item ); - long my_style = GetWindowStyleFlag(); - if (my_style & wxLC_REPORT) - { - ret = InsertItem( item ); - for (int i = 1; i < wxFileData::FileList_Max; i++) - SetItem( item.m_itemId, i, fd->GetEntry((wxFileData::fileListFieldType)i) ); - } - else if ((my_style & wxLC_LIST) || (my_style & wxLC_SMALL_ICON)) - { - ret = InsertItem( item ); - } - return ret; -} - -void wxFileCtrl::UpdateItem(const wxListItem &item) -{ - wxFileData *fd = (wxFileData*)GetItemData(item); - wxCHECK_RET(fd, wxT("invalid filedata")); - - fd->ReadData(); - - SetItemText(item, fd->GetFileName()); - SetItemImage(item, fd->GetImageId()); - - if (GetWindowStyleFlag() & wxLC_REPORT) - { - for (int i = 1; i < wxFileData::FileList_Max; i++) - SetItem( item.m_itemId, i, fd->GetEntry((wxFileData::fileListFieldType)i) ); - } -} - -void wxFileCtrl::UpdateFiles() -{ - // don't do anything before ShowModal() call which sets m_dirName - if ( m_dirName == wxT("*") ) - return; - - wxBusyCursor bcur; // this may take a while... - - DeleteAllItems(); - - wxListItem item; - item.m_itemId = 0; - item.m_col = 0; - -#if defined(__WINDOWS__) || defined(__DOS__) || defined(__WXMAC__) || defined(__OS2__) - if ( IsTopMostDir(m_dirName) ) - { - wxArrayString names, paths; - wxArrayInt icons; - size_t n, count = wxGetAvailableDrives(paths, names, icons); - - for (n=0; nGetFilePath() ) ); - new_name += wxFILE_SEP_PATH; - new_name += event.GetLabel(); - - wxLogNull log; - - if (wxFileExists(new_name)) - { - wxMessageDialog dialog(this, _("File name exists already."), _("Error"), wxOK | wxICON_ERROR ); - dialog.ShowModal(); - event.Veto(); - } - - if (wxRenameFile(fd->GetFilePath(),new_name)) - { - fd->SetNewName( new_name, event.GetLabel() ); - SetItemState( event.GetItem(), wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED ); - UpdateItem( event.GetItem() ); - EnsureVisible( event.GetItem() ); - } - else - { - wxMessageDialog dialog(this, _("Operation not permitted."), _("Error"), wxOK | wxICON_ERROR ); - dialog.ShowModal(); - event.Veto(); - } -} - -void wxFileCtrl::OnListColClick( wxListEvent &event ) -{ - int col = event.GetColumn(); - - switch (col) - { - case wxFileData::FileList_Name : - case wxFileData::FileList_Size : - case wxFileData::FileList_Type : - case wxFileData::FileList_Time : break; - default : return; - } - - if ((wxFileData::fileListFieldType)col == m_sort_field) - m_sort_foward = !m_sort_foward; - else - m_sort_field = (wxFileData::fileListFieldType)col; - - SortItems(m_sort_field, m_sort_foward); -} - -void wxFileCtrl::SortItems(wxFileData::fileListFieldType field, bool foward) -{ - m_sort_field = field; - m_sort_foward = foward; - long sort_dir = foward ? 1 : -1; - - switch (m_sort_field) - { - case wxFileData::FileList_Name : - { - wxListCtrl::SortItems((wxListCtrlCompare)wxFileDataNameCompare, sort_dir); - break; - } - case wxFileData::FileList_Size : - { - wxListCtrl::SortItems((wxListCtrlCompare)wxFileDataSizeCompare, sort_dir); - break; - } - case wxFileData::FileList_Type : - { - wxListCtrl::SortItems((wxListCtrlCompare)wxFileDataTypeCompare, sort_dir); - break; - } - case wxFileData::FileList_Time : - { - wxListCtrl::SortItems((wxListCtrlCompare)wxFileDataTimeCompare, sort_dir); - break; - } - default : break; - } -} - -wxFileCtrl::~wxFileCtrl() -{ - // Normally the data are freed via an EVT_LIST_DELETE_ALL_ITEMS event and - // wxFileCtrl::OnListDeleteAllItems. But if the event is generated after - // the destruction of the wxFileCtrl we need to free any data here: - FreeAllItemsData(); -} - //----------------------------------------------------------------------------- // wxGenericFileDialog //----------------------------------------------------------------------------- #define ID_LIST_MODE (wxID_FILEDLGG ) #define ID_REPORT_MODE (wxID_FILEDLGG + 1) -#define ID_UP_DIR (wxID_FILEDLGG + 5) -#define ID_PARENT_DIR (wxID_FILEDLGG + 6) -#define ID_NEW_DIR (wxID_FILEDLGG + 7) -#define ID_CHOICE (wxID_FILEDLGG + 8) -#define ID_TEXT (wxID_FILEDLGG + 9) -#define ID_LIST_CTRL (wxID_FILEDLGG + 10) -#define ID_CHECK (wxID_FILEDLGG + 12) +#define ID_UP_DIR (wxID_FILEDLGG + 2) +#define ID_HOME_DIR (wxID_FILEDLGG + 3) +#define ID_NEW_DIR (wxID_FILEDLGG + 4) +#define ID_FILE_CTRL (wxID_FILEDLGG + 5) IMPLEMENT_DYNAMIC_CLASS(wxGenericFileDialog, wxFileDialogBase) BEGIN_EVENT_TABLE(wxGenericFileDialog,wxDialog) - EVT_BUTTON(ID_LIST_MODE, wxGenericFileDialog::OnList) - EVT_BUTTON(ID_REPORT_MODE, wxGenericFileDialog::OnReport) - EVT_BUTTON(ID_UP_DIR, wxGenericFileDialog::OnUp) - EVT_BUTTON(ID_PARENT_DIR, wxGenericFileDialog::OnHome) - EVT_BUTTON(ID_NEW_DIR, wxGenericFileDialog::OnNew) - EVT_BUTTON(wxID_OK, wxGenericFileDialog::OnListOk) - EVT_LIST_ITEM_SELECTED(ID_LIST_CTRL, wxGenericFileDialog::OnSelected) - EVT_LIST_ITEM_ACTIVATED(ID_LIST_CTRL, wxGenericFileDialog::OnActivated) - EVT_CHOICE(ID_CHOICE,wxGenericFileDialog::OnChoiceFilter) - EVT_TEXT_ENTER(ID_TEXT,wxGenericFileDialog::OnTextEnter) - EVT_TEXT(ID_TEXT,wxGenericFileDialog::OnTextChange) - EVT_CHECKBOX(ID_CHECK,wxGenericFileDialog::OnCheck) + EVT_BUTTON(ID_LIST_MODE, wxGenericFileDialog::OnList) + EVT_BUTTON(ID_REPORT_MODE, wxGenericFileDialog::OnReport) + EVT_BUTTON(ID_UP_DIR, wxGenericFileDialog::OnUp) + EVT_BUTTON(ID_HOME_DIR, wxGenericFileDialog::OnHome) + EVT_BUTTON(ID_NEW_DIR, wxGenericFileDialog::OnNew) + EVT_BUTTON(wxID_OK, wxGenericFileDialog::OnOk) + EVT_FILECTRL_FILEACTIVATED(ID_FILE_CTRL, wxGenericFileDialog::OnFileActivated) + + EVT_UPDATE_UI(ID_UP_DIR, wxGenericFileDialog::OnUpdateButtonsUI) +#if defined(__DOS__) || defined(__WINDOWS__) || defined(__OS2__) + EVT_UPDATE_UI(ID_NEW_DIR, wxGenericFileDialog::OnUpdateButtonsUI) +#endif // defined(__DOS__) || defined(__WINDOWS__) || defined(__OS2__) END_EVENT_TABLE() long wxGenericFileDialog::ms_lastViewStyle = wxLC_LIST; @@ -874,11 +131,7 @@ void wxGenericFileDialog::Init() { m_bypassGenericImpl = false; - m_choice = NULL; - m_text = NULL; - m_list = NULL; - m_check = NULL; - m_static = NULL; + m_filectrl = NULL; m_upDirButton = NULL; m_newDirButton = NULL; } @@ -890,10 +143,12 @@ wxGenericFileDialog::wxGenericFileDialog(wxWindow *parent, const wxString& wildCard, long style, const wxPoint& pos, + const wxSize& sz, + const wxString& name, bool bypassGenericImpl ) : wxFileDialogBase() { Init(); - Create( parent, message, defaultDir, defaultFile, wildCard, style, pos, bypassGenericImpl ); + Create( parent, message, defaultDir, defaultFile, wildCard, style, pos, sz, name, bypassGenericImpl ); } bool wxGenericFileDialog::Create( wxWindow *parent, @@ -903,12 +158,16 @@ bool wxGenericFileDialog::Create( wxWindow *parent, const wxString& wildCard, long style, const wxPoint& pos, + const wxSize& sz, + const wxString& name, bool bypassGenericImpl ) { m_bypassGenericImpl = bypassGenericImpl; + parent = GetParentForModalDialog(parent); + if (!wxFileDialogBase::Create(parent, message, defaultDir, defaultFile, - wildCard, style, pos)) + wildCard, style, pos, sz, name)) { return false; } @@ -916,12 +175,14 @@ bool wxGenericFileDialog::Create( wxWindow *parent, if (m_bypassGenericImpl) return true; - if (!wxDialog::Create( parent, wxID_ANY, message, pos, wxDefaultSize, - wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER )) + if (!wxDialog::Create( parent, wxID_ANY, message, pos, sz, + wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | style, name + )) { return false; } +#if wxUSE_CONFIG if (wxConfig::Get(false)) { wxConfig::Get()->Read(wxT("/wxWindows/wxFileDialog/ViewStyle"), @@ -929,148 +190,92 @@ bool wxGenericFileDialog::Create( wxWindow *parent, wxConfig::Get()->Read(wxT("/wxWindows/wxFileDialog/ShowHidden"), &ms_lastShowHidden); } - - if (m_dialogStyle == 0) - m_dialogStyle = wxOPEN; - if ((m_dialogStyle & wxMULTIPLE ) && !(m_dialogStyle & wxOPEN)) - m_dialogStyle |= wxOPEN; +#endif if ((m_dir.empty()) || (m_dir == wxT("."))) { m_dir = wxGetCwd(); + if (m_dir.empty()) + m_dir = wxFILE_SEP_PATH; } - size_t len = m_dir.Len(); + const size_t len = m_dir.length(); if ((len > 1) && (wxEndsWithPathSeparator(m_dir))) m_dir.Remove( len-1, 1 ); - m_path = m_dir; - m_path += wxFILE_SEP_PATH; - m_path += defaultFile; m_filterExtension = wxEmptyString; // layout - bool is_pda = (wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_PDA); + const bool is_pda = (wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_PDA); wxBoxSizer *mainsizer = new wxBoxSizer( wxVERTICAL ); wxBoxSizer *buttonsizer = new wxBoxSizer( wxHORIZONTAL ); - - wxBitmapButton *but; - - but = new wxBitmapButton(this, ID_LIST_MODE, - wxArtProvider::GetBitmap(wxART_LIST_VIEW, wxART_BUTTON)); -#if wxUSE_TOOLTIPS - but->SetToolTip( _("View files as a list view") ); -#endif - buttonsizer->Add( but, 0, wxALL, 5 ); - - but = new wxBitmapButton(this, ID_REPORT_MODE, - wxArtProvider::GetBitmap(wxART_REPORT_VIEW, wxART_BUTTON)); -#if wxUSE_TOOLTIPS - but->SetToolTip( _("View files as a detailed view") ); -#endif - buttonsizer->Add( but, 0, wxALL, 5 ); - + AddBitmapButton( ID_LIST_MODE, wxART_LIST_VIEW, + _("View files as a list view"), buttonsizer ); + AddBitmapButton( ID_REPORT_MODE, wxART_REPORT_VIEW, + _("View files as a detailed view"), buttonsizer ); buttonsizer->Add( 30, 5, 1 ); - - m_upDirButton = new wxBitmapButton(this, ID_UP_DIR, - wxArtProvider::GetBitmap(wxART_GO_DIR_UP, wxART_BUTTON)); -#if wxUSE_TOOLTIPS - m_upDirButton->SetToolTip( _("Go to parent directory") ); -#endif - buttonsizer->Add( m_upDirButton, 0, wxALL, 5 ); + m_upDirButton = AddBitmapButton( ID_UP_DIR, wxART_GO_DIR_UP, + _("Go to parent directory"), buttonsizer ); #ifndef __DOS__ // VS: Home directory is meaningless in MS-DOS... - but = new wxBitmapButton(this, ID_PARENT_DIR, - wxArtProvider::GetBitmap(wxART_GO_HOME, wxART_BUTTON)); -#if wxUSE_TOOLTIPS - but->SetToolTip( _("Go to home directory") ); -#endif - buttonsizer->Add( but, 0, wxALL, 5); - + AddBitmapButton( ID_HOME_DIR, wxART_GO_HOME, + _("Go to home directory"), buttonsizer ); buttonsizer->Add( 20, 20 ); #endif //!__DOS__ - m_newDirButton = new wxBitmapButton(this, ID_NEW_DIR, - wxArtProvider::GetBitmap(wxART_NEW_DIR, wxART_BUTTON)); -#if wxUSE_TOOLTIPS - m_newDirButton->SetToolTip( _("Create new directory") ); -#endif - buttonsizer->Add( m_newDirButton, 0, wxALL, 5 ); + m_newDirButton = AddBitmapButton( ID_NEW_DIR, wxART_NEW_DIR, + _("Create new directory"), buttonsizer ); if (is_pda) - mainsizer->Add( buttonsizer, 0, wxALL | wxEXPAND, 0 ); + mainsizer->Add( buttonsizer, wxSizerFlags().Expand() ); else - mainsizer->Add( buttonsizer, 0, wxALL | wxEXPAND, 5 ); + mainsizer->Add( buttonsizer, wxSizerFlags().Expand() + .Border( wxLEFT | wxRIGHT | wxTOP ) ); - wxBoxSizer *staticsizer = new wxBoxSizer( wxHORIZONTAL ); - if (is_pda) - staticsizer->Add( new wxStaticText( this, wxID_ANY, _("Current directory:") ), 0, wxRIGHT, 10 ); - m_static = new wxStaticText( this, wxID_ANY, m_dir ); - staticsizer->Add( m_static, 1 ); - mainsizer->Add( staticsizer, 0, wxEXPAND | wxLEFT|wxRIGHT|wxBOTTOM, 10 ); + long style2 = 0; + if ( HasFdFlag(wxFD_MULTIPLE) ) + style2 |= wxFC_MULTIPLE; - long style2 = ms_lastViewStyle | wxSUNKEN_BORDER; - if ( !(m_dialogStyle & wxMULTIPLE) ) - style2 |= wxLC_SINGLE_SEL; + m_filectrl = new wxGenericFileCtrl( this, ID_FILE_CTRL, + m_dir, defaultFile, + wildCard, + style2, + wxDefaultPosition, wxSize(540,200) + ); - m_list = new wxFileCtrl( this, ID_LIST_CTRL, - wxEmptyString, ms_lastShowHidden, - wxDefaultPosition, wxSize(540,200), - style2); + m_filectrl->ShowHidden( ms_lastShowHidden ); - if (is_pda) + if (ms_lastViewStyle == wxLC_LIST) { - // PDAs have a different screen layout - mainsizer->Add( m_list, 1, wxEXPAND | wxLEFT|wxRIGHT, 5 ); - - 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 ); - mainsizer->Add( textsizer, 0, wxEXPAND ); - - m_check = NULL; - m_choice = new wxChoice( this, ID_CHOICE ); - textsizer->Add( m_choice, 1, wxCENTER|wxALL, 5 ); - - buttonsizer = new wxBoxSizer( wxHORIZONTAL ); - buttonsizer->Add( new wxButton( this, wxID_OK ), 0, wxCENTER | wxALL, 5 ); - buttonsizer->Add( new wxButton( this, wxID_CANCEL ), 0, wxCENTER | wxALL, 5 ); - mainsizer->Add( buttonsizer, 0, wxALIGN_RIGHT ); + m_filectrl->ChangeToListMode(); } - else + else if (ms_lastViewStyle == wxLC_REPORT) { - mainsizer->Add( m_list, 1, wxEXPAND | wxLEFT|wxRIGHT, 10 ); - - wxBoxSizer *textsizer = new wxBoxSizer( wxHORIZONTAL ); - m_text = new wxTextCtrl( this, ID_TEXT, m_fileName, wxDefaultPosition, wxDefaultSize, wxPROCESS_ENTER ); - textsizer->Add( m_text, 1, wxCENTER | wxLEFT|wxRIGHT|wxTOP, 10 ); - textsizer->Add( new wxButton( this, wxID_OK ), 0, wxCENTER | wxLEFT|wxRIGHT|wxTOP, 10 ); - mainsizer->Add( textsizer, 0, wxEXPAND ); - - wxBoxSizer *choicesizer = new wxBoxSizer( wxHORIZONTAL ); - m_choice = new wxChoice( this, ID_CHOICE ); - choicesizer->Add( m_choice, 1, wxCENTER|wxALL, 10 ); - m_check = new wxCheckBox( this, ID_CHECK, _("Show hidden files") ); - m_check->SetValue( ms_lastShowHidden ); - choicesizer->Add( m_check, 0, wxCENTER|wxALL, 10 ); - choicesizer->Add( new wxButton( this, wxID_CANCEL ), 0, wxCENTER | wxALL, 10 ); - mainsizer->Add( choicesizer, 0, wxEXPAND ); + m_filectrl->ChangeToReportMode(); } - SetWildcard(wildCard); + mainsizer->Add(m_filectrl, wxSizerFlags(1).Expand().HorzBorder()); - SetAutoLayout( true ); - SetSizer( mainsizer ); + wxSizer *bsizer = CreateButtonSizer(wxOK | wxCANCEL); + if ( bsizer ) + { + if (is_pda) + mainsizer->Add(bsizer, wxSizerFlags().Expand().Border()); + else + mainsizer->Add(bsizer, wxSizerFlags().Expand().DoubleBorder()); + } - mainsizer->Fit( this ); - mainsizer->SetSizeHints( this ); + SetSizer( mainsizer ); - Centre( wxBOTH ); + if (!is_pda) + { + mainsizer->SetSizeHints( this ); - m_text->SetFocus(); + Centre( wxBOTH ); + } return true; } @@ -1079,6 +284,7 @@ wxGenericFileDialog::~wxGenericFileDialog() { if (!m_bypassGenericImpl) { +#if wxUSE_CONFIG if (wxConfig::Get(false)) { wxConfig::Get()->Write(wxT("/wxWindows/wxFileDialog/ViewStyle"), @@ -1086,389 +292,115 @@ wxGenericFileDialog::~wxGenericFileDialog() wxConfig::Get()->Write(wxT("/wxWindows/wxFileDialog/ShowHidden"), ms_lastShowHidden); } - - const int count = m_choice->GetCount(); - for ( int i = 0; i < count; i++ ) - { - delete (wxString *)m_choice->GetClientData(i); - } +#endif } } -int wxGenericFileDialog::ShowModal() +wxBitmapButton* wxGenericFileDialog::AddBitmapButton( wxWindowID winId, + const wxArtID& artId, + const wxString& tip, + wxSizer *sizer) { - m_list->GoToDir(m_dir); - UpdateControls(); - m_text->SetValue(m_fileName); - - return wxDialog::ShowModal(); -} - -bool wxGenericFileDialog::Show( bool show ) -{ - if (show) - { - m_list->GoToDir(m_dir); - UpdateControls(); - m_text->SetValue(m_fileName); - } - - return wxDialog::Show( show ); + wxBitmapButton *but = new wxBitmapButton(this, winId, + wxArtProvider::GetBitmap(artId, wxART_BUTTON)); + but->SetToolTip(tip); + sizer->Add(but, wxSizerFlags().Border()); + return but; } -void wxGenericFileDialog::DoSetFilterIndex(int filterindex) +int wxGenericFileDialog::ShowModal() { - wxString *str = (wxString*) m_choice->GetClientData( filterindex ); - m_list->SetWild( *str ); - m_filterIndex = filterindex; - if ( str->Left(2) == wxT("*.") ) + if (CreateExtraControl()) { - m_filterExtension = str->Mid(1); - if (m_filterExtension == _T(".*")) - m_filterExtension.clear(); + wxSizer *sizer = GetSizer(); + sizer->Insert(2 /* after m_filectrl */, m_extraControl, + wxSizerFlags().Expand().HorzBorder()); + sizer->Fit(this); } - else - { - m_filterExtension.clear(); - } -} - -void wxGenericFileDialog::SetWildcard(const wxString& wildCard) -{ - wxFileDialogBase::SetWildcard(wildCard); - wxArrayString wildDescriptions, wildFilters; - const size_t count = wxParseCommonDialogsFilter(m_wildCard, - wildDescriptions, - wildFilters); - wxCHECK_RET( count, wxT("wxFileDialog: bad wildcard string") ); + m_filectrl->SetDirectory(m_dir); - const size_t countOld = m_choice->GetCount(); - size_t n; - for ( n = 0; n < countOld; n++ ) - { - delete (wxString *)m_choice->GetClientData(n); - } - - for ( n = 0; n < count; n++ ) - { - m_choice->Append( wildDescriptions[n], new wxString( wildFilters[n] ) ); - } - - SetFilterIndex( 0 ); -} - -void wxGenericFileDialog::SetFilterIndex( int filterindex ) -{ - m_choice->SetSelection( filterindex ); - - DoSetFilterIndex(filterindex); -} - -void wxGenericFileDialog::OnChoiceFilter( wxCommandEvent &event ) -{ - DoSetFilterIndex((int)event.GetInt()); -} - -void wxGenericFileDialog::OnCheck( wxCommandEvent &event ) -{ - m_list->ShowHidden( (ms_lastShowHidden = event.GetInt() != 0) ); -} - -void wxGenericFileDialog::OnActivated( wxListEvent &event ) -{ - HandleAction( event.m_item.m_text ); -} - -void wxGenericFileDialog::OnTextEnter( wxCommandEvent &WXUNUSED(event) ) -{ - wxCommandEvent cevent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK); - cevent.SetEventObject( this ); - GetEventHandler()->ProcessEvent( cevent ); + return wxDialog::ShowModal(); } -static bool ignoreChanges = false; - -void wxGenericFileDialog::OnTextChange( wxCommandEvent &WXUNUSED(event) ) +bool wxGenericFileDialog::Show( bool show ) { - if (!ignoreChanges) + // Called by ShowModal, so don't repeate the update +#ifndef __WIN32__ + if (show) { - // Clear selections. Otherwise when the user types in a value they may - // not get the file whose name they typed. - if (m_list->GetSelectedItemCount() > 0) - { - long item = m_list->GetNextItem(-1, wxLIST_NEXT_ALL, - wxLIST_STATE_SELECTED); - while ( item != -1 ) - { - m_list->SetItemState(item,0, wxLIST_STATE_SELECTED); - item = m_list->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - } - } + m_filectrl->SetDirectory(m_dir); } -} +#endif -void wxGenericFileDialog::OnSelected( wxListEvent &event ) -{ - wxString filename( event.m_item.m_text ); - if (filename == wxT("..")) return; - - wxString dir = m_list->GetDir(); - if (!IsTopMostDir(dir)) - dir += wxFILE_SEP_PATH; - dir += filename; - if (wxDirExists(dir)) return; - - ignoreChanges = true; - m_text->SetValue( filename ); - ignoreChanges = false; + return wxDialog::Show( show ); } -void wxGenericFileDialog::HandleAction( const wxString &fn ) +void wxGenericFileDialog::OnOk( wxCommandEvent &WXUNUSED(event) ) { - wxString filename( fn ); - wxString dir = m_list->GetDir(); - if (filename.empty()) return; - if (filename == wxT(".")) return; - - // "some/place/" means they want to chdir not try to load "place" - bool want_dir = filename.Last() == wxFILE_SEP_PATH; - if (want_dir) - filename = filename.RemoveLast(); - - if (filename == wxT("..")) - { - m_list->GoToParentDir(); - m_list->SetFocus(); - UpdateControls(); - return; - } - -#ifdef __UNIX__ - if (filename == wxT("~")) - { - m_list->GoToHomeDir(); - m_list->SetFocus(); - UpdateControls(); - return; - } - - if (filename.BeforeFirst(wxT('/')) == wxT("~")) - { - filename = wxString(wxGetUserHome()) + filename.Remove(0, 1); - } -#endif // __UNIX__ - - if (!(m_dialogStyle & wxSAVE)) - { - if ((filename.Find(wxT('*')) != wxNOT_FOUND) || - (filename.Find(wxT('?')) != wxNOT_FOUND)) - { - if (filename.Find(wxFILE_SEP_PATH) != wxNOT_FOUND) - { - wxMessageBox(_("Illegal file specification."), _("Error"), wxOK | wxICON_ERROR ); - return; - } - m_list->SetWild( filename ); - return; - } - } - - if (!IsTopMostDir(dir)) - dir += wxFILE_SEP_PATH; - if (!wxIsAbsolutePath(filename)) - { - dir += filename; - filename = dir; - } - - if (wxDirExists(filename)) - { - m_list->GoToDir( filename ); - UpdateControls(); - return; - } + wxArrayString selectedFiles; + m_filectrl->GetFilenames(selectedFiles); - // they really wanted a dir, but it doesn't exist - if (want_dir) - { - wxMessageBox(_("Directory doesn't exist."), _("Error"), - wxOK | wxICON_ERROR ); + if (selectedFiles.Count() == 0) return; - } - - // append the default extension to the filename if it doesn't have any - // - // VZ: the logic of testing for !wxFileExists() only for the open file - // dialog is not entirely clear to me, why don't we allow saving to a - // file without extension as well? - if ( !(m_dialogStyle & wxOPEN) || !wxFileExists(filename) ) - { - filename = AppendExtension(filename, m_filterExtension); - } - // check that the file [doesn't] exist if necessary - if ( (m_dialogStyle & wxSAVE) && - (m_dialogStyle & wxOVERWRITE_PROMPT) && - wxFileExists( filename ) ) + if (selectedFiles.Count() == 1) { - wxString msg; - msg.Printf( _("File '%s' already exists, do you really want to overwrite it?"), filename.c_str() ); - - if (wxMessageBox(msg, _("Confirm"), wxYES_NO) != wxYES) - return; - } - else if ( (m_dialogStyle & wxOPEN) && - (m_dialogStyle & wxFILE_MUST_EXIST) && - !wxFileExists(filename) ) - { - wxMessageBox(_("Please choose an existing file."), _("Error"), - wxOK | wxICON_ERROR ); + SetPath( selectedFiles[0] ); } - SetPath( filename ); - - // change to the directory where the user went if asked - if ( m_dialogStyle & wxCHANGE_DIR ) - { - wxString cwd; - wxSplitPath(filename, &cwd, NULL, NULL); - - if ( cwd != wxGetCwd() ) - { - wxSetWorkingDirectory(cwd); - } - } - - wxCommandEvent event; - wxDialog::OnOK(event); -} - -void wxGenericFileDialog::OnListOk( wxCommandEvent &WXUNUSED(event) ) -{ - HandleAction( m_text->GetValue() ); + EndModal(wxID_OK); } void wxGenericFileDialog::OnList( wxCommandEvent &WXUNUSED(event) ) { - m_list->ChangeToListMode(); + m_filectrl->ChangeToListMode(); ms_lastViewStyle = wxLC_LIST; - m_list->SetFocus(); + m_filectrl->GetFileList()->SetFocus(); } void wxGenericFileDialog::OnReport( wxCommandEvent &WXUNUSED(event) ) { - m_list->ChangeToReportMode(); + m_filectrl->ChangeToReportMode(); ms_lastViewStyle = wxLC_REPORT; - m_list->SetFocus(); + m_filectrl->GetFileList()->SetFocus(); } void wxGenericFileDialog::OnUp( wxCommandEvent &WXUNUSED(event) ) { - m_list->GoToParentDir(); - m_list->SetFocus(); - UpdateControls(); + m_filectrl->GoToParentDir(); + m_filectrl->GetFileList()->SetFocus(); } void wxGenericFileDialog::OnHome( wxCommandEvent &WXUNUSED(event) ) { - m_list->GoToHomeDir(); - m_list->SetFocus(); - UpdateControls(); + m_filectrl->GoToHomeDir(); + m_filectrl->SetFocus(); } void wxGenericFileDialog::OnNew( wxCommandEvent &WXUNUSED(event) ) { - m_list->MakeDir(); + m_filectrl->GetFileList()->MakeDir(); } -void wxGenericFileDialog::SetPath( const wxString& path ) +void wxGenericFileDialog::OnFileActivated( wxFileCtrlEvent &WXUNUSED(event) ) { - // not only set the full path but also update filename and dir - m_path = path; - if ( !path.empty() ) - { - wxString ext; - wxSplitPath(path, &m_dir, &m_fileName, &ext); - if (!ext.empty()) - { - m_fileName += wxT("."); - m_fileName += ext; - } - } + wxCommandEvent dummy; + OnOk( dummy ); } -void wxGenericFileDialog::GetPaths( wxArrayString& paths ) const +void wxGenericFileDialog::OnUpdateButtonsUI(wxUpdateUIEvent& event) { - paths.Empty(); - if (m_list->GetSelectedItemCount() == 0) - { - paths.Add( GetPath() ); - return; - } - - paths.Alloc( m_list->GetSelectedItemCount() ); - - wxString dir = m_list->GetDir(); -#ifdef __UNIX__ - if (dir != wxT("/")) -#endif - dir += wxFILE_SEP_PATH; - - wxListItem item; - item.m_mask = wxLIST_MASK_TEXT; - - item.m_itemId = m_list->GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED ); - while ( item.m_itemId != -1 ) - { - m_list->GetItem( item ); - paths.Add( dir + item.m_text ); - item.m_itemId = m_list->GetNextItem( item.m_itemId, - wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED ); - } -} - -void wxGenericFileDialog::GetFilenames(wxArrayString& files) const -{ - files.Empty(); - if (m_list->GetSelectedItemCount() == 0) - { - files.Add( GetFilename() ); - return; - } - files.Alloc( m_list->GetSelectedItemCount() ); - - wxListItem item; - item.m_mask = wxLIST_MASK_TEXT; - - item.m_itemId = m_list->GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED ); - while ( item.m_itemId != -1 ) - { - m_list->GetItem( item ); - files.Add( item.m_text ); - item.m_itemId = m_list->GetNextItem( item.m_itemId, - wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED ); - } + // surprisingly, we can be called before m_filectrl is set in Create() as + // wxFileCtrl ctor itself can generate idle events, so we need this test + if ( m_filectrl ) + event.Enable( !IsTopMostDir(m_filectrl->GetShownDirectory()) ); } -void wxGenericFileDialog::UpdateControls() -{ - wxString dir = m_list->GetDir(); - m_static->SetLabel(dir); +#ifdef wxHAS_GENERIC_FILEDIALOG - bool enable = !IsTopMostDir(dir); - m_upDirButton->Enable(enable); +IMPLEMENT_DYNAMIC_CLASS(wxFileDialog, wxGenericFileDialog) -#if defined(__DOS__) || defined(__WINDOWS__) || defined(__OS2__) - m_newDirButton->Enable(enable); -#endif // defined(__DOS__) || defined(__WINDOWS__) || defined(__OS2__) -} - -#ifdef USE_GENERIC_FILEDIALOG - -IMPLEMENT_DYNAMIC_CLASS(wxFileDialog, wxGenericFileDialog); - -#endif // USE_GENERIC_FILEDIALOG +#endif // wxHAS_GENERIC_FILEDIALOG #endif // wxUSE_FILEDLG -