picker controls improvements: fixes to valid paths recognition and event generation under GTK (patch 1510064)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@39838 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2006-06-26 01:04:44 +00:00
parent 6be6127e66
commit 58772e4992
8 changed files with 146 additions and 57 deletions

View File

@ -32,11 +32,7 @@ It is only available if \texttt{wxUSE\_COLOURPICKERCTRL} is set to $1$ (the defa
\twocolwidtha{5cm}%
\begin{twocollist}\itemsep=0pt
\twocolitem{\windowstyle{wxCLRP\_DEFAULT}}{Default style.}
\twocolitem{\windowstyle{wxCLRP\_USE\_TEXTCTRL}}{Creates a text control to the left of the
picker button which is completely managed by the \helpref{wxColourPickerCtrl}{wxcolourpickerctrl}
and which can be used by the user to specify a colour (see \helpref{SetColour}{wxcolourpickerctrlsetcolour}).
The text control is automatically synchronized with button's value. Use functions defined in \helpref{wxPickerBase}{wxpickerbase} to modify the text control.}
\twocolitem{\windowstyle{wxCLRP\_DEFAULT}}{The default style: 0.}
\twocolitem{\windowstyle{wxCLRP\_USE\_TEXTCTRL}}{Creates a text control to the left of the
picker button which is completely managed by the \helpref{wxColourPickerCtrl}{wxcolourpickerctrl}
and which can be used by the user to specify a colour (see \helpref{SetColour}{wxcolourpickerctrlsetcolour}).

View File

@ -32,7 +32,8 @@ It is only available if \texttt{wxUSE\_DIRPICKERCTRL} is set to $1$ (the default
\twocolwidtha{5cm}%
\begin{twocollist}\itemsep=0pt
\twocolitem{\windowstyle{wxDIRP\_DEFAULT\_STYLE}}{Default style.}
\twocolitem{\windowstyle{wxDIRP\_DEFAULT\_STYLE}}{The default style: includes
wxDIRP\_DIR\_MUST\_EXIST and, under wxMSW only, wxDIRP\_USE\_TEXTCTRL.}
\twocolitem{\windowstyle{wxDIRP\_USE\_TEXTCTRL}}{Creates a text control to the left of the
picker button which is completely managed by the \helpref{wxDirPickerCtrl}{wxdirpickerctrl}
and which can be used by the user to specify a path (see \helpref{SetPath}{wxdirpickerctrlsetpath}).
@ -47,7 +48,10 @@ The text control is automatically synchronized with button's value. Use function
\twocolwidtha{7cm}%
\begin{twocollist}\itemsep=0pt
\twocolitem{{\bf EVT\_DIRPICKER\_CHANGED(id, func)}}{The user changed the directory selected in the control either using the button or using text control (see wxDIRP_USE_TEXTCTRL; note that in this case the event is fired only if the user's input is valid, e.g. an existing directory path).}
\twocolitem{{\bf EVT\_DIRPICKER\_CHANGED(id, func)}}{The user changed the
directory selected in the control either using the button or using text control
(see wxDIRP\_USE\_TEXTCTRL; note that in this case the event is fired only if
the user's input is valid, e.g. an existing directory path).}
\end{twocollist}
\wxheading{See also}

View File

@ -32,7 +32,9 @@ It is only available if \texttt{wxUSE\_FILEPICKERCTRL} is set to $1$ (the defaul
\twocolwidtha{5cm}%
\begin{twocollist}\itemsep=0pt
\twocolitem{\windowstyle{wxFLP\_DEFAULT\_STYLE}}{Default style.}
\twocolitem{\windowstyle{wxFLP\_DEFAULT\_STYLE}}{The default style: includes
wxFLP\_OPEN | wxFLP\_FILE\_MUST\_EXIST and, under wxMSW only,
wxFLP\_USE\_TEXTCTRL.}
\twocolitem{\windowstyle{wxFLP\_USE\_TEXTCTRL}}{Creates a text control to the left of the
picker button which is completely managed by the \helpref{wxFilePickerCtrl}{wxfilepickerctrl}
and which can be used by the user to specify a path (see \helpref{SetPath}{wxfilepickerctrlsetpath}).

View File

@ -32,7 +32,8 @@ It is only available if \texttt{wxUSE\_FONTPICKERCTRL} is set to $1$ (the defaul
\twocolwidtha{5cm}%
\begin{twocollist}\itemsep=0pt
\twocolitem{\windowstyle{wxFNTP\_DEFAULT}}{Default style.}
\twocolitem{\windowstyle{wxFNTP\_DEFAULT}}{The default style:
wxFNTP\_FONTDESC\_AS\_LABEL | wxFNTP\_USEFONT\_FOR\_LABEL.}
\twocolitem{\windowstyle{wxFNTP\_USE\_TEXTCTRL}}{Creates a text control to the left of the
picker button which is completely managed by the \helpref{wxFontPickerCtrl}{wxfontpickerctrl}
and which can be used by the user to specify a font (see \helpref{SetSelectedFont}{wxfontpickerctrlsetselectedfont}).

View File

@ -17,7 +17,6 @@
#if wxUSE_FILEPICKERCTRL || wxUSE_DIRPICKERCTRL
#include "wx/pickerbase.h"
#include "wx/filename.h"
class WXDLLIMPEXP_CORE wxDialog;
class WXDLLIMPEXP_CORE wxFileDirPickerEvent;
@ -96,7 +95,6 @@ class WXDLLIMPEXP_CORE wxFileDirPickerCtrlBase : public wxPickerBase
{
public:
wxFileDirPickerCtrlBase() : m_bIgnoreNextTextCtrlUpdate(false) {}
virtual ~wxFileDirPickerCtrlBase() {}
// NB: no default values since this function will never be used
// directly by the user and derived classes wouldn't use them
@ -139,6 +137,9 @@ public: // internal functions
// Returns the event type sent by this picker
virtual wxEventType GetEventType() const = 0;
// Returns the filtered value currently placed in the text control (if present).
virtual wxString GetTextCtrlValue() const = 0;
protected:
// true if the next UpdateTextCtrl() call is to ignore
@ -160,16 +161,15 @@ protected:
#ifdef __WXGTK__
// GTK apps usually don't have a textctrl next to the picker
#define wxFLP_DEFAULT_STYLE (wxFLP_OPEN)
#define wxFLP_DEFAULT_STYLE (wxFLP_OPEN|wxFLP_FILE_MUST_EXIST)
#else
#define wxFLP_DEFAULT_STYLE (wxFLP_USE_TEXTCTRL|wxFLP_OPEN)
#define wxFLP_DEFAULT_STYLE (wxFLP_USE_TEXTCTRL|wxFLP_OPEN|wxFLP_FILE_MUST_EXIST)
#endif
class WXDLLIMPEXP_CORE wxFilePickerCtrl : public wxFileDirPickerCtrlBase
{
public:
wxFilePickerCtrl() {}
virtual ~wxFilePickerCtrl() {}
wxFilePickerCtrl(wxWindow *parent,
wxWindowID id,
@ -217,10 +217,11 @@ public: // overrides
return true;
}
bool CheckPath(const wxString &path) const
{
return HasFlag(wxFLP_SAVE) || wxFileName::FileExists(path);
}
// return true if the given path is valid for this control
bool CheckPath(const wxString& path) const;
// return the text control value in canonical form
wxString GetTextCtrlValue() const;
bool IsCwdToUpdate() const
{ return HasFlag(wxFLP_CHANGE_DIR); }
@ -255,35 +256,43 @@ private:
#ifdef __WXGTK__
// GTK apps usually don't have a textctrl next to the picker
#define wxDIRP_DEFAULT_STYLE 0
#define wxDIRP_DEFAULT_STYLE (wxDIRP_DIR_MUST_EXIST)
#else
#define wxDIRP_DEFAULT_STYLE (wxDIRP_USE_TEXTCTRL)
#define wxDIRP_DEFAULT_STYLE (wxDIRP_USE_TEXTCTRL|wxDIRP_DIR_MUST_EXIST)
#endif
class WXDLLIMPEXP_CORE wxDirPickerCtrl : public wxFileDirPickerCtrlBase
{
public:
wxDirPickerCtrl() {}
virtual ~wxDirPickerCtrl() {}
wxDirPickerCtrl(wxWindow *parent, wxWindowID id,
const wxString& path = wxEmptyString,
const wxString& message = wxDirSelectorPromptStr,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize, long style = wxDIRP_DEFAULT_STYLE,
const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxDirPickerCtrlNameStr)
{ Create(parent, id, path, message, pos, size, style, validator, name); }
const wxString& path = wxEmptyString,
const wxString& message = wxDirSelectorPromptStr,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxDIRP_DEFAULT_STYLE,
const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxDirPickerCtrlNameStr)
{
Create(parent, id, path, message, pos, size, style, validator, name);
}
bool Create(wxWindow *parent, wxWindowID id,
const wxString& path = wxEmptyString,
const wxString& message = wxDirSelectorPromptStr,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize, long style = wxDIRP_DEFAULT_STYLE,
const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxDirPickerCtrlNameStr)
{ return wxFileDirPickerCtrlBase::CreateBase(parent, id, path, message, wxEmptyString,
pos, size, style, validator, name); }
const wxString& path = wxEmptyString,
const wxString& message = wxDirSelectorPromptStr,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxDIRP_DEFAULT_STYLE,
const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxDirPickerCtrlNameStr)
{
return wxFileDirPickerCtrlBase::CreateBase
(
parent, id, path, message, wxEmptyString,
pos, size, style, validator, name
);
}
public: // overrides
@ -297,8 +306,9 @@ public: // overrides
return true;
}
bool CheckPath(const wxString &path) const
{ if (HasFlag(wxDIRP_DIR_MUST_EXIST)) return wxFileName::DirExists(path); else return true; }
bool CheckPath(const wxString &path) const;
wxString GetTextCtrlValue() const;
bool IsCwdToUpdate() const
{ return HasFlag(wxDIRP_CHANGE_DIR); }

View File

@ -39,12 +39,6 @@
{ \
m_dialog->Destroy(); \
return wxButton::Destroy(); \
} \
\
virtual void SetPath(const wxString &str) \
{ \
m_path=str; \
UpdateDialogPath(m_dialog); \
}
@ -105,6 +99,8 @@ public: // some overrides
~(wxFD_SAVE | wxFD_OVERWRITE_PROMPT)) | wxFD_OPEN;
}
virtual void SetPath(const wxString &str);
// see macro defined above
FILEDIRBTN_OVERRIDES
@ -123,7 +119,7 @@ private:
class WXDLLIMPEXP_CORE wxDirButton : public wxGenericDirButton
{
public:
wxDirButton() { m_dialog = NULL;}
wxDirButton() { Init(); }
wxDirButton(wxWindow *parent,
wxWindowID id,
const wxString& label = wxFilePickerWidgetLabel,
@ -135,7 +131,8 @@ public:
const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxFilePickerWidgetNameStr)
{
m_dialog = NULL;
Init();
Create(parent, id, label, path, message, wxEmptyString,
pos, size, style, validator, name);
}
@ -157,9 +154,6 @@ public: // overrides
const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxFilePickerWidgetNameStr);
// used by the GTK callback only
void UpdatePath(char *gtkpath)
{ m_path = wxString::FromAscii(gtkpath); }
// GtkFileChooserButton does not support GTK_FILE_CHOOSER_CREATE_FOLDER
// thus we must ensure that the wxDD_DIR_MUST_EXIST style was given
@ -168,12 +162,28 @@ public: // overrides
return (wxGenericDirButton::GetDialogStyle() | wxDD_DIR_MUST_EXIST);
}
virtual void SetPath(const wxString &str);
// see macro defined above
FILEDIRBTN_OVERRIDES
protected:
// common part of all ctors
void Init()
{
m_dialog = NULL;
m_bIgnoreNextChange = false;
}
wxDialog *m_dialog;
public: // used by the GTK callback only
bool m_bIgnoreNextChange;
void UpdatePath(const char *gtkpath)
{ m_path = wxString::FromAscii(gtkpath); }
private:
DECLARE_DYNAMIC_CLASS(wxDirButton)
};

View File

@ -27,6 +27,7 @@
#if wxUSE_FILEPICKERCTRL || wxUSE_DIRPICKERCTRL
#include "wx/filepicker.h"
#include "wx/filename.h"
#ifndef WX_PRECOMP
#include "wx/textctrl.h"
@ -106,9 +107,7 @@ void wxFileDirPickerCtrlBase::UpdatePickerFromTextCtrl()
// remove the eventually present path-separator from the end of the textctrl
// string otherwise we would generate a wxFileDirPickerEvent when changing
// from e.g. /home/user to /home/user/ and we want to avoid it !
wxString newpath(m_text->GetValue());
if (!newpath.empty() && wxFileName::IsPathSeparator(newpath.Last()))
newpath.RemoveLast();
wxString newpath(GetTextCtrlValue());
if (!CheckPath(newpath))
return; // invalid user input
@ -120,7 +119,7 @@ void wxFileDirPickerCtrlBase::UpdatePickerFromTextCtrl()
// NOTE: the path separator is required because if newpath is "C:"
// then no change would happen
if (IsCwdToUpdate())
wxSetWorkingDirectory(newpath + wxFileName::GetPathSeparator());
wxSetWorkingDirectory(newpath);
// fire an event
wxFileDirPickerEvent event(GetEventType(), this, GetId(), newpath);
@ -158,9 +157,48 @@ void wxFileDirPickerCtrlBase::OnFileDirChange(wxFileDirPickerEvent &ev)
#endif // wxUSE_FILEPICKERCTRL || wxUSE_DIRPICKERCTRL
// ----------------------------------------------------------------------------
// wxFileDirPickerCtrl
// ----------------------------------------------------------------------------
#if wxUSE_FILEPICKERCTRL
IMPLEMENT_DYNAMIC_CLASS(wxFilePickerCtrl, wxPickerBase)
#endif
bool wxFilePickerCtrl::CheckPath(const wxString& path) const
{
// if wxFLP_SAVE was given or wxFLP_FILE_MUST_EXIST has NOT been given we
// must accept any path
return HasFlag(wxFLP_SAVE) ||
!HasFlag(wxFLP_FILE_MUST_EXIST) ||
wxFileName::FileExists(path);
}
wxString wxFilePickerCtrl::GetTextCtrlValue() const
{
// filter it through wxFileName to remove any spurious path separator
return wxFileName(m_text->GetValue()).GetFullPath();
}
#endif // wxUSE_FILEPICKERCTRL
// ----------------------------------------------------------------------------
// wxDirPickerCtrl
// ----------------------------------------------------------------------------
#if wxUSE_DIRPICKERCTRL
IMPLEMENT_DYNAMIC_CLASS(wxDirPickerCtrl, wxPickerBase)
#endif
bool wxDirPickerCtrl::CheckPath(const wxString& path) const
{
// if wxDIRP_DIR_MUST_EXIST has NOT been given we must accept any path
return !HasFlag(wxDIRP_DIR_MUST_EXIST) || wxFileName::DirExists(path);
}
wxString wxDirPickerCtrl::GetTextCtrlValue() const
{
// filter it through wxFileName to remove any spurious path separator
return wxFileName::DirName(m_text->GetValue()).GetPath();
}
#endif // wxUSE_DIRPICKERCTRL

View File

@ -20,12 +20,10 @@
#if wxUSE_FILEPICKERCTRL && defined(__WXGTK26__)
#include "wx/filepicker.h"
#include "wx/tooltip.h"
#include <gtk/gtk.h>
#include <unistd.h> // chdir
// ============================================================================
@ -129,6 +127,13 @@ void wxFileButton::OnDialogOK(wxCommandEvent& ev)
}
}
void wxFileButton::SetPath(const wxString &str)
{
m_path = str;
UpdateDialogPath(m_dialog);
}
#endif // wxUSE_FILEPICKERCTRL && defined(__WXGTK26__)
@ -136,6 +141,8 @@ void wxFileButton::OnDialogOK(wxCommandEvent& ev)
#if wxUSE_DIRPICKERCTRL && defined(__WXGTK26__)
#include <unistd.h> // chdir
//-----------------------------------------------------------------------------
// "current-folder-changed"
//-----------------------------------------------------------------------------
@ -145,6 +152,12 @@ static void gtk_dirbutton_currentfolderchanged_callback(GtkFileChooserButton *wi
wxDirButton *p)
{
// update the m_path member of the wxDirButtonGTK
// unless the path was changed by wxDirButton::SetPath()
if (p->m_bIgnoreNextChange)
{
p->m_bIgnoreNextChange=false;
return;
}
wxASSERT(p);
// NB: it's important to use gtk_file_chooser_get_filename instead of
@ -202,6 +215,7 @@ bool wxDirButton::Create( wxWindow *parent, wxWindowID id,
m_wildcard = wildcard;
if ((m_dialog = CreateDialog()) == NULL)
return false;
SetPath(path);
// little trick used to avoid problems when there are other GTK windows 'grabbed':
// GtkFileChooserDialog won't be responsive to user events if there is another
@ -246,4 +260,18 @@ wxDirButton::~wxDirButton()
m_dialog->m_widget = NULL;
}
void wxDirButton::SetPath(const wxString &str)
{
m_path = str;
// wxDirButton uses the "current-folder-changed" signal which is triggered also
// when we set the path on the dialog associated with this button; thus we need
// to set the following flag to avoid sending a wxFileDirPickerEvent from this
// function (which would be inconsistent with wxFileButton's behaviour and in
// general with all wxWidgets control-manipulation functions which do not send events).
m_bIgnoreNextChange = true;
UpdateDialogPath(m_dialog);
}
#endif // wxUSE_DIRPICKERCTRL && defined(__WXGTK26__)