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:
parent
6be6127e66
commit
58772e4992
@ -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}).
|
||||
|
@ -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}
|
||||
|
@ -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}).
|
||||
|
@ -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}).
|
||||
|
@ -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); }
|
||||
|
@ -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)
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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__)
|
||||
|
Loading…
Reference in New Issue
Block a user