Add wxFileDialog::GetCurrentlySelectedFilename().

Also send wxEVT_UPDATE_UI events for the extra controls in wxFileDialog.

The combination of these changes allows extra controls to update their state
depending on the current selection in the dialog. Show a simple example of
doing it in the dialogs sample.

Closes #15235.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74071 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2013-05-31 23:21:27 +00:00
parent 438959cca8
commit 926df8a162
8 changed files with 123 additions and 9 deletions

View File

@ -669,6 +669,7 @@ All (GUI):
- Pass menu events to the handler in the associated wxMenuBar.
- Add wxWindow::BeginRepositioningChildren() and EndRepositioningChildren().
- Fix wxStyledTextCtrl::SetInsertionPointEnd() (troelsk).
- Add wxFileDialog::GetCurrentlySelectedFilename() (Carl Godkin).
wxGTK:

View File

@ -122,6 +122,9 @@ public:
virtual wxString GetWildcard() const { return m_wildCard; }
virtual int GetFilterIndex() const { return m_filterIndex; }
virtual wxString GetCurrentlySelectedFilename() const
{ return m_currentlySelectedFilename; }
// this function is called with wxFileDialog as parameter and should
// create the window containing the extra controls we want to show in it
typedef wxWindow *(*ExtraControlCreatorFunction)(wxWindow*);
@ -155,6 +158,13 @@ protected:
wxString m_fileName;
wxString m_wildCard;
int m_filterIndex;
// Currently selected, but not yet necessarily accepted by the user, file.
// This should be updated whenever the selection in the control changes by
// the platform-specific code to provide a useful implementation of
// GetCurrentlySelectedFilename().
wxString m_currentlySelectedFilename;
wxWindow* m_extraControl;
// returns true if control is created (if it already exists returns false)

View File

@ -58,6 +58,9 @@ public:
virtual bool SupportsExtraControl() const { return true; }
// Implementation only.
void GTKSelectionChanged(const wxString& filename);
protected:
// override this from wxTLW since the native

View File

@ -44,6 +44,9 @@ public:
// called from the hook procedure on CDN_INITDONE reception
virtual void MSWOnInitDone(WXHWND hDlg);
// called from the hook procedure on CDN_SELCHANGE.
void MSWOnSelChange(WXHWND hDlg);
protected:
#if !(defined(__SMARTPHONE__) && defined(__WXWINCE__))

View File

@ -183,6 +183,26 @@ public:
*/
virtual ~wxFileDialog();
/**
Returns the path of the file currently selected in dialog.
Notice that this file is not necessarily going to be accepted by the
user, so calling this function mostly makes sense from an update UI
event handler of a custom file dialog extra control to update its state
depending on the currently selected file.
Currently this function is fully implemented under GTK and MSW and
always returns an empty string elsewhere.
@since 2.9.5
@return The path of the currently selected file or an empty string if
nothing is selected.
@see SetExtraControlCreator()
*/
virtual wxString GetCurrentlySelectedFilename() const;
/**
Returns the default directory.
*/

View File

@ -25,6 +25,7 @@
#include "wx/apptrait.h"
#include "wx/datetime.h"
#include "wx/filename.h"
#include "wx/image.h"
#include "wx/bookctrl.h"
#include "wx/artprov.h"
@ -1332,14 +1333,34 @@ class MyExtraPanel : public wxPanel
{
public:
MyExtraPanel(wxWindow *parent);
void OnCheckBox(wxCommandEvent& event) { m_btn->Enable(event.IsChecked()); }
wxString GetInfo() const
{
return wxString::Format("checkbox value = %d", (int) m_cb->GetValue());
}
private:
void OnCheckBox(wxCommandEvent& event) { m_btn->Enable(event.IsChecked()); }
void OnUpdateLabelUI(wxUpdateUIEvent& event)
{
wxFileDialog* const dialog = wxStaticCast(GetParent(), wxFileDialog);
const wxString fn = dialog->GetCurrentlySelectedFilename();
wxString msg;
if ( fn.empty() )
msg = "Nothing";
else if ( wxFileName::FileExists(fn) )
msg = "File";
else if ( wxFileName::DirExists(fn) )
msg = "Directory";
else
msg = "Something else";
event.SetText(msg + " selected");
}
wxButton *m_btn;
wxCheckBox *m_cb;
wxStaticText *m_label;
};
MyExtraPanel::MyExtraPanel(wxWindow *parent)
@ -1348,12 +1369,20 @@ MyExtraPanel::MyExtraPanel(wxWindow *parent)
m_btn = new wxButton(this, -1, wxT("Custom Button"));
m_btn->Enable(false);
m_cb = new wxCheckBox(this, -1, wxT("Enable Custom Button"));
m_cb->Connect(wxID_ANY, wxEVT_CHECKBOX,
m_cb->Connect(wxEVT_CHECKBOX,
wxCommandEventHandler(MyExtraPanel::OnCheckBox), NULL, this);
m_label = new wxStaticText(this, wxID_ANY, "Nothing selected");
m_label->Connect(wxEVT_UPDATE_UI,
wxUpdateUIEventHandler(MyExtraPanel::OnUpdateLabelUI),
NULL, this);
wxBoxSizer *sizerTop = new wxBoxSizer(wxHORIZONTAL);
sizerTop->Add(m_cb, wxSizerFlags().Centre().Border());
sizerTop->AddStretchSpacer();
sizerTop->Add(m_btn, wxSizerFlags().Right().Border());
sizerTop->Add(m_btn, wxSizerFlags().Centre().Border());
sizerTop->AddStretchSpacer();
sizerTop->Add(m_label, wxSizerFlags().Centre().Border());
SetSizerAndFit(sizerTop);
}

View File

@ -116,6 +116,15 @@ static void gtk_filedialog_response_callback(GtkWidget *w,
gtk_filedialog_cancel_callback(w, dialog);
}
static void gtk_filedialog_selchanged_callback(GtkFileChooser *chooser,
wxFileDialog *dialog)
{
wxGtkString filename(gtk_file_chooser_get_preview_filename(chooser));
dialog->GTKSelectionChanged(wxString::FromUTF8(filename));
}
static void gtk_filedialog_update_preview_callback(GtkFileChooser *chooser,
gpointer user_data)
{
@ -249,6 +258,8 @@ bool wxFileDialog::Create(wxWindow *parent, const wxString& message,
g_signal_connect (m_widget, "response",
G_CALLBACK (gtk_filedialog_response_callback), this);
g_signal_connect (m_widget, "selection-changed",
G_CALLBACK (gtk_filedialog_selchanged_callback), this);
// deal with extensions/filters
SetWildcard(wildCard);
@ -463,4 +474,12 @@ int wxFileDialog::GetFilterIndex() const
return m_fc.GetFilterIndex();
}
void wxFileDialog::GTKSelectionChanged(const wxString& filename)
{
m_currentlySelectedFilename = filename;
if (m_extraControl)
m_extraControl->UpdateWindowUI(wxUPDATE_UI_RECURSE);
}
#endif // wxUSE_FILEDLG

View File

@ -173,13 +173,23 @@ wxFileDialogHookFunction(HWND hDlg,
case WM_NOTIFY:
{
OFNOTIFY *pNotifyCode = reinterpret_cast<OFNOTIFY *>(lParam);
if ( pNotifyCode->hdr.code == CDN_INITDONE )
OFNOTIFY* const
pNotifyCode = reinterpret_cast<OFNOTIFY *>(lParam);
wxFileDialog* const
dialog = reinterpret_cast<wxFileDialog *>(
pNotifyCode->lpOFN->lCustData
);
switch ( pNotifyCode->hdr.code )
{
reinterpret_cast<wxFileDialog *>(
pNotifyCode->lpOFN->lCustData)
->MSWOnInitDone((WXHWND)hDlg);
}
case CDN_INITDONE:
dialog->MSWOnInitDone((WXHWND)hDlg);
break;
case CDN_SELCHANGE:
dialog->MSWOnSelChange((WXHWND)hDlg);
break;
}
}
break;
@ -323,10 +333,29 @@ void wxFileDialog::MSWOnInitDone(WXHWND hDlg)
SetPosition(gs_rectDialog.GetPosition());
}
// Call selection change handler so that update handler will be
// called once with no selection.
MSWOnSelChange(hDlg);
// we shouldn't destroy this HWND
SetHWND(NULL);
}
void wxFileDialog::MSWOnSelChange(WXHWND hDlg)
{
TCHAR buf[MAX_PATH];
LRESULT len = SendMessage(::GetParent(hDlg), CDM_GETFILEPATH,
MAX_PATH, reinterpret_cast<LPARAM>(buf));
if ( len > 0 )
m_currentlySelectedFilename = buf;
else
m_currentlySelectedFilename.clear();
if ( m_extraControl )
m_extraControl->UpdateWindowUI(wxUPDATE_UI_RECURSE);
}
// helper used below in ShowCommFileDialog(): style is used to determine
// whether to show the "Save file" dialog (if it contains wxFD_SAVE bit) or
// "Open file" one; returns true on success or false on failure in which case