1 ////////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxGenericFileDialog 
   4 // Author:      Robert Roebling 
   8 // Copyright:   (c) Robert Roebling 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  13 #pragma implementation "filedlgg.h" 
  16 // For compilers that support precompilation, includes "wx.h". 
  17 #include "wx/wxprec.h" 
  25 // NOTE : it probably also supports MAC, untested 
  26 #if !defined(__UNIX__) && !defined(__DOS__) && !defined(__WIN32__) && !defined(__OS2__) 
  27 #error wxGenericFileDialog currently only supports Unix, win32 and DOS 
  30 #include "wx/checkbox.h" 
  31 #include "wx/textctrl.h" 
  32 #include "wx/choice.h" 
  33 #include "wx/checkbox.h" 
  34 #include "wx/stattext.h" 
  38 #include "wx/msgdlg.h" 
  40 #include "wx/bmpbuttn.h" 
  41 #include "wx/tokenzr.h" 
  42 #include "wx/config.h" 
  43 #include "wx/imaglist.h" 
  45 #include "wx/artprov.h" 
  46 #include "wx/settings.h" 
  47 #include "wx/file.h"        // for wxS_IXXX constants only 
  48 #include "wx/filedlg.h"     // wxOPEN, wxSAVE... 
  49 #include "wx/generic/filedlgg.h" 
  50 #include "wx/generic/dirctrlg.h" // for wxFileIconsTable 
  53     #include "wx/tooltip.h" 
  56 #include <sys/types.h> 
  68     #include "wx/msw/wrapwin.h" 
  69     #include "wx/msw/mslu.h" 
  77 #if defined(__UNIX__) || defined(__DOS__) 
  81 // ---------------------------------------------------------------------------- 
  83 // ---------------------------------------------------------------------------- 
  86 int wxCALLBACK 
wxFileDataNameCompare( long data1
, long data2
, long data
) 
  88      wxFileData 
*fd1 
= (wxFileData
*)data1
; 
  89      wxFileData 
*fd2 
= (wxFileData
*)data2
; 
  90      if (fd1
->GetFileName() == wxT("..")) return -data
; 
  91      if (fd2
->GetFileName() == wxT("..")) return data
; 
  92      if (fd1
->IsDir() && !fd2
->IsDir()) return -data
; 
  93      if (fd2
->IsDir() && !fd1
->IsDir()) return data
; 
  94      return data
*wxStrcmp( fd1
->GetFileName(), fd2
->GetFileName() ); 
  98 int wxCALLBACK 
wxFileDataSizeCompare( long data1
, long data2
, long data
) 
 100      wxFileData 
*fd1 
= (wxFileData
*)data1
; 
 101      wxFileData 
*fd2 
= (wxFileData
*)data2
; 
 102      if (fd1
->GetFileName() == wxT("..")) return -data
; 
 103      if (fd2
->GetFileName() == wxT("..")) return data
; 
 104      if (fd1
->IsDir() && !fd2
->IsDir()) return -data
; 
 105      if (fd2
->IsDir() && !fd1
->IsDir()) return data
; 
 106      if (fd1
->IsLink() && !fd2
->IsLink()) return -data
; 
 107      if (fd2
->IsLink() && !fd1
->IsLink()) return data
; 
 108      return data
*(fd1
->GetSize() - fd2
->GetSize()); 
 112 int wxCALLBACK 
wxFileDataTypeCompare( long data1
, long data2
, long data
) 
 114      wxFileData 
*fd1 
= (wxFileData
*)data1
; 
 115      wxFileData 
*fd2 
= (wxFileData
*)data2
; 
 116      if (fd1
->GetFileName() == wxT("..")) return -data
; 
 117      if (fd2
->GetFileName() == wxT("..")) return data
; 
 118      if (fd1
->IsDir() && !fd2
->IsDir()) return -data
; 
 119      if (fd2
->IsDir() && !fd1
->IsDir()) return data
; 
 120      if (fd1
->IsLink() && !fd2
->IsLink()) return -data
; 
 121      if (fd2
->IsLink() && !fd1
->IsLink()) return data
; 
 122      return data
*wxStrcmp( fd1
->GetFileType(), fd2
->GetFileType() ); 
 126 int wxCALLBACK 
wxFileDataTimeCompare( long data1
, long data2
, long data
) 
 128      wxFileData 
*fd1 
= (wxFileData
*)data1
; 
 129      wxFileData 
*fd2 
= (wxFileData
*)data2
; 
 130      if (fd1
->GetFileName() == wxT("..")) return -data
; 
 131      if (fd2
->GetFileName() == wxT("..")) return data
; 
 132      if (fd1
->IsDir() && !fd2
->IsDir()) return -data
; 
 133      if (fd2
->IsDir() && !fd1
->IsDir()) return data
; 
 135      return fd1
->GetDateTime().IsLaterThan(fd2
->GetDateTime()) ? int(data
) : -int(data
); 
 138 #if defined(__UNIX__) && !defined(__OS2__) 
 139 #define IsTopMostDir(dir)   (dir == wxT("/")) 
 142 #if defined(__DOS__) || defined(__WINDOWS__) || defined (__OS2__) 
 143 #define IsTopMostDir(dir)   (dir.IsEmpty()) 
 146 #if defined(__DOS__) || defined(__WINDOWS__) || defined(__OS2__) 
 147 // defined in src/generic/dirctrlg.cpp 
 148 extern bool wxIsDriveAvailable(const wxString
& dirName
); 
 151 // defined in src/generic/dirctrlg.cpp 
 152 extern size_t wxGetAvailableDrives(wxArrayString 
&paths
, wxArrayString 
&names
, wxArrayInt 
&icon_ids
); 
 154 //----------------------------------------------------------------------------- 
 156 //----------------------------------------------------------------------------- 
 158 wxFileData::wxFileData( const wxString 
&filePath
, const wxString 
&fileName
, fileType type
, int image_id 
) 
 160     m_fileName 
= fileName
; 
 161     m_filePath 
= filePath
; 
 168 void wxFileData::Copy( const wxFileData
& fileData 
) 
 170     m_fileName 
= fileData
.GetFileName(); 
 171     m_filePath 
= fileData
.GetFilePath(); 
 172     m_size 
= fileData
.GetSize(); 
 173     m_dateTime 
= fileData
.GetDateTime(); 
 174     m_permissions 
= fileData
.GetPermissions(); 
 175     m_type 
= fileData
.GetType(); 
 176     m_image 
= GetImageId(); 
 179 void wxFileData::ReadData() 
 187 #if defined(__DOS__) || defined(__WINDOWS__) || defined(__OS2__) 
 188     // c:\.. is a drive don't stat it 
 189     if ((m_fileName 
== wxT("..")) && (m_filePath
.length() <= 5)) 
 195 #endif // __DOS__ || __WINDOWS__ 
 199 #if defined(__UNIX__) && (!defined( __OS2__ ) && !defined(__VMS)) 
 200     lstat( m_filePath
.fn_str(), &buff 
); 
 201     m_type 
|= S_ISLNK( buff
.st_mode 
) != 0 ? is_link 
: 0; 
 203     wxStat( m_filePath
, &buff 
); 
 206     m_type 
|= (buff
.st_mode 
& S_IFDIR
) != 0 ? is_dir 
: 0; 
 207     m_type 
|= (buff
.st_mode 
& wxS_IXUSR
) != 0 ? is_exe 
: 0; 
 209     // try to get a better icon 
 210     if (m_image 
== wxFileIconsTable::file
) 
 212         if (m_fileName
.Find(wxT('.'), true) != wxNOT_FOUND
) 
 214             m_image 
= wxTheFileIconsTable
->GetIconID( m_fileName
.AfterLast(wxT('.'))); 
 217             m_image 
= wxFileIconsTable::executable
; 
 221     m_size 
= buff
.st_size
; 
 223     m_dateTime 
= buff
.st_mtime
; 
 225 #if defined(__UNIX__) 
 226     m_permissions
.Printf(_T("%c%c%c%c%c%c%c%c%c"), 
 227                          buff
.st_mode 
& wxS_IRUSR 
? _T('r') : _T('-'), 
 228                          buff
.st_mode 
& wxS_IWUSR 
? _T('w') : _T('-'), 
 229                          buff
.st_mode 
& wxS_IXUSR 
? _T('x') : _T('-'), 
 230                          buff
.st_mode 
& wxS_IRGRP 
? _T('r') : _T('-'), 
 231                          buff
.st_mode 
& wxS_IWGRP 
? _T('w') : _T('-'), 
 232                          buff
.st_mode 
& wxS_IXGRP 
? _T('x') : _T('-'), 
 233                          buff
.st_mode 
& wxS_IROTH 
? _T('r') : _T('-'), 
 234                          buff
.st_mode 
& wxS_IWOTH 
? _T('w') : _T('-'), 
 235                          buff
.st_mode 
& wxS_IXOTH 
? _T('x') : _T('-')); 
 236 #elif defined(__WIN32__) 
 237     DWORD attribs 
= GetFileAttributes(m_filePath
); 
 238     if (attribs 
!= (DWORD
)-1) 
 240         m_permissions
.Printf(_T("%c%c%c%c"), 
 241                              attribs 
& FILE_ATTRIBUTE_ARCHIVE  
? _T('A') : _T(' '), 
 242                              attribs 
& FILE_ATTRIBUTE_READONLY 
? _T('R') : _T(' '), 
 243                              attribs 
& FILE_ATTRIBUTE_HIDDEN   
? _T('H') : _T(' '), 
 244                              attribs 
& FILE_ATTRIBUTE_SYSTEM   
? _T('S') : _T(' ')); 
 249 wxString 
wxFileData::GetFileType() const 
 257    else if (m_fileName
.Find(wxT('.'), true) != wxNOT_FOUND
) 
 258         return m_fileName
.AfterLast(wxT('.')); 
 260     return wxEmptyString
; 
 263 wxString 
wxFileData::GetModificationTime() const 
 265     // want time as 01:02 so they line up nicely, no %r in WIN32 
 266     return m_dateTime
.FormatDate() + wxT(" ") + m_dateTime
.Format(wxT("%I:%M:%S %p")); 
 269 wxString 
wxFileData::GetHint() const 
 271     wxString s 
= m_filePath
; 
 281         s 
+= wxString::Format( _("%ld bytes"), m_size 
); 
 287         s 
<< GetModificationTime() 
 295 wxString 
wxFileData::GetEntry( fileListFieldType num 
) const 
 305             if (!IsDir() && !IsLink() && !IsDrive()) 
 306                 s
.Printf(_T("%ld"), m_size
); 
 315                 s 
= GetModificationTime(); 
 318 #if defined(__UNIX__) || defined(__WIN32__) 
 322 #endif // defined(__UNIX__) || defined(__WIN32__) 
 325             wxFAIL_MSG( _T("unexpected field in wxFileData::GetEntry()") ); 
 331 void wxFileData::SetNewName( const wxString 
&filePath
, const wxString 
&fileName 
) 
 333     m_fileName 
= fileName
; 
 334     m_filePath 
= filePath
; 
 337 void wxFileData::MakeItem( wxListItem 
&item 
) 
 339     item
.m_text 
= m_fileName
; 
 340     item
.ClearAttributes(); 
 342         item
.SetTextColour(*wxRED
); 
 344         item
.SetTextColour(*wxBLUE
); 
 346     item
.m_image 
= m_image
; 
 350         wxColour dg 
= wxTheColourDatabase
->Find( _T("MEDIUM GREY") ); 
 352             item
.SetTextColour(dg
); 
 354     item
.m_data 
= (long)this; 
 357 //----------------------------------------------------------------------------- 
 359 //----------------------------------------------------------------------------- 
 361 IMPLEMENT_DYNAMIC_CLASS(wxFileCtrl
,wxListCtrl
) 
 363 BEGIN_EVENT_TABLE(wxFileCtrl
,wxListCtrl
) 
 364     EVT_LIST_DELETE_ITEM(wxID_ANY
, wxFileCtrl::OnListDeleteItem
) 
 365     EVT_LIST_DELETE_ALL_ITEMS(wxID_ANY
, wxFileCtrl::OnListDeleteAllItems
) 
 366     EVT_LIST_END_LABEL_EDIT(wxID_ANY
, wxFileCtrl::OnListEndLabelEdit
) 
 367     EVT_LIST_COL_CLICK(wxID_ANY
, wxFileCtrl::OnListColClick
) 
 371 wxFileCtrl::wxFileCtrl() 
 373     m_showHidden 
= false; 
 375     m_sort_field 
= wxFileData::FileList_Name
; 
 378 wxFileCtrl::wxFileCtrl(wxWindow 
*win
, 
 380                        const wxString
& wild
, 
 385                        const wxValidator 
&validator
, 
 386                        const wxString 
&name
) 
 387           : wxListCtrl(win
, id
, pos
, size
, style
, validator
, name
), 
 390     wxImageList 
*imageList 
= wxTheFileIconsTable
->GetSmallImageList(); 
 392     SetImageList( imageList
, wxIMAGE_LIST_SMALL 
); 
 394     m_showHidden 
= showHidden
; 
 397     m_sort_field 
= wxFileData::FileList_Name
; 
 399     m_dirName 
= wxT("*"); 
 401     if (style 
& wxLC_REPORT
) 
 402         ChangeToReportMode(); 
 405 void wxFileCtrl::ChangeToListMode() 
 408     SetSingleStyle( wxLC_LIST 
); 
 412 void wxFileCtrl::ChangeToReportMode() 
 415     SetSingleStyle( wxLC_REPORT 
); 
 417     // do this since WIN32 does mm/dd/yy UNIX does mm/dd/yyyy 
 418     // don't hardcode since mm/dd is dd/mm elsewhere 
 420     wxDateTime 
dt(22, wxDateTime::Dec
, 2002, 22, 22, 22); 
 421     wxString txt 
= dt
.FormatDate() + wxT("22") + dt
.Format(wxT("%I:%M:%S %p")); 
 422     GetTextExtent(txt
, &w
, &h
); 
 424     InsertColumn( 0, _("Name"), wxLIST_FORMAT_LEFT
, w 
); 
 425     InsertColumn( 1, _("Size"), wxLIST_FORMAT_LEFT
, w
/2 ); 
 426     InsertColumn( 2, _("Type"), wxLIST_FORMAT_LEFT
, w
/2 ); 
 427     InsertColumn( 3, _("Modified"), wxLIST_FORMAT_LEFT
, w 
); 
 428 #if defined(__UNIX__) 
 429     GetTextExtent(wxT("Permissions 2"), &w
, &h
); 
 430     InsertColumn( 4, _("Permissions"), wxLIST_FORMAT_LEFT
, w 
); 
 431 #elif defined(__WIN32__) 
 432     GetTextExtent(wxT("Attributes 2"), &w
, &h
); 
 433     InsertColumn( 4, _("Attributes"), wxLIST_FORMAT_LEFT
, w 
); 
 439 void wxFileCtrl::ChangeToSmallIconMode() 
 442     SetSingleStyle( wxLC_SMALL_ICON 
); 
 446 void wxFileCtrl::ShowHidden( bool show 
) 
 452 long wxFileCtrl::Add( wxFileData 
*fd
, wxListItem 
&item 
) 
 455     item
.m_mask 
= wxLIST_MASK_TEXT 
+ wxLIST_MASK_DATA 
+ wxLIST_MASK_IMAGE
; 
 456     fd
->MakeItem( item 
); 
 457     long my_style 
= GetWindowStyleFlag(); 
 458     if (my_style 
& wxLC_REPORT
) 
 460         ret 
= InsertItem( item 
); 
 461         for (int i 
= 1; i 
< wxFileData::FileList_Max
; i
++) 
 462             SetItem( item
.m_itemId
, i
, fd
->GetEntry((wxFileData::fileListFieldType
)i
) ); 
 464     else if ((my_style 
& wxLC_LIST
) || (my_style 
& wxLC_SMALL_ICON
)) 
 466         ret 
= InsertItem( item 
); 
 471 void wxFileCtrl::UpdateItem(const wxListItem 
&item
) 
 473     wxFileData 
*fd 
= (wxFileData
*)GetItemData(item
); 
 474     wxCHECK_RET(fd
, wxT("invalid filedata")); 
 478     SetItemText(item
, fd
->GetFileName()); 
 479     SetItemImage(item
, fd
->GetImageId(), fd
->GetImageId()); 
 481     if (GetWindowStyleFlag() & wxLC_REPORT
) 
 483         for (int i 
= 1; i 
< wxFileData::FileList_Max
; i
++) 
 484             SetItem( item
.m_itemId
, i
, fd
->GetEntry((wxFileData::fileListFieldType
)i
) ); 
 488 void wxFileCtrl::UpdateFiles() 
 490     // don't do anything before ShowModal() call which sets m_dirName 
 491     if ( m_dirName 
== wxT("*") ) 
 494     wxBusyCursor bcur
; // this may take a while... 
 502 #if defined(__WINDOWS__) || defined(__DOS__) || defined(__WXMAC__) || defined(__OS2__) 
 503     if ( IsTopMostDir(m_dirName
) ) 
 505         wxArrayString names
, paths
; 
 507         size_t n
, count 
= wxGetAvailableDrives(paths
, names
, icons
); 
 509         for (n
=0; n
<count
; n
++) 
 511             wxFileData 
*fd 
= new wxFileData(paths
[n
], names
[n
], wxFileData::is_drive
, icons
[n
]); 
 512             if (Add(fd
, item
) != -1) 
 519 #endif // defined(__DOS__) || defined(__WINDOWS__) 
 522         if ( !IsTopMostDir(m_dirName
) ) 
 524             wxString 
p(wxPathOnly(m_dirName
)); 
 525 #if defined(__UNIX__) && !defined(__OS2__) 
 526             if (p
.IsEmpty()) p 
= wxT("/"); 
 528             wxFileData 
*fd 
= new wxFileData(p
, wxT(".."), wxFileData::is_dir
, wxFileIconsTable::folder
); 
 529             if (Add(fd
, item
) != -1) 
 535         wxString 
dirname(m_dirName
); 
 536 #if defined(__DOS__) || defined(__WINDOWS__) || defined(__OS2__) 
 537         if (dirname
.length() == 2 && dirname
[1u] == wxT(':')) 
 538             dirname 
<< wxT('\\'); 
 539 #endif // defined(__DOS__) || defined(__WINDOWS__) || defined(__OS2__) 
 542         if ( dir
.IsOpened() ) 
 544             wxString 
dirPrefix(dirname
); 
 545             if (dirPrefix
.Last() != wxFILE_SEP_PATH
) 
 546                 dirPrefix 
+= wxFILE_SEP_PATH
; 
 548             int hiddenFlag 
= m_showHidden 
? wxDIR_HIDDEN 
: 0; 
 553             // Get the directories first (not matched against wildcards): 
 554             cont 
= dir
.GetFirst(&f
, wxEmptyString
, wxDIR_DIRS 
| hiddenFlag
); 
 557                 wxFileData 
*fd 
= new wxFileData(dirPrefix 
+ f
, f
, wxFileData::is_dir
, wxFileIconsTable::folder
); 
 558                 if (Add(fd
, item
) != -1) 
 563                 cont 
= dir
.GetNext(&f
); 
 566             // Tokenize the wildcard string, so we can handle more than 1 
 567             // search pattern in a wildcard. 
 568             wxStringTokenizer 
tokenWild(m_wild
, wxT(";")); 
 569             while ( tokenWild
.HasMoreTokens() ) 
 571                 cont 
= dir
.GetFirst(&f
, tokenWild
.GetNextToken(), 
 572                                         wxDIR_FILES 
| hiddenFlag
); 
 575                     wxFileData 
*fd 
= new wxFileData(dirPrefix 
+ f
, f
, wxFileData::is_file
, wxFileIconsTable::file
); 
 576                     if (Add(fd
, item
) != -1) 
 581                     cont 
= dir
.GetNext(&f
); 
 587     SortItems(m_sort_field
, m_sort_foward
); 
 590 void wxFileCtrl::SetWild( const wxString 
&wild 
) 
 592     if (wild
.Find(wxT('|')) != wxNOT_FOUND
) 
 599 void wxFileCtrl::MakeDir() 
 601     wxString 
new_name( _("NewName") ); 
 602     wxString 
path( m_dirName 
); 
 603     path 
+= wxFILE_SEP_PATH
; 
 605     if (wxFileExists(path
)) 
 607         // try NewName0, NewName1 etc. 
 610             new_name 
= _("NewName"); 
 612             num
.Printf( wxT("%d"), i 
); 
 616             path 
+= wxFILE_SEP_PATH
; 
 619         } while (wxFileExists(path
)); 
 625         wxMessageDialog 
dialog(this, _("Operation not permitted."), _("Error"), wxOK 
| wxICON_ERROR 
); 
 630     wxFileData 
*fd 
= new wxFileData( path
, new_name
, wxFileData::is_dir
, wxFileIconsTable::folder 
); 
 634     long id 
= Add( fd
, item 
); 
 638         SortItems(m_sort_field
, m_sort_foward
); 
 639         id 
= FindItem( 0, (long)fd 
); 
 647 void wxFileCtrl::GoToParentDir() 
 649     if (!IsTopMostDir(m_dirName
)) 
 651         size_t len 
= m_dirName
.Len(); 
 652         if (wxEndsWithPathSeparator(m_dirName
)) 
 653             m_dirName
.Remove( len
-1, 1 ); 
 654         wxString 
fname( wxFileNameFromPath(m_dirName
) ); 
 655         m_dirName 
= wxPathOnly( m_dirName 
); 
 656 #if defined(__DOS__) || defined(__WINDOWS__) || defined(__OS2__) 
 657         if (!m_dirName
.IsEmpty()) 
 659             if (m_dirName
.Last() == wxT('.')) 
 660                 m_dirName 
= wxEmptyString
; 
 662 #elif defined(__UNIX__) 
 663         if (m_dirName
.IsEmpty()) 
 664             m_dirName 
= wxT("/"); 
 667         long id 
= FindItem( 0, fname 
); 
 670             SetItemState( id
, wxLIST_STATE_SELECTED
, wxLIST_STATE_SELECTED 
); 
 676 void wxFileCtrl::GoToHomeDir() 
 678     wxString s 
= wxGetUserHome( wxString() ); 
 682 void wxFileCtrl::GoToDir( const wxString 
&dir 
) 
 684     if (!wxDirExists(dir
)) return; 
 688     SetItemState( 0, wxLIST_STATE_SELECTED
, wxLIST_STATE_SELECTED 
); 
 692 void wxFileCtrl::FreeItemData(wxListItem
& item
) 
 696         wxFileData 
*fd 
= (wxFileData
*)item
.m_data
; 
 703 void wxFileCtrl::OnListDeleteItem( wxListEvent 
&event 
) 
 705     FreeItemData(event
.m_item
); 
 708 void wxFileCtrl::OnListDeleteAllItems( wxListEvent 
& WXUNUSED(event
) ) 
 713 void wxFileCtrl::FreeAllItemsData() 
 716     item
.m_mask 
= wxLIST_MASK_DATA
; 
 718     item
.m_itemId 
= GetNextItem( -1, wxLIST_NEXT_ALL 
); 
 719     while ( item
.m_itemId 
!= -1 ) 
 723         item
.m_itemId 
= GetNextItem( item
.m_itemId
, wxLIST_NEXT_ALL 
); 
 727 void wxFileCtrl::OnListEndLabelEdit( wxListEvent 
&event 
) 
 729     wxFileData 
*fd 
= (wxFileData
*)event
.m_item
.m_data
; 
 732     if ((event
.GetLabel().IsEmpty()) || 
 733         (event
.GetLabel() == _(".")) || 
 734         (event
.GetLabel() == _("..")) || 
 735         (event
.GetLabel().First( wxFILE_SEP_PATH 
) != wxNOT_FOUND
)) 
 737         wxMessageDialog 
dialog(this, _("Illegal directory name."), _("Error"), wxOK 
| wxICON_ERROR 
); 
 743     wxString 
new_name( wxPathOnly( fd
->GetFilePath() ) ); 
 744     new_name 
+= wxFILE_SEP_PATH
; 
 745     new_name 
+= event
.GetLabel(); 
 749     if (wxFileExists(new_name
)) 
 751         wxMessageDialog 
dialog(this, _("File name exists already."), _("Error"), wxOK 
| wxICON_ERROR 
); 
 756     if (wxRenameFile(fd
->GetFilePath(),new_name
)) 
 758         fd
->SetNewName( new_name
, event
.GetLabel() ); 
 759         SetItemState( event
.GetItem(), wxLIST_STATE_SELECTED
, wxLIST_STATE_SELECTED 
); 
 760         UpdateItem( event
.GetItem() ); 
 761         EnsureVisible( event
.GetItem() ); 
 765         wxMessageDialog 
dialog(this, _("Operation not permitted."), _("Error"), wxOK 
| wxICON_ERROR 
); 
 771 void wxFileCtrl::OnListColClick( wxListEvent 
&event 
) 
 773     int col 
= event
.GetColumn(); 
 777         case wxFileData::FileList_Name 
: 
 778         case wxFileData::FileList_Size 
: 
 779         case wxFileData::FileList_Type 
: 
 780         case wxFileData::FileList_Time 
: break; 
 784     if ((wxFileData::fileListFieldType
)col 
== m_sort_field
) 
 785         m_sort_foward 
= !m_sort_foward
; 
 787         m_sort_field 
= (wxFileData::fileListFieldType
)col
; 
 789     SortItems(m_sort_field
, m_sort_foward
); 
 792 void wxFileCtrl::SortItems(wxFileData::fileListFieldType field
, bool foward
) 
 794     m_sort_field 
= field
; 
 795     m_sort_foward 
= foward
; 
 796     long sort_dir 
= foward 
? 1 : -1; 
 798     switch (m_sort_field
) 
 800         case wxFileData::FileList_Name 
: 
 802             wxListCtrl::SortItems((wxListCtrlCompare
)wxFileDataNameCompare
, sort_dir
); 
 805         case wxFileData::FileList_Size 
: 
 807              wxListCtrl::SortItems((wxListCtrlCompare
)wxFileDataSizeCompare
, sort_dir
); 
 810         case wxFileData::FileList_Type 
: 
 812              wxListCtrl::SortItems((wxListCtrlCompare
)wxFileDataTypeCompare
, sort_dir
); 
 815         case wxFileData::FileList_Time 
: 
 817              wxListCtrl::SortItems((wxListCtrlCompare
)wxFileDataTimeCompare
, sort_dir
); 
 824 wxFileCtrl::~wxFileCtrl() 
 828 //----------------------------------------------------------------------------- 
 829 // wxGenericFileDialog 
 830 //----------------------------------------------------------------------------- 
 832 #define  ID_LIST_MODE     (wxID_FILEDLGG    ) 
 833 #define  ID_REPORT_MODE   (wxID_FILEDLGG + 1) 
 834 #define  ID_UP_DIR        (wxID_FILEDLGG + 5) 
 835 #define  ID_PARENT_DIR    (wxID_FILEDLGG + 6) 
 836 #define  ID_NEW_DIR       (wxID_FILEDLGG + 7) 
 837 #define  ID_CHOICE        (wxID_FILEDLGG + 8) 
 838 #define  ID_TEXT          (wxID_FILEDLGG + 9) 
 839 #define  ID_LIST_CTRL     (wxID_FILEDLGG + 10) 
 840 #define  ID_ACTIVATED     (wxID_FILEDLGG + 11) 
 841 #define  ID_CHECK         (wxID_FILEDLGG + 12) 
 843 IMPLEMENT_DYNAMIC_CLASS(wxGenericFileDialog
, wxFileDialogBase
) 
 845 BEGIN_EVENT_TABLE(wxGenericFileDialog
,wxDialog
) 
 846         EVT_BUTTON(ID_LIST_MODE
, wxGenericFileDialog::OnList
) 
 847         EVT_BUTTON(ID_REPORT_MODE
, wxGenericFileDialog::OnReport
) 
 848         EVT_BUTTON(ID_UP_DIR
, wxGenericFileDialog::OnUp
) 
 849         EVT_BUTTON(ID_PARENT_DIR
, wxGenericFileDialog::OnHome
) 
 850         EVT_BUTTON(ID_NEW_DIR
, wxGenericFileDialog::OnNew
) 
 851         EVT_BUTTON(wxID_OK
, wxGenericFileDialog::OnListOk
) 
 852         EVT_LIST_ITEM_SELECTED(ID_LIST_CTRL
, wxGenericFileDialog::OnSelected
) 
 853         EVT_LIST_ITEM_ACTIVATED(ID_LIST_CTRL
, wxGenericFileDialog::OnActivated
) 
 854         EVT_CHOICE(ID_CHOICE
,wxGenericFileDialog::OnChoiceFilter
) 
 855         EVT_TEXT_ENTER(ID_TEXT
,wxGenericFileDialog::OnTextEnter
) 
 856         EVT_TEXT(ID_TEXT
,wxGenericFileDialog::OnTextChange
) 
 857         EVT_CHECKBOX(ID_CHECK
,wxGenericFileDialog::OnCheck
) 
 860 long wxGenericFileDialog::ms_lastViewStyle 
= wxLC_LIST
; 
 861 bool wxGenericFileDialog::ms_lastShowHidden 
= false; 
 863 wxGenericFileDialog::wxGenericFileDialog(wxWindow 
*parent
, 
 864                            const wxString
& message
, 
 865                            const wxString
& defaultDir
, 
 866                            const wxString
& defaultFile
, 
 867                            const wxString
& wildCard
, 
 870                     :wxFileDialogBase(parent
, message
, defaultDir
, defaultFile
, wildCard
, style
, pos
) 
 872     wxDialog::Create( parent
, wxID_ANY
, message
, pos
, wxDefaultSize
, 
 873                       wxDEFAULT_DIALOG_STYLE 
| wxRESIZE_BORDER 
); 
 875     if (wxConfig::Get(false)) 
 877         wxConfig::Get()->Read(wxT("/wxWindows/wxFileDialog/ViewStyle"), 
 879         wxConfig::Get()->Read(wxT("/wxWindows/wxFileDialog/ShowHidden"), 
 883     if (m_dialogStyle 
== 0) 
 884         m_dialogStyle 
= wxOPEN
; 
 885     if ((m_dialogStyle 
& wxMULTIPLE 
) && !(m_dialogStyle 
& wxOPEN
)) 
 886         m_dialogStyle 
|= wxOPEN
; 
 888     if ((m_dir
.empty()) || (m_dir 
== wxT("."))) 
 893     size_t len 
= m_dir
.Len(); 
 894     if ((len 
> 1) && (wxEndsWithPathSeparator(m_dir
))) 
 895         m_dir
.Remove( len
-1, 1 ); 
 898     m_path 
+= wxFILE_SEP_PATH
; 
 899     m_path 
+= defaultFile
; 
 900     m_filterExtension 
= wxEmptyString
; 
 902     // interpret wildcards 
 903     wxArrayString wildDescriptions
, wildFilters
; 
 904     if ( !wxParseCommonDialogsFilter(m_wildCard
, wildDescriptions
, wildFilters
) ) 
 906         wxFAIL_MSG( wxT("Wrong file type description") ); 
 911     bool is_pda 
= (wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_PDA
); 
 913     wxBoxSizer 
*mainsizer 
= new wxBoxSizer( wxVERTICAL 
); 
 915     wxBoxSizer 
*buttonsizer 
= new wxBoxSizer( wxHORIZONTAL 
); 
 919     but 
= new wxBitmapButton(this, ID_LIST_MODE
, 
 920                              wxArtProvider::GetBitmap(wxART_LIST_VIEW
, wxART_CMN_DIALOG
)); 
 922     but
->SetToolTip( _("View files as a list view") ); 
 924     buttonsizer
->Add( but
, 0, wxALL
, 5 ); 
 926     but 
= new wxBitmapButton(this, ID_REPORT_MODE
, 
 927                              wxArtProvider::GetBitmap(wxART_REPORT_VIEW
, wxART_CMN_DIALOG
)); 
 929     but
->SetToolTip( _("View files as a detailed view") ); 
 931     buttonsizer
->Add( but
, 0, wxALL
, 5 ); 
 933     buttonsizer
->Add( 30, 5, 1 ); 
 935     m_upDirButton 
= new wxBitmapButton(this, ID_UP_DIR
, 
 936                            wxArtProvider::GetBitmap(wxART_GO_DIR_UP
, wxART_CMN_DIALOG
)); 
 938     m_upDirButton
->SetToolTip( _("Go to parent directory") ); 
 940     buttonsizer
->Add( m_upDirButton
, 0, wxALL
, 5 ); 
 942 #ifndef __DOS__ // VS: Home directory is meaningless in MS-DOS... 
 943     but 
= new wxBitmapButton(this, ID_PARENT_DIR
, 
 944                              wxArtProvider::GetBitmap(wxART_GO_HOME
, wxART_CMN_DIALOG
)); 
 946     but
->SetToolTip( _("Go to home directory") ); 
 948     buttonsizer
->Add( but
, 0, wxALL
, 5); 
 950     buttonsizer
->Add( 20, 20 ); 
 953     m_newDirButton 
= new wxBitmapButton(this, ID_NEW_DIR
, 
 954                            wxArtProvider::GetBitmap(wxART_NEW_DIR
, wxART_CMN_DIALOG
)); 
 956     m_newDirButton
->SetToolTip( _("Create new directory") ); 
 958     buttonsizer
->Add( m_newDirButton
, 0, wxALL
, 5 ); 
 961         mainsizer
->Add( buttonsizer
, 0, wxALL 
| wxEXPAND
, 0 ); 
 963         mainsizer
->Add( buttonsizer
, 0, wxALL 
| wxEXPAND
, 5 ); 
 965     wxBoxSizer 
*staticsizer 
= new wxBoxSizer( wxHORIZONTAL 
); 
 967         staticsizer
->Add( new wxStaticText( this, wxID_ANY
, _("Current directory:") ), 0, wxRIGHT
, 10 ); 
 968     m_static 
= new wxStaticText( this, wxID_ANY
, m_dir 
); 
 969     staticsizer
->Add( m_static
, 1 ); 
 970     mainsizer
->Add( staticsizer
, 0, wxEXPAND 
| wxLEFT
|wxRIGHT
|wxBOTTOM
, 10 ); 
 972     long style2 
= ms_lastViewStyle 
| wxSUNKEN_BORDER
; 
 973     if ( !(m_dialogStyle 
& wxMULTIPLE
) ) 
 974         style2 
|= wxLC_SINGLE_SEL
; 
 976     m_list 
= new wxFileCtrl( this, ID_LIST_CTRL
, 
 977                              wildFilters
[0], ms_lastShowHidden
, 
 978                              wxDefaultPosition
, wxSize(540,200), 
 983         // PDAs have a different screen layout 
 984         mainsizer
->Add( m_list
, 1, wxEXPAND 
| wxLEFT
|wxRIGHT
, 5 ); 
 986         wxBoxSizer 
*textsizer 
= new wxBoxSizer( wxHORIZONTAL 
); 
 987         m_text 
= new wxTextCtrl( this, ID_TEXT
, m_fileName
, wxDefaultPosition
, wxDefaultSize
, wxPROCESS_ENTER 
); 
 988         textsizer
->Add( m_text
, 1, wxCENTER 
| wxALL
, 5 ); 
 989         mainsizer
->Add( textsizer
, 0, wxEXPAND 
); 
 992         m_choice 
= new wxChoice( this, ID_CHOICE 
); 
 993         textsizer
->Add( m_choice
, 1, wxCENTER
|wxALL
, 5 ); 
 995         buttonsizer 
= new wxBoxSizer( wxHORIZONTAL 
); 
 996         buttonsizer
->Add( new wxButton( this, wxID_OK
, _("OK") ), 0, wxCENTER 
| wxALL
, 5 ); 
 997         buttonsizer
->Add( new wxButton( this, wxID_CANCEL
, _("Cancel") ), 0, wxCENTER 
| wxALL
, 5 ); 
 998         mainsizer
->Add( buttonsizer
, 0, wxALIGN_RIGHT 
); 
1002         mainsizer
->Add( m_list
, 1, wxEXPAND 
| wxLEFT
|wxRIGHT
, 10 ); 
1004         wxBoxSizer 
*textsizer 
= new wxBoxSizer( wxHORIZONTAL 
); 
1005         m_text 
= new wxTextCtrl( this, ID_TEXT
, m_fileName
, wxDefaultPosition
, wxDefaultSize
, wxPROCESS_ENTER 
); 
1006         textsizer
->Add( m_text
, 1, wxCENTER 
| wxLEFT
|wxRIGHT
|wxTOP
, 10 ); 
1007         textsizer
->Add( new wxButton( this, wxID_OK
, _("OK") ), 0, wxCENTER 
| wxLEFT
|wxRIGHT
|wxTOP
, 10 ); 
1008         mainsizer
->Add( textsizer
, 0, wxEXPAND 
); 
1010         wxBoxSizer 
*choicesizer 
= new wxBoxSizer( wxHORIZONTAL 
); 
1011         m_choice 
= new wxChoice( this, ID_CHOICE 
); 
1012         choicesizer
->Add( m_choice
, 1, wxCENTER
|wxALL
, 10 ); 
1013         m_check 
= new wxCheckBox( this, ID_CHECK
, _("Show hidden files") ); 
1014         m_check
->SetValue( ms_lastShowHidden 
); 
1015         choicesizer
->Add( m_check
, 0, wxCENTER
|wxALL
, 10 ); 
1016         choicesizer
->Add( new wxButton( this, wxID_CANCEL
, _("Cancel") ), 0, wxCENTER 
| wxALL
, 10 ); 
1017         mainsizer
->Add( choicesizer
, 0, wxEXPAND 
); 
1020     for (size_t n
=0; n
<wildFilters
.GetCount(); n
++) 
1022         m_choice
->Append( wildDescriptions
[n
], (void*) new wxString( wildFilters
[n
] ) ); 
1024     SetFilterIndex( 0 ); 
1026     SetAutoLayout( true ); 
1027     SetSizer( mainsizer 
); 
1029     mainsizer
->Fit( this ); 
1030     mainsizer
->SetSizeHints( this ); 
1037 wxGenericFileDialog::~wxGenericFileDialog() 
1039     if (wxConfig::Get(false)) 
1041         wxConfig::Get()->Write(wxT("/wxWindows/wxFileDialog/ViewStyle"), 
1043         wxConfig::Get()->Write(wxT("/wxWindows/wxFileDialog/ShowHidden"), 
1047     const int count 
= m_choice
->GetCount(); 
1048     for ( int i 
= 0; i 
< count
; i
++ ) 
1050         delete (wxString 
*)m_choice
->GetClientData(i
); 
1054 int wxGenericFileDialog::ShowModal() 
1056     m_list
->GoToDir(m_dir
); 
1058     m_text
->SetValue(m_fileName
); 
1060     return wxDialog::ShowModal(); 
1063 bool wxGenericFileDialog::Show( bool show 
) 
1067         m_list
->GoToDir(m_dir
); 
1069         m_text
->SetValue(m_fileName
); 
1072     return wxDialog::Show( show 
); 
1075 void wxGenericFileDialog::DoSetFilterIndex(int filterindex
) 
1077     wxString 
*str 
= (wxString
*) m_choice
->GetClientData( filterindex 
); 
1078     m_list
->SetWild( *str 
); 
1079     m_filterIndex 
= filterindex
; 
1080     if ( str
->Left(2) == wxT("*.") ) 
1082         m_filterExtension 
= str
->Mid(1); 
1083         if (m_filterExtension 
== _T(".*")) 
1084             m_filterExtension
.clear(); 
1088         m_filterExtension
.clear(); 
1092 void wxGenericFileDialog::SetFilterIndex( int filterindex 
) 
1094     m_choice
->SetSelection( filterindex 
); 
1096     DoSetFilterIndex(filterindex
); 
1099 void wxGenericFileDialog::OnChoiceFilter( wxCommandEvent 
&event 
) 
1101     DoSetFilterIndex((int)event
.GetInt()); 
1104 void wxGenericFileDialog::OnCheck( wxCommandEvent 
&event 
) 
1106     m_list
->ShowHidden( (ms_lastShowHidden 
= event
.GetInt() != 0) ); 
1109 void wxGenericFileDialog::OnActivated( wxListEvent 
&event 
) 
1111     HandleAction( event
.m_item
.m_text 
); 
1114 void wxGenericFileDialog::OnTextEnter( wxCommandEvent 
&WXUNUSED(event
) ) 
1116     wxCommandEvent 
cevent(wxEVT_COMMAND_BUTTON_CLICKED
, wxID_OK
); 
1117     cevent
.SetEventObject( this ); 
1118     GetEventHandler()->ProcessEvent( cevent 
); 
1121 static bool ignoreChanges 
= false; 
1123 void wxGenericFileDialog::OnTextChange( wxCommandEvent 
&WXUNUSED(event
) ) 
1127         // Clear selections.  Otherwise when the user types in a value they may 
1128         // not get the file whose name they typed. 
1129         if (m_list
->GetSelectedItemCount() > 0) 
1131             long item 
= m_list
->GetNextItem(-1, wxLIST_NEXT_ALL
, 
1132                 wxLIST_STATE_SELECTED
); 
1133             while ( item 
!= -1 ) 
1135                 m_list
->SetItemState(item
,0, wxLIST_STATE_SELECTED
); 
1136                 item 
= m_list
->GetNextItem(item
, wxLIST_NEXT_ALL
, wxLIST_STATE_SELECTED
); 
1142 void wxGenericFileDialog::OnSelected( wxListEvent 
&event 
) 
1144     wxString 
filename( event
.m_item
.m_text 
); 
1145     if (filename 
== wxT("..")) return; 
1147     wxString dir 
= m_list
->GetDir(); 
1148     if (!IsTopMostDir(dir
)) 
1149         dir 
+= wxFILE_SEP_PATH
; 
1151     if (wxDirExists(dir
)) return; 
1153     ignoreChanges 
= true; 
1154     m_text
->SetValue( filename 
); 
1155     ignoreChanges 
= false; 
1158 void wxGenericFileDialog::HandleAction( const wxString 
&fn 
) 
1160     wxString 
filename( fn 
); 
1161     wxString dir 
= m_list
->GetDir(); 
1162     if (filename
.IsEmpty()) return; 
1163     if (filename 
== wxT(".")) return; 
1165     // "some/place/" means they want to chdir not try to load "place" 
1166     bool want_dir 
= filename
.Last() == wxFILE_SEP_PATH
; 
1168         filename 
= filename
.RemoveLast(); 
1170     if (filename 
== wxT("..")) 
1172         m_list
->GoToParentDir(); 
1179     if (filename 
== wxT("~")) 
1181         m_list
->GoToHomeDir(); 
1187     if (filename
.BeforeFirst(wxT('/')) == wxT("~")) 
1189         filename 
= wxGetUserHome() + filename
.Remove(0, 1); 
1193     if ((filename
.Find(wxT('*')) != wxNOT_FOUND
) || 
1194         (filename
.Find(wxT('?')) != wxNOT_FOUND
)) 
1196         if (filename
.Find(wxFILE_SEP_PATH
) != wxNOT_FOUND
) 
1198             wxMessageBox(_("Illegal file specification."), _("Error"), wxOK 
| wxICON_ERROR 
); 
1201         m_list
->SetWild( filename 
); 
1205     if (!IsTopMostDir(dir
)) 
1206         dir 
+= wxFILE_SEP_PATH
; 
1207     if (!wxIsAbsolutePath(filename
)) 
1213     if (wxDirExists(filename
)) 
1215         m_list
->GoToDir( filename 
); 
1220     // they really wanted a dir, but it doesn't exist 
1223         wxMessageBox(_("Directory doesn't exist."), _("Error"), 
1224                      wxOK 
| wxICON_ERROR 
); 
1228     // append the default extension to the filename if it doesn't have any 
1230     // VZ: the logic of testing for !wxFileExists() only for the open file 
1231     //     dialog is not entirely clear to me, why don't we allow saving to a 
1232     //     file without extension as well? 
1233     if ( !(m_dialogStyle 
& wxOPEN
) || !wxFileExists(filename
) ) 
1235         filename 
= AppendExtension(filename
, m_filterExtension
); 
1238     // check that the file [doesn't] exist if necessary 
1239     if ( (m_dialogStyle 
& wxSAVE
) && 
1240             (m_dialogStyle 
& wxOVERWRITE_PROMPT
) && 
1241                 wxFileExists( filename 
) ) 
1244         msg
.Printf( _("File '%s' already exists, do you really want to overwrite it?"), filename
.c_str() ); 
1246         if (wxMessageBox(msg
, _("Confirm"), wxYES_NO
) != wxYES
) 
1249     else if ( (m_dialogStyle 
& wxOPEN
) && 
1250                 (m_dialogStyle 
& wxFILE_MUST_EXIST
) && 
1251                     !wxFileExists(filename
) ) 
1253         wxMessageBox(_("Please choose an existing file."), _("Error"), 
1254                      wxOK 
| wxICON_ERROR 
); 
1257     SetPath( filename 
); 
1259     // change to the directory where the user went if asked 
1260     if ( m_dialogStyle 
& wxCHANGE_DIR 
) 
1263         wxSplitPath(filename
, &cwd
, NULL
, NULL
); 
1265         if ( cwd 
!= wxGetCwd() ) 
1267             wxSetWorkingDirectory(cwd
); 
1271     wxCommandEvent event
; 
1272     wxDialog::OnOK(event
); 
1275 void wxGenericFileDialog::OnListOk( wxCommandEvent 
&WXUNUSED(event
) ) 
1277     HandleAction( m_text
->GetValue() ); 
1280 void wxGenericFileDialog::OnList( wxCommandEvent 
&WXUNUSED(event
) ) 
1282     m_list
->ChangeToListMode(); 
1283     ms_lastViewStyle 
= wxLC_LIST
; 
1287 void wxGenericFileDialog::OnReport( wxCommandEvent 
&WXUNUSED(event
) ) 
1289     m_list
->ChangeToReportMode(); 
1290     ms_lastViewStyle 
= wxLC_REPORT
; 
1294 void wxGenericFileDialog::OnUp( wxCommandEvent 
&WXUNUSED(event
) ) 
1296     m_list
->GoToParentDir(); 
1301 void wxGenericFileDialog::OnHome( wxCommandEvent 
&WXUNUSED(event
) ) 
1303     m_list
->GoToHomeDir(); 
1308 void wxGenericFileDialog::OnNew( wxCommandEvent 
&WXUNUSED(event
) ) 
1313 void wxGenericFileDialog::SetPath( const wxString
& path 
) 
1315     // not only set the full path but also update filename and dir 
1317     if ( !path
.empty() ) 
1320         wxSplitPath(path
, &m_dir
, &m_fileName
, &ext
); 
1323             m_fileName 
+= wxT("."); 
1329 void wxGenericFileDialog::GetPaths( wxArrayString
& paths 
) const 
1332     if (m_list
->GetSelectedItemCount() == 0) 
1334         paths
.Add( GetPath() ); 
1338     paths
.Alloc( m_list
->GetSelectedItemCount() ); 
1340     wxString dir 
= m_list
->GetDir(); 
1342     if (dir 
!= wxT("/")) 
1344         dir 
+= wxFILE_SEP_PATH
; 
1347     item
.m_mask 
= wxLIST_MASK_TEXT
; 
1349     item
.m_itemId 
= m_list
->GetNextItem( -1, wxLIST_NEXT_ALL
, wxLIST_STATE_SELECTED 
); 
1350     while ( item
.m_itemId 
!= -1 ) 
1352         m_list
->GetItem( item 
); 
1353         paths
.Add( dir 
+ item
.m_text 
); 
1354         item
.m_itemId 
= m_list
->GetNextItem( item
.m_itemId
, 
1355             wxLIST_NEXT_ALL
, wxLIST_STATE_SELECTED 
); 
1359 void wxGenericFileDialog::GetFilenames(wxArrayString
& files
) const 
1362     if (m_list
->GetSelectedItemCount() == 0) 
1364         files
.Add( GetFilename() ); 
1367     files
.Alloc( m_list
->GetSelectedItemCount() ); 
1370     item
.m_mask 
= wxLIST_MASK_TEXT
; 
1372     item
.m_itemId 
= m_list
->GetNextItem( -1, wxLIST_NEXT_ALL
, wxLIST_STATE_SELECTED 
); 
1373     while ( item
.m_itemId 
!= -1 ) 
1375         m_list
->GetItem( item 
); 
1376         files
.Add( item
.m_text 
); 
1377         item
.m_itemId 
= m_list
->GetNextItem( item
.m_itemId
, 
1378             wxLIST_NEXT_ALL
, wxLIST_STATE_SELECTED 
); 
1382 void wxGenericFileDialog::UpdateControls() 
1384     wxString dir 
= m_list
->GetDir(); 
1385     m_static
->SetLabel(dir
); 
1387     bool enable 
= !IsTopMostDir(dir
); 
1388     m_upDirButton
->Enable(enable
); 
1390 #if defined(__DOS__) || defined(__WINDOWS__) || defined(__OS2__) 
1391     m_newDirButton
->Enable(enable
); 
1392 #endif // defined(__DOS__) || defined(__WINDOWS__) || defined(__OS2__) 
1395 #ifdef USE_GENERIC_FILEDIALOG 
1397 IMPLEMENT_DYNAMIC_CLASS(wxFileDialog
, wxGenericFileDialog
); 
1399 #endif // USE_GENERIC_FILEDIALOG 
1401 #endif // wxUSE_FILEDLG