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
This commit is contained in:
Julian Smart
2006-03-06 10:44:48 +00:00
parent d83959ef7c
commit 619111b9aa
3 changed files with 158 additions and 30 deletions

View File

@@ -212,6 +212,7 @@ wxWinCE:
directly, however. directly, however.
- Added support for the context menu event (wxContextMenuEvent) - Added support for the context menu event (wxContextMenuEvent)
and added platform-specific wxWindow::EnableContextMenu. and added platform-specific wxWindow::EnableContextMenu.
- Fixed wxGenericFileDialog to work with WinCE.
wxUniv: wxUniv:

View File

@@ -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 parts of the filesystem, is a pain; the standard file dialog only
shows folders under My Documents or folders on memory cards shows folders under My Documents or folders on memory cards
(not the system or card root directory, for example). This is (not the system or card root directory, for example). This is
a known problem for PocketPC developers, and a wxFileDialog a known problem for PocketPC developers.
replacement will need to be written.
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} \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. 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 \item {\bf wxStaticLine.} Lines don't show up, and the documentation suggests that
missing styles are implemented with WM\_PAINT. 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 \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 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. control, or have a separately-named control (wxHtmlCtrl), with a syntax as close as possible to wxHtmlWindow.

View File

@@ -41,6 +41,7 @@
#include "wx/dir.h" #include "wx/dir.h"
#include "wx/artprov.h" #include "wx/artprov.h"
#include "wx/settings.h" #include "wx/settings.h"
#include "wx/filefn.h"
#include "wx/file.h" // for wxS_IXXX constants only #include "wx/file.h" // for wxS_IXXX constants only
#include "wx/filedlg.h" // wxOPEN, wxSAVE... #include "wx/filedlg.h" // wxOPEN, wxSAVE...
#include "wx/generic/filedlgg.h" #include "wx/generic/filedlgg.h"
@@ -50,8 +51,10 @@
#include "wx/tooltip.h" #include "wx/tooltip.h"
#endif #endif
#ifndef __WXWINCE__
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#endif
#ifdef __UNIX__ #ifdef __UNIX__
#include <dirent.h> #include <dirent.h>
@@ -70,7 +73,10 @@
#include <direct.h> #include <direct.h>
#endif #endif
#ifndef __WXWINCE__
#include <time.h> #include <time.h>
#endif
#if defined(__UNIX__) || defined(__DOS__) #if defined(__UNIX__) || defined(__DOS__)
#include <unistd.h> #include <unistd.h>
#endif #endif
@@ -159,7 +165,9 @@ int wxCALLBACK wxFileDataTimeCompare(long data1, long data2, long sortOrder)
return fd1->GetDateTime().IsLaterThan(fd2->GetDateTime()) ? sortOrder : -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()) #define IsTopMostDir(dir) (dir.empty())
#else #else
#define IsTopMostDir(dir) (dir == wxT("/")) #define IsTopMostDir(dir) (dir == wxT("/"))
@@ -209,7 +217,7 @@ void wxFileData::ReadData()
return; 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 // c:\.. is a drive don't stat it
if ((m_fileName == wxT("..")) && (m_filePath.length() <= 5)) if ((m_fileName == wxT("..")) && (m_filePath.length() <= 5))
{ {
@@ -219,6 +227,40 @@ void wxFileData::ReadData()
} }
#endif // __DOS__ || __WINDOWS__ #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; wxStructStat buff;
#if defined(__UNIX__) && (!defined( __OS2__ ) && !defined(__VMS)) #if defined(__UNIX__) && (!defined( __OS2__ ) && !defined(__VMS))
@@ -237,21 +279,11 @@ void wxFileData::ReadData()
m_type |= (buff.st_mode & S_IFDIR) != 0 ? is_dir : 0; m_type |= (buff.st_mode & S_IFDIR) != 0 ? is_dir : 0;
m_type |= (buff.st_mode & wxS_IXUSR) != 0 ? is_exe : 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_size = buff.st_size;
m_dateTime = buff.st_mtime; m_dateTime = buff.st_mtime;
#endif
// __WXWINCE__
#if defined(__UNIX__) #if defined(__UNIX__)
m_permissions.Printf(_T("%c%c%c%c%c%c%c%c%c"), m_permissions.Printf(_T("%c%c%c%c%c%c%c%c%c"),
@@ -265,7 +297,7 @@ void wxFileData::ReadData()
buff.st_mode & wxS_IWOTH ? _T('w') : _T('-'), buff.st_mode & wxS_IWOTH ? _T('w') : _T('-'),
buff.st_mode & wxS_IXOTH ? _T('x') : _T('-')); buff.st_mode & wxS_IXOTH ? _T('x') : _T('-'));
#elif defined(__WIN32__) #elif defined(__WIN32__)
DWORD attribs = GetFileAttributes(m_filePath); DWORD attribs = GetFileAttributes(m_filePath.fn_str());
if (attribs != (DWORD)-1) if (attribs != (DWORD)-1)
{ {
m_permissions.Printf(_T("%c%c%c%c"), m_permissions.Printf(_T("%c%c%c%c"),
@@ -275,6 +307,18 @@ void wxFileData::ReadData()
attribs & FILE_ATTRIBUTE_SYSTEM ? _T('S') : _T(' ')); attribs & FILE_ATTRIBUTE_SYSTEM ? _T('S') : _T(' '));
} }
#endif #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 wxString wxFileData::GetFileType() const
@@ -390,6 +434,8 @@ void wxFileData::MakeItem( wxListItem &item )
// wxFileCtrl // wxFileCtrl
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static bool ignoreChanges = false;
IMPLEMENT_DYNAMIC_CLASS(wxFileCtrl,wxListCtrl) IMPLEMENT_DYNAMIC_CLASS(wxFileCtrl,wxListCtrl)
BEGIN_EVENT_TABLE(wxFileCtrl,wxListCtrl) BEGIN_EVENT_TABLE(wxFileCtrl,wxListCtrl)
@@ -531,7 +577,7 @@ void wxFileCtrl::UpdateFiles()
item.m_itemId = 0; item.m_itemId = 0;
item.m_col = 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) ) if ( IsTopMostDir(m_dirName) )
{ {
wxArrayString names, paths; wxArrayString names, paths;
@@ -551,10 +597,10 @@ void wxFileCtrl::UpdateFiles()
#endif // defined(__DOS__) || defined(__WINDOWS__) #endif // defined(__DOS__) || defined(__WINDOWS__)
{ {
// Real directory... // Real directory...
if ( !IsTopMostDir(m_dirName) ) if ( !IsTopMostDir(m_dirName) && !m_dirName.empty() )
{ {
wxString p(wxPathOnly(m_dirName)); wxString p(wxPathOnly(m_dirName));
#if defined(__UNIX__) && !defined(__OS2__) #if (defined(__UNIX__) || defined(__WXWINCE__)) && !defined(__OS2__)
if (p.empty()) p = wxT("/"); if (p.empty()) p = wxT("/");
#endif // __UNIX__ #endif // __UNIX__
wxFileData *fd = new wxFileData(p, wxT(".."), wxFileData::is_dir, wxFileIconsTable::folder); 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(':')) if (dirname.length() == 2 && dirname[1u] == wxT(':'))
dirname << wxT('\\'); dirname << wxT('\\');
#endif // defined(__DOS__) || defined(__WINDOWS__) || defined(__OS2__) #endif // defined(__DOS__) || defined(__WINDOWS__) || defined(__OS2__)
if (dirname.empty())
dirname = wxFILE_SEP_PATH;
wxLogNull logNull;
wxDir dir(dirname); wxDir dir(dirname);
if ( dir.IsOpened() ) if ( dir.IsOpened() )
@@ -699,8 +750,10 @@ void wxFileCtrl::GoToParentDir()
long id = FindItem( 0, fname ); long id = FindItem( 0, fname );
if (id != wxNOT_FOUND) if (id != wxNOT_FOUND)
{ {
ignoreChanges = true;
SetItemState( id, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED ); SetItemState( id, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED );
EnsureVisible( id ); EnsureVisible( id );
ignoreChanges = false;
} }
} }
} }
@@ -717,7 +770,11 @@ void wxFileCtrl::GoToDir( const wxString &dir )
m_dirName = dir; m_dirName = dir;
UpdateFiles(); UpdateFiles();
ignoreChanges = true;
SetItemState( 0, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED ); SetItemState( 0, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED );
ignoreChanges = false;
EnsureVisible( 0 ); EnsureVisible( 0 );
} }
@@ -788,7 +845,11 @@ void wxFileCtrl::OnListEndLabelEdit( wxListEvent &event )
if (wxRenameFile(fd->GetFilePath(),new_name)) if (wxRenameFile(fd->GetFilePath(),new_name))
{ {
fd->SetNewName( new_name, event.GetLabel() ); fd->SetNewName( new_name, event.GetLabel() );
ignoreChanges = true;
SetItemState( event.GetItem(), wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED ); SetItemState( event.GetItem(), wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED );
ignoreChanges = false;
UpdateItem( event.GetItem() ); UpdateItem( event.GetItem() );
EnsureVisible( event.GetItem() ); EnsureVisible( event.GetItem() );
} }
@@ -942,6 +1003,8 @@ bool wxGenericFileDialog::Create( wxWindow *parent,
return false; return false;
} }
ignoreChanges = true;
if (wxConfig::Get(false)) if (wxConfig::Get(false))
{ {
wxConfig::Get()->Read(wxT("/wxWindows/wxFileDialog/ViewStyle"), wxConfig::Get()->Read(wxT("/wxWindows/wxFileDialog/ViewStyle"),
@@ -958,6 +1021,8 @@ bool wxGenericFileDialog::Create( wxWindow *parent,
if ((m_dir.empty()) || (m_dir == wxT("."))) if ((m_dir.empty()) || (m_dir == wxT(".")))
{ {
m_dir = wxGetCwd(); m_dir = wxGetCwd();
if (m_dir.empty())
m_dir = wxFILE_SEP_PATH;
} }
size_t len = m_dir.Len(); size_t len = m_dir.Len();
@@ -1032,10 +1097,16 @@ bool wxGenericFileDialog::Create( wxWindow *parent,
staticsizer->Add( m_static, 1 ); staticsizer->Add( m_static, 1 );
mainsizer->Add( staticsizer, 0, wxEXPAND | wxLEFT|wxRIGHT|wxBOTTOM, 10 ); mainsizer->Add( staticsizer, 0, wxEXPAND | wxLEFT|wxRIGHT|wxBOTTOM, 10 );
long style2 = ms_lastViewStyle | wxSUNKEN_BORDER; long style2 = ms_lastViewStyle;
if ( !(m_dialogStyle & wxMULTIPLE) ) if ( !(m_dialogStyle & wxMULTIPLE) )
style2 |= wxLC_SINGLE_SEL; style2 |= wxLC_SINGLE_SEL;
#ifdef __WXWINCE__
style2 |= wxSIMPLE_BORDER;
#else
style2 |= wxSUNKEN_BORDER;
#endif
m_list = new wxFileCtrl( this, ID_LIST_CTRL, m_list = new wxFileCtrl( this, ID_LIST_CTRL,
wxEmptyString, ms_lastShowHidden, wxEmptyString, ms_lastShowHidden,
wxDefaultPosition, wxSize(540,200), wxDefaultPosition, wxSize(540,200),
@@ -1085,18 +1156,25 @@ bool wxGenericFileDialog::Create( wxWindow *parent,
SetAutoLayout( true ); SetAutoLayout( true );
SetSizer( mainsizer ); SetSizer( mainsizer );
if (!is_pda)
{
mainsizer->Fit( this ); mainsizer->Fit( this );
mainsizer->SetSizeHints( this ); mainsizer->SetSizeHints( this );
Centre( wxBOTH ); Centre( wxBOTH );
}
m_text->SetFocus(); m_text->SetFocus();
ignoreChanges = false;
return true; return true;
} }
wxGenericFileDialog::~wxGenericFileDialog() wxGenericFileDialog::~wxGenericFileDialog()
{ {
ignoreChanges = true;
if (!m_bypassGenericImpl) if (!m_bypassGenericImpl)
{ {
if (wxConfig::Get(false)) if (wxConfig::Get(false))
@@ -1117,21 +1195,28 @@ wxGenericFileDialog::~wxGenericFileDialog()
int wxGenericFileDialog::ShowModal() int wxGenericFileDialog::ShowModal()
{ {
ignoreChanges = true;
m_list->GoToDir(m_dir); m_list->GoToDir(m_dir);
UpdateControls(); UpdateControls();
m_text->SetValue(m_fileName); m_text->SetValue(m_fileName);
ignoreChanges = false;
return wxDialog::ShowModal(); return wxDialog::ShowModal();
} }
bool wxGenericFileDialog::Show( bool show ) bool wxGenericFileDialog::Show( bool show )
{ {
// Called by ShowModal, so don't repeate the update
#ifndef __WIN32__
if (show) if (show)
{ {
m_list->GoToDir(m_dir); m_list->GoToDir(m_dir);
UpdateControls(); UpdateControls();
m_text->SetValue(m_fileName); m_text->SetValue(m_fileName);
} }
#endif
return wxDialog::Show( show ); return wxDialog::Show( show );
} }
@@ -1207,8 +1292,6 @@ void wxGenericFileDialog::OnTextEnter( wxCommandEvent &WXUNUSED(event) )
GetEventHandler()->ProcessEvent( cevent ); GetEventHandler()->ProcessEvent( cevent );
} }
static bool ignoreChanges = false;
void wxGenericFileDialog::OnTextChange( wxCommandEvent &WXUNUSED(event) ) void wxGenericFileDialog::OnTextChange( wxCommandEvent &WXUNUSED(event) )
{ {
if (!ignoreChanges) if (!ignoreChanges)
@@ -1230,7 +1313,18 @@ void wxGenericFileDialog::OnTextChange( wxCommandEvent &WXUNUSED(event) )
void wxGenericFileDialog::OnSelected( wxListEvent &event ) void wxGenericFileDialog::OnSelected( wxListEvent &event )
{ {
static bool inSelected = false;
if (inSelected)
return;
inSelected = true;
wxString filename( event.m_item.m_text ); 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; if (filename == wxT("..")) return;
wxString dir = m_list->GetDir(); wxString dir = m_list->GetDir();
@@ -1242,10 +1336,15 @@ void wxGenericFileDialog::OnSelected( wxListEvent &event )
ignoreChanges = true; ignoreChanges = true;
m_text->SetValue( filename ); m_text->SetValue( filename );
ignoreChanges = false; ignoreChanges = false;
#endif
inSelected = false;
} }
void wxGenericFileDialog::HandleAction( const wxString &fn ) void wxGenericFileDialog::HandleAction( const wxString &fn )
{ {
if (ignoreChanges)
return;
wxString filename( fn ); wxString filename( fn );
wxString dir = m_list->GetDir(); wxString dir = m_list->GetDir();
if (filename.empty()) return; if (filename.empty()) return;
@@ -1258,18 +1357,22 @@ void wxGenericFileDialog::HandleAction( const wxString &fn )
if (filename == wxT("..")) if (filename == wxT(".."))
{ {
ignoreChanges = true;
m_list->GoToParentDir(); m_list->GoToParentDir();
m_list->SetFocus(); m_list->SetFocus();
UpdateControls(); UpdateControls();
ignoreChanges = false;
return; return;
} }
#ifdef __UNIX__ #ifdef __UNIX__
if (filename == wxT("~")) if (filename == wxT("~"))
{ {
ignoreChanges = true;
m_list->GoToHomeDir(); m_list->GoToHomeDir();
m_list->SetFocus(); m_list->SetFocus();
UpdateControls(); UpdateControls();
ignoreChanges = false;
return; return;
} }
@@ -1304,8 +1407,10 @@ void wxGenericFileDialog::HandleAction( const wxString &fn )
if (wxDirExists(filename)) if (wxDirExists(filename))
{ {
ignoreChanges = true;
m_list->GoToDir( filename ); m_list->GoToDir( filename );
UpdateControls(); UpdateControls();
ignoreChanges = false;
return; return;
} }
@@ -1371,41 +1476,59 @@ void wxGenericFileDialog::OnListOk( wxCommandEvent &WXUNUSED(event) )
void wxGenericFileDialog::OnList( wxCommandEvent &WXUNUSED(event) ) void wxGenericFileDialog::OnList( wxCommandEvent &WXUNUSED(event) )
{ {
ignoreChanges = true;
m_list->ChangeToListMode(); m_list->ChangeToListMode();
ms_lastViewStyle = wxLC_LIST; ms_lastViewStyle = wxLC_LIST;
m_list->SetFocus(); m_list->SetFocus();
ignoreChanges = false;
} }
void wxGenericFileDialog::OnReport( wxCommandEvent &WXUNUSED(event) ) void wxGenericFileDialog::OnReport( wxCommandEvent &WXUNUSED(event) )
{ {
ignoreChanges = true;
m_list->ChangeToReportMode(); m_list->ChangeToReportMode();
ms_lastViewStyle = wxLC_REPORT; ms_lastViewStyle = wxLC_REPORT;
m_list->SetFocus(); m_list->SetFocus();
ignoreChanges = false;
} }
void wxGenericFileDialog::OnUp( wxCommandEvent &WXUNUSED(event) ) void wxGenericFileDialog::OnUp( wxCommandEvent &WXUNUSED(event) )
{ {
ignoreChanges = true;
m_list->GoToParentDir(); m_list->GoToParentDir();
m_list->SetFocus(); m_list->SetFocus();
UpdateControls(); UpdateControls();
ignoreChanges = false;
} }
void wxGenericFileDialog::OnHome( wxCommandEvent &WXUNUSED(event) ) void wxGenericFileDialog::OnHome( wxCommandEvent &WXUNUSED(event) )
{ {
ignoreChanges = true;
m_list->GoToHomeDir(); m_list->GoToHomeDir();
m_list->SetFocus(); m_list->SetFocus();
UpdateControls(); UpdateControls();
ignoreChanges = false;
} }
void wxGenericFileDialog::OnNew( wxCommandEvent &WXUNUSED(event) ) void wxGenericFileDialog::OnNew( wxCommandEvent &WXUNUSED(event) )
{ {
ignoreChanges = true;
m_list->MakeDir(); m_list->MakeDir();
ignoreChanges = false;
} }
void wxGenericFileDialog::SetPath( const wxString& path ) void wxGenericFileDialog::SetPath( const wxString& path )
{ {
// not only set the full path but also update filename and dir // not only set the full path but also update filename and dir
m_path = path; m_path = path;
#ifdef __WXWINCE__
if (m_path.empty())
m_path = wxFILE_SEP_PATH;
#endif
if ( !path.empty() ) if ( !path.empty() )
{ {
wxString ext; wxString ext;
@@ -1432,6 +1555,9 @@ void wxGenericFileDialog::GetPaths( wxArrayString& paths ) const
wxString dir = m_list->GetDir(); wxString dir = m_list->GetDir();
#ifdef __UNIX__ #ifdef __UNIX__
if (dir != wxT("/")) if (dir != wxT("/"))
#endif
#ifdef __WXWINCE__
if (dir != wxT("/") && dir != wxT("\\"))
#endif #endif
dir += wxFILE_SEP_PATH; dir += wxFILE_SEP_PATH;