From: Julian Smart Date: Mon, 6 Mar 2006 10:44:48 +0000 (+0000) Subject: Fixed wxGenericFileDialog to work with WinCE, so it can be used to X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/619111b9aa66549dd55fec55c07be63d5b19ae88 Fixed wxGenericFileDialog to work with WinCE, so it can be used to replace native dialog that doesn't allow access to all folders. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@37827 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/docs/changes.txt b/docs/changes.txt index bb9b5f2edf..d8f127eca3 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -212,6 +212,7 @@ wxWinCE: directly, however. - Added support for the context menu event (wxContextMenuEvent) and added platform-specific wxWindow::EnableContextMenu. +- Fixed wxGenericFileDialog to work with WinCE. wxUniv: diff --git a/docs/latex/wx/wxmsw.tex b/docs/latex/wx/wxmsw.tex index afe1710e96..ca86dc1fb1 100644 --- a/docs/latex/wx/wxmsw.tex +++ b/docs/latex/wx/wxmsw.tex @@ -319,8 +319,11 @@ Allowing the user to access files on memory cards, or on arbitrary parts of the filesystem, is a pain; the standard file dialog only shows folders under My Documents or folders on memory cards (not the system or card root directory, for example). This is -a known problem for PocketPC developers, and a wxFileDialog -replacement will need to be written. +a known problem for PocketPC developers. + +If you need a file dialog that allows access to all folders, +you can use wxGenericFileDialog instead. You will need to include +{\tt wx/generic/filedlgg.h}. \subsubsection{Embedded Visual C++ Issues} @@ -362,8 +365,6 @@ show the SIP automatically using the WC\_SIPREF control. the correct size on the emulator, but too small on a VGA Pocket Loox device. \item {\bf wxStaticLine.} Lines don't show up, and the documentation suggests that missing styles are implemented with WM\_PAINT. -\item {\bf wxFileDialog.} A more flexible dialog needs to be written (probably using wxGenericFileDialog) -that can access arbitrary locations. \item {\bf HTML control.} PocketPC has its own HTML control which can be used for showing local pages or navigating the web. We should create a version of wxHtmlWindow that uses this control, or have a separately-named control (wxHtmlCtrl), with a syntax as close as possible to wxHtmlWindow. diff --git a/src/generic/filedlgg.cpp b/src/generic/filedlgg.cpp index fc92b7327a..efbe7253ed 100644 --- a/src/generic/filedlgg.cpp +++ b/src/generic/filedlgg.cpp @@ -41,6 +41,7 @@ #include "wx/dir.h" #include "wx/artprov.h" #include "wx/settings.h" +#include "wx/filefn.h" #include "wx/file.h" // for wxS_IXXX constants only #include "wx/filedlg.h" // wxOPEN, wxSAVE... #include "wx/generic/filedlgg.h" @@ -50,8 +51,10 @@ #include "wx/tooltip.h" #endif +#ifndef __WXWINCE__ #include #include +#endif #ifdef __UNIX__ #include @@ -70,7 +73,10 @@ #include #endif +#ifndef __WXWINCE__ #include +#endif + #if defined(__UNIX__) || defined(__DOS__) #include #endif @@ -159,7 +165,9 @@ int wxCALLBACK wxFileDataTimeCompare(long data1, long data2, long sortOrder) return fd1->GetDateTime().IsLaterThan(fd2->GetDateTime()) ? sortOrder : -sortOrder; } -#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("/")) @@ -209,7 +217,7 @@ void wxFileData::ReadData() return; } -#if defined(__DOS__) || defined(__WINDOWS__) || defined(__OS2__) +#if defined(__DOS__) || (defined(__WINDOWS__) && !defined(__WXWINCE__)) || defined(__OS2__) // c:\.. is a drive don't stat it if ((m_fileName == wxT("..")) && (m_filePath.length() <= 5)) { @@ -219,6 +227,40 @@ void wxFileData::ReadData() } #endif // __DOS__ || __WINDOWS__ +#ifdef __WXWINCE__ + + // WinCE + + DWORD fileAttribs = GetFileAttributes(m_filePath.fn_str()); + m_type |= (fileAttribs & FILE_ATTRIBUTE_DIRECTORY) != 0 ? is_dir : 0; + + wxString p, f, ext; + wxSplitPath(m_filePath, & p, & f, & ext); + if (wxStricmp(ext, wxT("exe")) == 0) + m_type |= is_exe; + + // Find out size + m_size = 0; + HANDLE fileHandle = CreateFile(m_filePath.fn_str(), + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if (fileHandle != INVALID_HANDLE_VALUE) + { + m_size = GetFileSize(fileHandle, 0); + CloseHandle(fileHandle); + } + + m_dateTime = wxFileModificationTime(m_filePath); + +#else + + // OTHER PLATFORMS + wxStructStat buff; #if defined(__UNIX__) && (!defined( __OS2__ ) && !defined(__VMS)) @@ -237,22 +279,12 @@ void wxFileData::ReadData() 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 = buff.st_size; m_dateTime = buff.st_mtime; - +#endif + // __WXWINCE__ + #if defined(__UNIX__) m_permissions.Printf(_T("%c%c%c%c%c%c%c%c%c"), buff.st_mode & wxS_IRUSR ? _T('r') : _T('-'), @@ -265,7 +297,7 @@ void wxFileData::ReadData() buff.st_mode & wxS_IWOTH ? _T('w') : _T('-'), buff.st_mode & wxS_IXOTH ? _T('x') : _T('-')); #elif defined(__WIN32__) - DWORD attribs = GetFileAttributes(m_filePath); + DWORD attribs = GetFileAttributes(m_filePath.fn_str()); if (attribs != (DWORD)-1) { m_permissions.Printf(_T("%c%c%c%c"), @@ -275,6 +307,18 @@ void wxFileData::ReadData() attribs & FILE_ATTRIBUTE_SYSTEM ? _T('S') : _T(' ')); } #endif + + // 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; + } + } } wxString wxFileData::GetFileType() const @@ -390,6 +434,8 @@ void wxFileData::MakeItem( wxListItem &item ) // wxFileCtrl //----------------------------------------------------------------------------- +static bool ignoreChanges = false; + IMPLEMENT_DYNAMIC_CLASS(wxFileCtrl,wxListCtrl) BEGIN_EVENT_TABLE(wxFileCtrl,wxListCtrl) @@ -531,7 +577,7 @@ void wxFileCtrl::UpdateFiles() item.m_itemId = 0; item.m_col = 0; -#if defined(__WINDOWS__) || defined(__DOS__) || defined(__WXMAC__) || defined(__OS2__) +#if (defined(__WINDOWS__) || defined(__DOS__) || defined(__WXMAC__) || defined(__OS2__)) && !defined(__WXWINCE__) if ( IsTopMostDir(m_dirName) ) { wxArrayString names, paths; @@ -551,10 +597,10 @@ void wxFileCtrl::UpdateFiles() #endif // defined(__DOS__) || defined(__WINDOWS__) { // Real directory... - if ( !IsTopMostDir(m_dirName) ) + if ( !IsTopMostDir(m_dirName) && !m_dirName.empty() ) { wxString p(wxPathOnly(m_dirName)); -#if defined(__UNIX__) && !defined(__OS2__) +#if (defined(__UNIX__) || defined(__WXWINCE__)) && !defined(__OS2__) if (p.empty()) p = wxT("/"); #endif // __UNIX__ wxFileData *fd = new wxFileData(p, wxT(".."), wxFileData::is_dir, wxFileIconsTable::folder); @@ -569,6 +615,11 @@ void wxFileCtrl::UpdateFiles() if (dirname.length() == 2 && dirname[1u] == wxT(':')) dirname << wxT('\\'); #endif // defined(__DOS__) || defined(__WINDOWS__) || defined(__OS2__) + + if (dirname.empty()) + dirname = wxFILE_SEP_PATH; + + wxLogNull logNull; wxDir dir(dirname); if ( dir.IsOpened() ) @@ -699,8 +750,10 @@ void wxFileCtrl::GoToParentDir() long id = FindItem( 0, fname ); if (id != wxNOT_FOUND) { + ignoreChanges = true; SetItemState( id, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED ); EnsureVisible( id ); + ignoreChanges = false; } } } @@ -717,7 +770,11 @@ void wxFileCtrl::GoToDir( const wxString &dir ) m_dirName = dir; UpdateFiles(); + + ignoreChanges = true; SetItemState( 0, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED ); + ignoreChanges = false; + EnsureVisible( 0 ); } @@ -788,7 +845,11 @@ void wxFileCtrl::OnListEndLabelEdit( wxListEvent &event ) if (wxRenameFile(fd->GetFilePath(),new_name)) { fd->SetNewName( new_name, event.GetLabel() ); + + ignoreChanges = true; SetItemState( event.GetItem(), wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED ); + ignoreChanges = false; + UpdateItem( event.GetItem() ); EnsureVisible( event.GetItem() ); } @@ -942,6 +1003,8 @@ bool wxGenericFileDialog::Create( wxWindow *parent, return false; } + ignoreChanges = true; + if (wxConfig::Get(false)) { wxConfig::Get()->Read(wxT("/wxWindows/wxFileDialog/ViewStyle"), @@ -958,6 +1021,8 @@ bool wxGenericFileDialog::Create( wxWindow *parent, 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(); @@ -1032,10 +1097,16 @@ bool wxGenericFileDialog::Create( wxWindow *parent, staticsizer->Add( m_static, 1 ); mainsizer->Add( staticsizer, 0, wxEXPAND | wxLEFT|wxRIGHT|wxBOTTOM, 10 ); - long style2 = ms_lastViewStyle | wxSUNKEN_BORDER; + long style2 = ms_lastViewStyle; if ( !(m_dialogStyle & wxMULTIPLE) ) style2 |= wxLC_SINGLE_SEL; +#ifdef __WXWINCE__ + style2 |= wxSIMPLE_BORDER; +#else + style2 |= wxSUNKEN_BORDER; +#endif + m_list = new wxFileCtrl( this, ID_LIST_CTRL, wxEmptyString, ms_lastShowHidden, wxDefaultPosition, wxSize(540,200), @@ -1085,18 +1156,25 @@ bool wxGenericFileDialog::Create( wxWindow *parent, SetAutoLayout( true ); SetSizer( mainsizer ); - mainsizer->Fit( this ); - mainsizer->SetSizeHints( this ); - - Centre( wxBOTH ); + if (!is_pda) + { + mainsizer->Fit( this ); + mainsizer->SetSizeHints( this ); + Centre( wxBOTH ); + } + m_text->SetFocus(); + + ignoreChanges = false; return true; } wxGenericFileDialog::~wxGenericFileDialog() { + ignoreChanges = true; + if (!m_bypassGenericImpl) { if (wxConfig::Get(false)) @@ -1117,21 +1195,28 @@ wxGenericFileDialog::~wxGenericFileDialog() int wxGenericFileDialog::ShowModal() { + ignoreChanges = true; + m_list->GoToDir(m_dir); UpdateControls(); m_text->SetValue(m_fileName); + ignoreChanges = false; + return wxDialog::ShowModal(); } bool wxGenericFileDialog::Show( bool show ) { + // Called by ShowModal, so don't repeate the update +#ifndef __WIN32__ if (show) { m_list->GoToDir(m_dir); UpdateControls(); m_text->SetValue(m_fileName); } +#endif return wxDialog::Show( show ); } @@ -1207,8 +1292,6 @@ void wxGenericFileDialog::OnTextEnter( wxCommandEvent &WXUNUSED(event) ) GetEventHandler()->ProcessEvent( cevent ); } -static bool ignoreChanges = false; - void wxGenericFileDialog::OnTextChange( wxCommandEvent &WXUNUSED(event) ) { if (!ignoreChanges) @@ -1230,7 +1313,18 @@ void wxGenericFileDialog::OnTextChange( wxCommandEvent &WXUNUSED(event) ) void wxGenericFileDialog::OnSelected( wxListEvent &event ) { + static bool inSelected = false; + + if (inSelected) + return; + + inSelected = true; wxString filename( event.m_item.m_text ); + +#ifdef __WXWINCE__ + // No double-click on most WinCE devices, so do action immediately. + HandleAction( filename ); +#else if (filename == wxT("..")) return; wxString dir = m_list->GetDir(); @@ -1242,10 +1336,15 @@ void wxGenericFileDialog::OnSelected( wxListEvent &event ) ignoreChanges = true; m_text->SetValue( filename ); ignoreChanges = false; +#endif + inSelected = false; } void wxGenericFileDialog::HandleAction( const wxString &fn ) { + if (ignoreChanges) + return; + wxString filename( fn ); wxString dir = m_list->GetDir(); if (filename.empty()) return; @@ -1258,18 +1357,22 @@ void wxGenericFileDialog::HandleAction( const wxString &fn ) if (filename == wxT("..")) { + ignoreChanges = true; m_list->GoToParentDir(); m_list->SetFocus(); UpdateControls(); + ignoreChanges = false; return; } #ifdef __UNIX__ if (filename == wxT("~")) { + ignoreChanges = true; m_list->GoToHomeDir(); m_list->SetFocus(); UpdateControls(); + ignoreChanges = false; return; } @@ -1304,8 +1407,10 @@ void wxGenericFileDialog::HandleAction( const wxString &fn ) if (wxDirExists(filename)) { + ignoreChanges = true; m_list->GoToDir( filename ); UpdateControls(); + ignoreChanges = false; return; } @@ -1371,41 +1476,59 @@ void wxGenericFileDialog::OnListOk( wxCommandEvent &WXUNUSED(event) ) void wxGenericFileDialog::OnList( wxCommandEvent &WXUNUSED(event) ) { + ignoreChanges = true; m_list->ChangeToListMode(); ms_lastViewStyle = wxLC_LIST; m_list->SetFocus(); + ignoreChanges = false; } void wxGenericFileDialog::OnReport( wxCommandEvent &WXUNUSED(event) ) { + ignoreChanges = true; m_list->ChangeToReportMode(); ms_lastViewStyle = wxLC_REPORT; m_list->SetFocus(); + ignoreChanges = false; } void wxGenericFileDialog::OnUp( wxCommandEvent &WXUNUSED(event) ) { + ignoreChanges = true; m_list->GoToParentDir(); m_list->SetFocus(); UpdateControls(); + ignoreChanges = false; } void wxGenericFileDialog::OnHome( wxCommandEvent &WXUNUSED(event) ) { + ignoreChanges = true; m_list->GoToHomeDir(); m_list->SetFocus(); UpdateControls(); + ignoreChanges = false; } void wxGenericFileDialog::OnNew( wxCommandEvent &WXUNUSED(event) ) { + ignoreChanges = true; + m_list->MakeDir(); + + ignoreChanges = false; } void wxGenericFileDialog::SetPath( const wxString& path ) { // not only set the full path but also update filename and dir m_path = path; + +#ifdef __WXWINCE__ + if (m_path.empty()) + m_path = wxFILE_SEP_PATH; +#endif + if ( !path.empty() ) { wxString ext; @@ -1432,6 +1555,9 @@ void wxGenericFileDialog::GetPaths( wxArrayString& paths ) const wxString dir = m_list->GetDir(); #ifdef __UNIX__ if (dir != wxT("/")) +#endif +#ifdef __WXWINCE__ + if (dir != wxT("/") && dir != wxT("\\")) #endif dir += wxFILE_SEP_PATH;