417 lines
12 KiB
C++
417 lines
12 KiB
C++
//////////////////////////////////////////////////////////////////////////////
|
|
// Name: src/generic/filedlgg.cpp
|
|
// Purpose: wxGenericFileDialog
|
|
// Author: Robert Roebling
|
|
// Modified by:
|
|
// Created: 12/12/98
|
|
// Copyright: (c) Robert Roebling
|
|
// Licence: wxWindows licence
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// For compilers that support precompilation, includes "wx.h".
|
|
#include "wx/wxprec.h"
|
|
|
|
#ifdef __BORLANDC__
|
|
#pragma hdrstop
|
|
#endif
|
|
|
|
#if wxUSE_FILEDLG
|
|
|
|
// NOTE : it probably also supports MAC, untested
|
|
#if !defined(__UNIX__) && !defined(__WIN32__)
|
|
#error wxGenericFileDialog currently only supports Unix and MSW
|
|
#endif
|
|
|
|
#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/artprov.h"
|
|
#include "wx/filefn.h"
|
|
#include "wx/filectrl.h"
|
|
#include "wx/generic/filedlgg.h"
|
|
#include "wx/debug.h"
|
|
#include "wx/modalhook.h"
|
|
|
|
#if wxUSE_TOOLTIPS
|
|
#include "wx/tooltip.h"
|
|
#endif
|
|
#if wxUSE_CONFIG
|
|
#include "wx/config.h"
|
|
#endif
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
|
|
#ifdef __UNIX__
|
|
#include <dirent.h>
|
|
#include <pwd.h>
|
|
#ifndef __VMS
|
|
# include <grp.h>
|
|
#endif
|
|
#endif
|
|
|
|
#include <time.h>
|
|
|
|
#if defined(__UNIX__)
|
|
#include <unistd.h>
|
|
#endif
|
|
|
|
#if defined(__WINDOWS__)
|
|
#define IsTopMostDir(dir) (dir.empty())
|
|
#else
|
|
#define IsTopMostDir(dir) (dir == wxT("/"))
|
|
#endif
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// wxGenericFileDialog
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#define ID_LIST_MODE (wxID_FILEDLGG )
|
|
#define ID_REPORT_MODE (wxID_FILEDLGG + 1)
|
|
#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)
|
|
|
|
wxIMPLEMENT_DYNAMIC_CLASS(wxGenericFileDialog, wxFileDialogBase);
|
|
|
|
wxBEGIN_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_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(__WINDOWS__)
|
|
EVT_UPDATE_UI(ID_NEW_DIR, wxGenericFileDialog::OnUpdateButtonsUI)
|
|
#endif // defined(__WINDOWS__)
|
|
wxEND_EVENT_TABLE()
|
|
|
|
long wxGenericFileDialog::ms_lastViewStyle = wxLC_LIST;
|
|
bool wxGenericFileDialog::ms_lastShowHidden = false;
|
|
|
|
void wxGenericFileDialog::Init()
|
|
{
|
|
m_bypassGenericImpl = false;
|
|
|
|
m_filectrl = NULL;
|
|
m_upDirButton = NULL;
|
|
m_newDirButton = NULL;
|
|
}
|
|
|
|
wxGenericFileDialog::wxGenericFileDialog(wxWindow *parent,
|
|
const wxString& message,
|
|
const wxString& defaultDir,
|
|
const wxString& defaultFile,
|
|
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, sz, name, bypassGenericImpl );
|
|
}
|
|
|
|
bool wxGenericFileDialog::Create( wxWindow *parent,
|
|
const wxString& message,
|
|
const wxString& defaultDir,
|
|
const wxString& defaultFile,
|
|
const wxString& wildCard,
|
|
long style,
|
|
const wxPoint& pos,
|
|
const wxSize& sz,
|
|
const wxString& name,
|
|
bool bypassGenericImpl )
|
|
{
|
|
m_bypassGenericImpl = bypassGenericImpl;
|
|
|
|
parent = GetParentForModalDialog(parent, style);
|
|
|
|
if (!wxFileDialogBase::Create(parent, message, defaultDir, defaultFile,
|
|
wildCard, style, pos, sz, name))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (m_bypassGenericImpl)
|
|
return true;
|
|
|
|
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"),
|
|
&ms_lastViewStyle);
|
|
wxConfig::Get()->Read(wxT("/wxWindows/wxFileDialog/ShowHidden"),
|
|
&ms_lastShowHidden);
|
|
}
|
|
#endif
|
|
|
|
if ((m_dir.empty()) || (m_dir == wxT(".")))
|
|
{
|
|
m_dir = wxGetCwd();
|
|
if (m_dir.empty())
|
|
m_dir = wxFILE_SEP_PATH;
|
|
}
|
|
|
|
const size_t len = m_dir.length();
|
|
if ((len > 1) && (wxEndsWithPathSeparator(m_dir)))
|
|
m_dir.Remove( len-1, 1 );
|
|
|
|
m_filterExtension = wxEmptyString;
|
|
|
|
// layout
|
|
|
|
const bool is_pda = (wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_PDA);
|
|
|
|
wxBoxSizer *mainsizer = new wxBoxSizer( wxVERTICAL );
|
|
|
|
wxBoxSizer *buttonsizer = new wxBoxSizer( wxHORIZONTAL );
|
|
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 = AddBitmapButton( ID_UP_DIR, wxART_GO_DIR_UP,
|
|
_("Go to parent directory"), buttonsizer );
|
|
|
|
AddBitmapButton( ID_HOME_DIR, wxART_GO_HOME,
|
|
_("Go to home directory"), buttonsizer );
|
|
buttonsizer->Add( 20, 20 );
|
|
|
|
m_newDirButton = AddBitmapButton( ID_NEW_DIR, wxART_NEW_DIR,
|
|
_("Create new directory"), buttonsizer );
|
|
|
|
if (is_pda)
|
|
mainsizer->Add( buttonsizer, wxSizerFlags().Expand() );
|
|
else
|
|
mainsizer->Add( buttonsizer, wxSizerFlags().Expand()
|
|
.Border( wxLEFT | wxRIGHT | wxTOP ) );
|
|
|
|
long style2 = 0;
|
|
if ( HasFdFlag(wxFD_MULTIPLE) )
|
|
style2 |= wxFC_MULTIPLE;
|
|
|
|
m_filectrl = new wxGenericFileCtrl( this, ID_FILE_CTRL,
|
|
m_dir, defaultFile,
|
|
wildCard,
|
|
style2,
|
|
wxDefaultPosition, wxSize(540,200)
|
|
);
|
|
|
|
m_filectrl->ShowHidden( ms_lastShowHidden );
|
|
|
|
if (ms_lastViewStyle == wxLC_LIST)
|
|
{
|
|
m_filectrl->ChangeToListMode();
|
|
}
|
|
else if (ms_lastViewStyle == wxLC_REPORT)
|
|
{
|
|
m_filectrl->ChangeToReportMode();
|
|
}
|
|
|
|
mainsizer->Add(m_filectrl, wxSizerFlags(1).Expand().HorzBorder());
|
|
|
|
wxSizer *bsizer = CreateButtonSizer(wxOK | wxCANCEL);
|
|
if ( bsizer )
|
|
{
|
|
if (is_pda)
|
|
mainsizer->Add(bsizer, wxSizerFlags().Expand().Border());
|
|
else
|
|
mainsizer->Add(bsizer, wxSizerFlags().Expand().DoubleBorder());
|
|
}
|
|
|
|
SetSizer( mainsizer );
|
|
|
|
if (!is_pda)
|
|
{
|
|
mainsizer->SetSizeHints( this );
|
|
|
|
Centre( wxBOTH );
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
wxGenericFileDialog::~wxGenericFileDialog()
|
|
{
|
|
if (!m_bypassGenericImpl)
|
|
{
|
|
#if wxUSE_CONFIG
|
|
if (wxConfig::Get(false))
|
|
{
|
|
wxConfig::Get()->Write(wxT("/wxWindows/wxFileDialog/ViewStyle"),
|
|
ms_lastViewStyle);
|
|
wxConfig::Get()->Write(wxT("/wxWindows/wxFileDialog/ShowHidden"),
|
|
ms_lastShowHidden);
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
wxBitmapButton* wxGenericFileDialog::AddBitmapButton( wxWindowID winId,
|
|
const wxArtID& artId,
|
|
const wxString& tip,
|
|
wxSizer *sizer)
|
|
{
|
|
wxBitmapButton *but = new wxBitmapButton(this, winId,
|
|
wxArtProvider::GetBitmap(artId, wxART_BUTTON));
|
|
but->SetToolTip(tip);
|
|
sizer->Add(but, wxSizerFlags().Border());
|
|
return but;
|
|
}
|
|
|
|
int wxGenericFileDialog::ShowModal()
|
|
{
|
|
WX_HOOK_MODAL_DIALOG();
|
|
|
|
if (CreateExtraControl())
|
|
{
|
|
wxSizer *sizer = GetSizer();
|
|
sizer->Insert(2 /* after m_filectrl */, m_extraControl,
|
|
wxSizerFlags().Expand().HorzBorder());
|
|
sizer->Fit(this);
|
|
}
|
|
|
|
m_filectrl->SetDirectory(m_dir);
|
|
|
|
return wxDialog::ShowModal();
|
|
}
|
|
|
|
bool wxGenericFileDialog::Show( bool show )
|
|
{
|
|
// Called by ShowModal, so don't repeate the update
|
|
#ifndef __WIN32__
|
|
if (show)
|
|
{
|
|
m_filectrl->SetDirectory(m_dir);
|
|
}
|
|
#endif
|
|
|
|
return wxDialog::Show( show );
|
|
}
|
|
|
|
void wxGenericFileDialog::OnOk( wxCommandEvent &WXUNUSED(event) )
|
|
{
|
|
wxArrayString selectedFiles;
|
|
m_filectrl->GetPaths(selectedFiles);
|
|
|
|
if (selectedFiles.Count() == 0)
|
|
return;
|
|
|
|
const wxString& path = selectedFiles[0];
|
|
|
|
if (selectedFiles.Count() == 1)
|
|
{
|
|
SetPath(path);
|
|
}
|
|
|
|
// check that the file [doesn't] exist if necessary
|
|
if ( HasFdFlag(wxFD_SAVE) && HasFdFlag(wxFD_OVERWRITE_PROMPT) &&
|
|
wxFileExists(path) )
|
|
{
|
|
if ( wxMessageBox
|
|
(
|
|
wxString::Format
|
|
(
|
|
_("File '%s' already exists, do you really want to overwrite it?"),
|
|
path
|
|
),
|
|
_("Confirm"),
|
|
wxYES_NO
|
|
) != wxYES)
|
|
return;
|
|
}
|
|
else if ( HasFdFlag(wxFD_OPEN) && HasFdFlag(wxFD_FILE_MUST_EXIST) &&
|
|
!wxFileExists(path) )
|
|
{
|
|
wxMessageBox(_("Please choose an existing file."), _("Error"),
|
|
wxOK | wxICON_ERROR );
|
|
return;
|
|
}
|
|
|
|
EndModal(wxID_OK);
|
|
}
|
|
|
|
void wxGenericFileDialog::OnList( wxCommandEvent &WXUNUSED(event) )
|
|
{
|
|
m_filectrl->ChangeToListMode();
|
|
ms_lastViewStyle = wxLC_LIST;
|
|
m_filectrl->GetFileList()->SetFocus();
|
|
}
|
|
|
|
void wxGenericFileDialog::OnReport( wxCommandEvent &WXUNUSED(event) )
|
|
{
|
|
m_filectrl->ChangeToReportMode();
|
|
ms_lastViewStyle = wxLC_REPORT;
|
|
m_filectrl->GetFileList()->SetFocus();
|
|
}
|
|
|
|
void wxGenericFileDialog::OnUp( wxCommandEvent &WXUNUSED(event) )
|
|
{
|
|
m_filectrl->GoToParentDir();
|
|
m_filectrl->GetFileList()->SetFocus();
|
|
}
|
|
|
|
void wxGenericFileDialog::OnHome( wxCommandEvent &WXUNUSED(event) )
|
|
{
|
|
m_filectrl->GoToHomeDir();
|
|
m_filectrl->SetFocus();
|
|
}
|
|
|
|
void wxGenericFileDialog::OnNew( wxCommandEvent &WXUNUSED(event) )
|
|
{
|
|
m_filectrl->GetFileList()->MakeDir();
|
|
}
|
|
|
|
void wxGenericFileDialog::OnFileActivated( wxFileCtrlEvent &WXUNUSED(event) )
|
|
{
|
|
wxCommandEvent dummy;
|
|
OnOk( dummy );
|
|
}
|
|
|
|
void wxGenericFileDialog::OnUpdateButtonsUI(wxUpdateUIEvent& event)
|
|
{
|
|
// 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()) );
|
|
}
|
|
|
|
#ifdef wxHAS_GENERIC_FILEDIALOG
|
|
|
|
wxIMPLEMENT_DYNAMIC_CLASS(wxFileDialog, wxGenericFileDialog);
|
|
|
|
#endif // wxHAS_GENERIC_FILEDIALOG
|
|
|
|
#endif // wxUSE_FILEDLG
|