1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/filectrl.cpp
3 // Purpose: wxGtkFileCtrl Implementation
4 // Author: Diaa M. Sami
7 // Copyright: (c) Diaa M. Sami
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
11 #include "wx/wxprec.h"
17 #include "wx/filectrl.h"
19 #if wxUSE_FILECTRL && !defined(__WXUNIVERSAL__)
22 # include "wx/sizer.h"
23 # include "wx/debug.h"
26 #include "wx/gtk/private.h"
27 #include "wx/filedlg.h"
28 #include "wx/filename.h"
29 #include "wx/tokenzr.h"
31 //-----------------------------------------------------------------------------
32 // wxGtkFileChooser implementation
33 //-----------------------------------------------------------------------------
35 void wxGtkFileChooser::SetWidget(GtkFileChooser
*w
)
39 wxASSERT( GTK_FILE_CHOOSER( w
) );
44 wxString
wxGtkFileChooser::GetPath() const
46 wxGtkString
str( gtk_file_chooser_get_filename( m_widget
) );
49 if (str
.c_str() != NULL
)
50 string
= wxString::FromUTF8(str
);
54 void wxGtkFileChooser::GetFilenames( wxArrayString
& files
) const
57 for ( size_t n
= 0; n
< files
.GetCount(); ++n
)
59 const wxFileName
file( files
[n
] );
60 files
[n
] = file
.GetFullName();
64 void wxGtkFileChooser::GetPaths( wxArrayString
& paths
) const
67 if ( gtk_file_chooser_get_select_multiple( m_widget
) )
69 GSList
*gpathsi
= gtk_file_chooser_get_filenames( m_widget
);
70 GSList
*gpaths
= gpathsi
;
73 wxString
file(wxString::FromUTF8(static_cast<gchar
*>(gpathsi
->data
)));
75 g_free( gpathsi
->data
);
76 gpathsi
= gpathsi
->next
;
79 g_slist_free( gpaths
);
82 paths
.Add( GetPath() );
85 bool wxGtkFileChooser::SetPath( const wxString
& path
)
90 return gtk_file_chooser_set_filename( m_widget
, path
.utf8_str() );
93 bool wxGtkFileChooser::SetDirectory( const wxString
& dir
)
95 return gtk_file_chooser_set_current_folder( m_widget
, dir
.utf8_str() ) != 0;
98 wxString
wxGtkFileChooser::GetDirectory() const
100 const wxGtkString
str( gtk_file_chooser_get_current_folder( m_widget
) );
101 return wxString::FromUTF8(str
);
104 wxString
wxGtkFileChooser::GetFilename() const
106 return wxFileName( GetPath() ).GetFullName();
109 void wxGtkFileChooser::SetWildcard( const wxString
& wildCard
)
114 wxArrayString wildDescriptions
, wildFilters
;
116 if ( !wxParseCommonDialogsFilter( wildCard
, wildDescriptions
, wildFilters
) )
118 wxFAIL_MSG( wxT( "wxGtkFileChooser::SetWildcard - bad wildcard string" ) );
122 // Parsing went fine. Set m_wildCard to be returned by wxGtkFileChooserBase::GetWildcard
123 GtkFileChooser
* chooser
= m_widget
;
125 // empty current filter list:
126 GSList
* ifilters
= gtk_file_chooser_list_filters( chooser
);
127 GSList
* filters
= ifilters
;
131 gtk_file_chooser_remove_filter( chooser
, GTK_FILE_FILTER( ifilters
->data
) );
132 ifilters
= ifilters
->next
;
134 g_slist_free( filters
);
136 if (!wildCard
.empty())
138 // add parsed to GtkChooser
139 for ( size_t n
= 0; n
< wildFilters
.GetCount(); ++n
)
141 GtkFileFilter
* filter
= gtk_file_filter_new();
143 gtk_file_filter_set_name( filter
, wxGTK_CONV_SYS( wildDescriptions
[n
] ) );
145 wxStringTokenizer
exttok( wildFilters
[n
], wxT( ";" ) );
148 while ( exttok
.HasMoreTokens() )
150 wxString token
= exttok
.GetNextToken();
151 gtk_file_filter_add_pattern( filter
, wxGTK_CONV_SYS( token
) );
154 m_wildcards
.Add( token
); // Only add first pattern to list, used later when saving
158 gtk_file_chooser_add_filter( chooser
, filter
);
161 // Reset the filter index
167 void wxGtkFileChooser::SetFilterIndex( int filterIndex
)
170 GtkFileChooser
*chooser
= m_widget
;
171 GSList
*filters
= gtk_file_chooser_list_filters( chooser
);
173 filter
= g_slist_nth_data( filters
, filterIndex
);
175 if ( filter
!= NULL
)
177 gtk_file_chooser_set_filter( chooser
, GTK_FILE_FILTER( filter
) );
181 wxFAIL_MSG( wxT( "wxGtkFileChooser::SetFilterIndex - bad filter index" ) );
184 g_slist_free( filters
);
187 int wxGtkFileChooser::GetFilterIndex() const
189 GtkFileChooser
*chooser
= m_widget
;
190 GtkFileFilter
*filter
= gtk_file_chooser_get_filter( chooser
);
191 GSList
*filters
= gtk_file_chooser_list_filters( chooser
);
192 const gint index
= g_slist_index( filters
, filter
);
193 g_slist_free( filters
);
197 wxFAIL_MSG( wxT( "wxGtkFileChooser::GetFilterIndex - bad filter index returned by gtk+" ) );
204 //-----------------------------------------------------------------------------
205 // end wxGtkFileChooser Implementation
206 //-----------------------------------------------------------------------------
210 // gtk signal handlers
215 gtkfilechooserwidget_file_activated_callback( GtkWidget
*WXUNUSED( widget
), wxGtkFileCtrl
*fileCtrl
)
217 GenerateFileActivatedEvent( fileCtrl
, fileCtrl
);
224 gtkfilechooserwidget_selection_changed_callback( GtkWidget
*WXUNUSED( widget
), wxGtkFileCtrl
*fileCtrl
)
226 // check next selection event and ignore it if it has 0 files
227 // because such events are redundantly generated by gtk.
228 if ( fileCtrl
->m_checkNextSelEvent
)
230 wxArrayString filenames
;
231 fileCtrl
->GetFilenames( filenames
);
233 if ( filenames
.Count() != 0 )
234 fileCtrl
->m_checkNextSelEvent
= false;
237 if ( !fileCtrl
->m_checkNextSelEvent
)
238 GenerateSelectionChangedEvent( fileCtrl
, fileCtrl
);
245 gtkfilechooserwidget_folder_changed_callback( GtkWidget
*WXUNUSED( widget
), wxGtkFileCtrl
*fileCtrl
)
247 if ( fileCtrl
->m_ignoreNextFolderChangeEvent
)
249 fileCtrl
->m_ignoreNextFolderChangeEvent
= false;
253 GenerateFolderChangedEvent( fileCtrl
, fileCtrl
);
256 fileCtrl
->m_checkNextSelEvent
= true;
260 // wxGtkFileCtrl implementation
262 IMPLEMENT_DYNAMIC_CLASS( wxGtkFileCtrl
, wxControl
)
264 void wxGtkFileCtrl::Init()
266 m_checkNextSelEvent
= false;
268 // ignore the first folder change event which is fired upon startup.
269 m_ignoreNextFolderChangeEvent
= true;
272 bool wxGtkFileCtrl::Create( wxWindow
*parent
,
274 const wxString
& defaultDirectory
,
275 const wxString
& defaultFileName
,
276 const wxString
& wildCard
,
280 const wxString
& name
)
282 if ( !PreCreation( parent
, pos
, size
) ||
283 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
) )
285 wxFAIL_MSG( wxT( "wxGtkFileCtrl creation failed" ) );
289 GtkFileChooserAction gtkAction
= GTK_FILE_CHOOSER_ACTION_OPEN
;
291 if ( style
& wxFC_SAVE
)
292 gtkAction
= GTK_FILE_CHOOSER_ACTION_SAVE
;
294 m_widget
= gtk_alignment_new ( 0, 0, 1, 1 );
295 g_object_ref(m_widget
);
296 m_fcWidget
= GTK_FILE_CHOOSER( gtk_file_chooser_widget_new(gtkAction
) );
297 gtk_widget_show ( GTK_WIDGET( m_fcWidget
) );
298 gtk_container_add ( GTK_CONTAINER ( m_widget
), GTK_WIDGET( m_fcWidget
) );
300 m_focusWidget
= GTK_WIDGET( m_fcWidget
);
302 g_signal_connect ( m_fcWidget
, "file-activated",
303 G_CALLBACK ( gtkfilechooserwidget_file_activated_callback
),
306 g_signal_connect ( m_fcWidget
, "current-folder-changed",
307 G_CALLBACK ( gtkfilechooserwidget_folder_changed_callback
),
310 g_signal_connect ( m_fcWidget
, "selection-changed",
311 G_CALLBACK ( gtkfilechooserwidget_selection_changed_callback
),
314 m_fc
.SetWidget( m_fcWidget
);
316 if ( style
& wxFC_MULTIPLE
)
317 gtk_file_chooser_set_select_multiple( m_fcWidget
, true );
319 SetWildcard( wildCard
);
321 // if defaultDir is specified it should contain the directory and
322 // defaultFileName should contain the default name of the file, however if
323 // directory is not given, defaultFileName contains both
325 if ( defaultDirectory
.empty() )
326 fn
.Assign( defaultFileName
);
327 else if ( !defaultFileName
.empty() )
328 fn
.Assign( defaultDirectory
, defaultFileName
);
330 fn
.AssignDir( defaultDirectory
);
332 // set the initial file name and/or directory
333 const wxString dir
= fn
.GetPath();
336 gtk_file_chooser_set_current_folder( m_fcWidget
,
340 const wxString fname
= fn
.GetFullName();
341 if ( style
& wxFC_SAVE
)
343 if ( !fname
.empty() )
345 gtk_file_chooser_set_current_name( m_fcWidget
,
351 if ( !fname
.empty() )
353 gtk_file_chooser_set_filename( m_fcWidget
,
354 fn
.GetFullPath().fn_str() );
358 m_parent
->DoAddChild( this );
360 PostCreation( size
);
365 bool wxGtkFileCtrl::SetPath( const wxString
& path
)
367 return m_fc
.SetPath( path
);
370 bool wxGtkFileCtrl::SetDirectory( const wxString
& dir
)
372 return m_fc
.SetDirectory( dir
);
375 bool wxGtkFileCtrl::SetFilename( const wxString
& name
)
377 if ( HasFlag( wxFC_SAVE
) )
379 gtk_file_chooser_set_current_name( m_fcWidget
, wxGTK_CONV( name
) );
383 return SetPath( wxFileName( GetDirectory(), name
).GetFullPath() );
386 void wxGtkFileCtrl::SetWildcard( const wxString
& wildCard
)
388 m_wildCard
= wildCard
;
390 m_fc
.SetWildcard( wildCard
);
393 void wxGtkFileCtrl::SetFilterIndex( int filterIndex
)
395 m_fc
.SetFilterIndex( filterIndex
);
398 wxString
wxGtkFileCtrl::GetPath() const
400 return m_fc
.GetPath();
403 void wxGtkFileCtrl::GetPaths( wxArrayString
& paths
) const
405 m_fc
.GetPaths( paths
);
408 wxString
wxGtkFileCtrl::GetDirectory() const
410 return m_fc
.GetDirectory();
413 wxString
wxGtkFileCtrl::GetFilename() const
415 return m_fc
.GetFilename();
418 void wxGtkFileCtrl::GetFilenames( wxArrayString
& files
) const
420 m_fc
.GetFilenames( files
);
423 void wxGtkFileCtrl::ShowHidden(bool show
)
425 // gtk_file_chooser_set_show_hidden() is new in 2.6
426 g_object_set (G_OBJECT (m_fcWidget
), "show-hidden", show
, NULL
);
429 #endif // wxUSE_FILECTRL
431 #endif // wxUSE_FILECTRL && !defined(__WXUNIVERSAL__)