From 6305f044a1d4cce68128529fa939a2cc1d35df85 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 29 May 2010 10:35:47 +0000 Subject: [PATCH] Add "filter changed" event to wxFileCtrl. Generate an event when the selection in the filter combobox of wxFileCtrl changes. Closes #12099. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@64429 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 1 + include/wx/filectrl.h | 10 ++++++++++ include/wx/gtk/filectrl.h | 18 +++++++++++++++++- interface/wx/filectrl.h | 22 ++++++++++++++++++++++ samples/widgets/filectrl.cpp | 6 ++++++ src/common/filectrlcmn.cpp | 10 ++++++++++ src/generic/filectrlg.cpp | 2 ++ src/gtk/filectrl.cpp | 28 ++++++++++++++++++++++++++++ 8 files changed, 96 insertions(+), 1 deletion(-) diff --git a/docs/changes.txt b/docs/changes.txt index 3bec98b420..357c9534d8 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -518,6 +518,7 @@ All (GUI): - Added wxToolBar::GetToolByPos(). - Added wxProgressDialog::Was{Cancelled,Skipped}() (Julien Weinzorn). - Added wxTreeCtrl::{Clear,Set}FocusedItem() (Nikolay Tiushkov). +- Added "filter changed" event to wxFileCtrl (Bill Jones). GTK: diff --git a/include/wx/filectrl.h b/include/wx/filectrl.h index 38b8b9bf17..d741ae2ab1 100644 --- a/include/wx/filectrl.h +++ b/include/wx/filectrl.h @@ -63,6 +63,7 @@ public: virtual void ShowHidden(bool show) = 0; }; +void GenerateFilterChangedEvent( wxFileCtrlBase *fileCtrl, wxWindow *wnd ); void GenerateFolderChangedEvent( wxFileCtrlBase *fileCtrl, wxWindow *wnd ); void GenerateSelectionChangedEvent( wxFileCtrlBase *fileCtrl, wxWindow *wnd ); void GenerateFileActivatedEvent( wxFileCtrlBase *fileCtrl, wxWindow *wnd, const wxString filename = wxEmptyString ); @@ -76,6 +77,8 @@ void GenerateFileActivatedEvent( wxFileCtrlBase *fileCtrl, wxWindow *wnd, const #endif // Some documentation +// On wxEVT_FILECTRL_FILTERCHANGED, only the value returned by GetFilterIndex is +// valid and it represents the (new) current filter index for the wxFileCtrl. // On wxEVT_FILECTRL_FOLDERCHANGED, only the value returned by GetDirectory is // valid and it represents the (new) current directory for the wxFileCtrl. // On wxEVT_FILECTRL_FILEACTIVATED, GetDirectory returns the current directory @@ -100,13 +103,16 @@ public: void SetFiles( const wxArrayString &files ) { m_files = files; } void SetDirectory( const wxString &directory ) { m_directory = directory; } + void SetFilterIndex( int filterIndex ) { m_filterIndex = filterIndex; } wxArrayString GetFiles() const { return m_files; } wxString GetDirectory() const { return m_directory; } + int GetFilterIndex() const { return m_filterIndex; } wxString GetFile() const; protected: + int m_filterIndex; wxString m_directory; wxArrayString m_files; @@ -118,6 +124,7 @@ typedef void ( wxEvtHandler::*wxFileCtrlEventFunction )( wxFileCtrlEvent& ); wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_FILECTRL_SELECTIONCHANGED, wxFileCtrlEvent ); wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_FILECTRL_FILEACTIVATED, wxFileCtrlEvent ); wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_FILECTRL_FOLDERCHANGED, wxFileCtrlEvent ); +wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_FILECTRL_FILTERCHANGED, wxFileCtrlEvent ); #define wxFileCtrlEventHandler(func) \ wxEVENT_HANDLER_CAST( wxFileCtrlEventFunction, func ) @@ -131,6 +138,9 @@ wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_FILECTRL_FOLDERCHANGED, wxFile #define EVT_FILECTRL_FOLDERCHANGED(id, fn) \ wx__DECLARE_EVT1(wxEVT_FILECTRL_FOLDERCHANGED, id, wxFileCtrlEventHandler(fn)) +#define EVT_FILECTRL_FILTERCHANGED(id, fn) \ + wx__DECLARE_EVT1(wxEVT_FILECTRL_FILTERCHANGED, id, wxFileCtrlEventHandler(fn)) + #endif // wxUSE_FILECTRL #endif // _WX_FILECTRL_H_BASE_ diff --git a/include/wx/gtk/filectrl.h b/include/wx/gtk/filectrl.h index e84fff83f4..d5c3848e76 100644 --- a/include/wx/gtk/filectrl.h +++ b/include/wx/gtk/filectrl.h @@ -32,7 +32,7 @@ typedef struct _GtkFileChooser GtkFileChooser; class WXDLLIMPEXP_CORE wxGtkFileChooser { public: - wxGtkFileChooser() {} + wxGtkFileChooser() { m_ignoreNextFilterEvent = false; } void SetWidget(GtkFileChooser *w); @@ -48,6 +48,10 @@ public: void SetWildcard( const wxString& wildCard ); void SetFilterIndex( int filterIndex ); + bool HasFilterChoice() const; + + bool ShouldIgnoreNextFilterEvent() const { return m_ignoreNextFilterEvent; } + wxString GetCurrentWildCard() const { return m_wildcards[GetFilterIndex()]; } @@ -56,6 +60,10 @@ private: // First wildcard in filter, to be used when the user // saves a file without giving an extension. wxArrayString m_wildcards; + + // If true, ignore the next event because it was generated by us and not + // the user. + bool m_ignoreNextFilterEvent; }; #if wxUSE_FILECTRL @@ -110,6 +118,14 @@ public: virtual bool HasMultipleFileSelection() const { return HasFlag( wxFC_MULTIPLE ); } virtual void ShowHidden(bool show); + virtual bool HasFilterChoice() const + { return m_fc.HasFilterChoice(); } + + + // Implementation only from now on. + bool GTKShouldIgnoreNextFilterEvent() const + { return m_fc.ShouldIgnoreNextFilterEvent(); } + bool m_checkNextSelEvent; bool m_ignoreNextFolderChangeEvent; diff --git a/interface/wx/filectrl.h b/interface/wx/filectrl.h index 56be6351e8..f638e0234c 100644 --- a/interface/wx/filectrl.h +++ b/interface/wx/filectrl.h @@ -37,6 +37,9 @@ The user changed the current selection(by selecting or deselecting a file) @event{EVT_FILECTRL_FOLDERCHANGED(id, func)} The current folder of the file control has been changed + @event{EVT_FILECTRL_FILTERCHANGED(id, func)} + The current file filter of the file control has been changed. + @since 2.9.1 @endEventTable @library{wxbase} @@ -195,6 +198,8 @@ public: The user changed the current selection(by selecting or deselecting a file) @event{EVT_FILECTRL_FOLDERCHANGED(id, func)} The current folder of the file control has been changed + @event{EVT_FILECTRL_FILTERCHANGED(id, func)} + The current file filter of the file control has been changed @endEventTable @library{wxbase} @@ -229,6 +234,16 @@ public: */ wxArrayString GetFiles() const; + /** + Returns the current file filter index. + + For a @b EVT_FILECTRL_FILTERCHANGED event, this method returns the new + file filter index. + + @since 2.9.1 + */ + int GetFilterIndex() const; + /** Sets the files changed by this event. */ @@ -239,5 +254,12 @@ public: Sets the directory of this event. */ void SetDirectory( const wxString &directory ); + + /** + Sets the filter index changed by this event. + + @since 2.9.1 + */ + void SetFilterIndex(int index); }; diff --git a/samples/widgets/filectrl.cpp b/samples/widgets/filectrl.cpp index a27367db31..fc6f9c679b 100644 --- a/samples/widgets/filectrl.cpp +++ b/samples/widgets/filectrl.cpp @@ -130,6 +130,7 @@ BEGIN_EVENT_TABLE( FileCtrlWidgetsPage, WidgetsPage ) EVT_CHECKBOX( wxID_ANY, FileCtrlWidgetsPage::OnCheckBox ) EVT_RADIOBOX( wxID_ANY, FileCtrlWidgetsPage::OnRadioBox ) + EVT_FILECTRL_FILTERCHANGED( wxID_ANY, FileCtrlWidgetsPage::OnFileCtrl ) EVT_FILECTRL_FOLDERCHANGED( wxID_ANY, FileCtrlWidgetsPage::OnFileCtrl ) EVT_FILECTRL_SELECTIONCHANGED( wxID_ANY, FileCtrlWidgetsPage::OnFileCtrl ) EVT_FILECTRL_FILEACTIVATED( wxID_ANY, FileCtrlWidgetsPage::OnFileCtrl ) @@ -317,6 +318,11 @@ void FileCtrlWidgetsPage::OnFileCtrl( wxFileCtrlEvent& event ) { wxLogMessage("Selection changed event: %s", wxJoin(event.GetFiles(), ' ')); } + else if ( event.GetEventType() == wxEVT_FILECTRL_FILTERCHANGED ) + { + wxLogMessage("Filter changed event: filter %d selected", + event.GetFilterIndex() + 1); + } } #endif // wxUSE_FILECTRL diff --git a/src/common/filectrlcmn.cpp b/src/common/filectrlcmn.cpp index dc9c7bb1e2..b8d3ec1830 100644 --- a/src/common/filectrlcmn.cpp +++ b/src/common/filectrlcmn.cpp @@ -28,11 +28,21 @@ const char wxFileCtrlNameStr[] = "wxfilectrl"; wxDEFINE_EVENT( wxEVT_FILECTRL_SELECTIONCHANGED, wxFileCtrlEvent ); wxDEFINE_EVENT( wxEVT_FILECTRL_FILEACTIVATED, wxFileCtrlEvent ); wxDEFINE_EVENT( wxEVT_FILECTRL_FOLDERCHANGED, wxFileCtrlEvent ); +wxDEFINE_EVENT( wxEVT_FILECTRL_FILTERCHANGED, wxFileCtrlEvent ); IMPLEMENT_DYNAMIC_CLASS( wxFileCtrlEvent, wxCommandEvent ) // some helper functions +void GenerateFilterChangedEvent( wxFileCtrlBase *fileCtrl, wxWindow *wnd ) +{ + wxFileCtrlEvent event( wxEVT_FILECTRL_FILTERCHANGED, wnd, wnd->GetId() ); + + event.SetFilterIndex( fileCtrl->GetFilterIndex() ); + + wnd->GetEventHandler()->ProcessEvent( event ); +} + void GenerateFolderChangedEvent( wxFileCtrlBase *fileCtrl, wxWindow *wnd ) { wxFileCtrlEvent event( wxEVT_FILECTRL_FOLDERCHANGED, wnd, wnd->GetId() ); diff --git a/src/generic/filectrlg.cpp b/src/generic/filectrlg.cpp index 3ab54d312b..a5355661c6 100644 --- a/src/generic/filectrlg.cpp +++ b/src/generic/filectrlg.cpp @@ -1184,6 +1184,8 @@ void wxGenericFileCtrl::DoSetFilterIndex( int filterindex ) { m_filterExtension.clear(); } + + GenerateFilterChangedEvent( this, this ); } void wxGenericFileCtrl::SetWildcard( const wxString& wildCard ) diff --git a/src/gtk/filectrl.cpp b/src/gtk/filectrl.cpp index f670e07350..eec4ce2a7a 100644 --- a/src/gtk/filectrl.cpp +++ b/src/gtk/filectrl.cpp @@ -26,6 +26,7 @@ #include "wx/gtk/private.h" #include "wx/filedlg.h" #include "wx/filename.h" +#include "wx/scopeguard.h" #include "wx/tokenzr.h" //----------------------------------------------------------------------------- @@ -126,6 +127,9 @@ void wxGtkFileChooser::SetWildcard( const wxString& wildCard ) GSList* ifilters = gtk_file_chooser_list_filters( chooser ); GSList* filters = ifilters; + m_ignoreNextFilterEvent = true; + wxON_BLOCK_EXIT_SET(m_ignoreNextFilterEvent, false); + while ( ifilters ) { gtk_file_chooser_remove_filter( chooser, GTK_FILE_FILTER( ifilters->data ) ); @@ -201,6 +205,11 @@ int wxGtkFileChooser::GetFilterIndex() const return index; } +bool wxGtkFileChooser::HasFilterChoice() const +{ + return gtk_file_chooser_get_filter( m_widget ) != NULL; +} + //----------------------------------------------------------------------------- // end wxGtkFileChooser Implementation //----------------------------------------------------------------------------- @@ -257,6 +266,21 @@ extern "C" } } +extern "C" +{ + static void + gtkfilechooserwidget_notify_callback( GObject *WXUNUSED( gobject ), GParamSpec *arg1, wxGtkFileCtrl *fileCtrl ) + { + const char *name = g_param_spec_get_name (arg1); + if ( strcmp( name, "filter" ) == 0 && + fileCtrl->HasFilterChoice() && + !fileCtrl->GTKShouldIgnoreNextFilterEvent() ) + { + GenerateFilterChangedEvent( fileCtrl, fileCtrl ); + } + } +} + // wxGtkFileCtrl implementation IMPLEMENT_DYNAMIC_CLASS( wxGtkFileCtrl, wxControl ) @@ -311,6 +335,10 @@ bool wxGtkFileCtrl::Create( wxWindow *parent, G_CALLBACK ( gtkfilechooserwidget_selection_changed_callback ), this ); + g_signal_connect ( m_fcWidget, "notify", + G_CALLBACK ( gtkfilechooserwidget_notify_callback ), + this ); + m_fc.SetWidget( m_fcWidget ); if ( style & wxFC_MULTIPLE ) -- 2.47.2