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"
20 # include "wx/sizer.h"
21 # include "wx/debug.h"
24 #include "wx/gtk/private.h"
25 #include "wx/filedlg.h"
26 #include "wx/filename.h"
27 #include "wx/tokenzr.h"
29 //-----------------------------------------------------------------------------
30 // wxGtkFileChooser implementation
31 //-----------------------------------------------------------------------------
33 void wxGtkFileChooser::SetWidget(GtkFileChooser
*w
)
37 wxASSERT( GTK_FILE_CHOOSER( w
) );
42 wxString
wxGtkFileChooser::GetPath() const
44 wxGtkString
str( gtk_file_chooser_get_filename( m_widget
) );
46 if ( str
.c_str() == NULL
)
49 return wxConvFileName
->cMB2WX( str
);
52 void wxGtkFileChooser::GetFilenames( wxArrayString
& files
) const
55 for ( size_t n
= 0; n
< files
.GetCount(); ++n
)
57 const wxFileName
file( files
[n
] );
58 files
[n
] = file
.GetFullName();
62 void wxGtkFileChooser::GetPaths( wxArrayString
& paths
) const
65 if ( gtk_file_chooser_get_select_multiple( m_widget
) )
67 GSList
*gpathsi
= gtk_file_chooser_get_filenames( m_widget
);
68 GSList
*gpaths
= gpathsi
;
71 wxString
file( wxConvFileName
->cMB2WX( ( gchar
* ) gpathsi
->data
) );
73 g_free( gpathsi
->data
);
74 gpathsi
= gpathsi
->next
;
77 g_slist_free( gpaths
);
80 paths
.Add( GetPath() );
83 bool wxGtkFileChooser::SetPath( const wxString
& path
)
85 if ( path
.empty() ) return true;
87 return gtk_file_chooser_set_filename( m_widget
,
88 wxConvFileName
->cWX2MB( path
.c_str() ) );
91 bool wxGtkFileChooser::SetDirectory( const wxString
& dir
)
94 gtk_file_chooser_set_current_folder( m_widget
,
95 wxConvFileName
->cWX2MB( dir
.c_str() ) );
99 wxString
wxGtkFileChooser::GetDirectory() const
101 const wxGtkString
str( gtk_file_chooser_get_current_folder( m_widget
) );
102 return wxString( str
, *wxConvFileName
);
105 wxString
wxGtkFileChooser::GetFilename() const
107 return wxFileName( GetPath() ).GetFullName();
110 void wxGtkFileChooser::SetWildcard( const wxString
& wildCard
)
113 wxArrayString wildDescriptions
, wildFilters
;
115 if ( !wxParseCommonDialogsFilter( wildCard
, wildDescriptions
, wildFilters
) )
117 wxFAIL_MSG( wxT( "wxGtkFileChooser::SetWildcard - bad wildcard string" ) );
121 // Parsing went fine. Set m_wildCard to be returned by wxGtkFileChooserBase::GetWildcard
122 GtkFileChooser
* chooser
= m_widget
;
124 // empty current filter list:
125 GSList
* ifilters
= gtk_file_chooser_list_filters( chooser
);
126 GSList
* filters
= ifilters
;
130 gtk_file_chooser_remove_filter( chooser
, GTK_FILE_FILTER( ifilters
->data
) );
131 ifilters
= ifilters
->next
;
133 g_slist_free( filters
);
135 if (!wildCard
.empty())
137 // add parsed to GtkChooser
138 for ( size_t n
= 0; n
< wildFilters
.GetCount(); ++n
)
140 GtkFileFilter
* filter
= gtk_file_filter_new();
142 gtk_file_filter_set_name( filter
, wxGTK_CONV_SYS( wildDescriptions
[n
] ) );
144 wxStringTokenizer
exttok( wildFilters
[n
], wxT( ";" ) );
145 while ( exttok
.HasMoreTokens() )
147 wxString token
= exttok
.GetNextToken();
148 gtk_file_filter_add_pattern( filter
, wxGTK_CONV_SYS( token
) );
151 gtk_file_chooser_add_filter( chooser
, filter
);
154 // Reset the filter index
160 void wxGtkFileChooser::SetFilterIndex( int filterIndex
)
163 GtkFileChooser
*chooser
= m_widget
;
164 GSList
*filters
= gtk_file_chooser_list_filters( chooser
);
166 filter
= g_slist_nth_data( filters
, filterIndex
);
168 if ( filter
!= NULL
)
170 gtk_file_chooser_set_filter( chooser
, GTK_FILE_FILTER( filter
) );
174 wxFAIL_MSG( wxT( "wxGtkFileChooser::SetFilterIndex - bad filter index" ) );
177 g_slist_free( filters
);
180 int wxGtkFileChooser::GetFilterIndex() const
182 GtkFileChooser
*chooser
= m_widget
;
183 GtkFileFilter
*filter
= gtk_file_chooser_get_filter( chooser
);
184 GSList
*filters
= gtk_file_chooser_list_filters( chooser
);
185 const gint index
= g_slist_index( filters
, filter
);
186 g_slist_free( filters
);
190 wxFAIL_MSG( wxT( "wxGtkFileChooser::GetFilterIndex - bad filter index returned by gtk+" ) );
197 //-----------------------------------------------------------------------------
198 // end wxGtkFileChooser Implementation
199 //-----------------------------------------------------------------------------
203 // gtk signal handlers
208 gtkfilechooserwidget_file_activated_callback( GtkWidget
*WXUNUSED( widget
), wxGtkFileCtrl
*fileCtrl
)
210 GenerateFileActivatedEvent( fileCtrl
, fileCtrl
);
217 gtkfilechooserwidget_selection_changed_callback( GtkWidget
*WXUNUSED( widget
), wxGtkFileCtrl
*fileCtrl
)
219 // check next selection event and ignore it if it has 0 files
220 // because such events are redundantly generated by gtk.
221 if ( fileCtrl
->m_checkNextSelEvent
)
223 wxArrayString filenames
;
224 fileCtrl
->GetFilenames( filenames
);
226 if ( filenames
.Count() != 0 )
227 fileCtrl
->m_checkNextSelEvent
= false;
230 if ( !fileCtrl
->m_checkNextSelEvent
)
231 GenerateSelectionChangedEvent( fileCtrl
, fileCtrl
);
238 gtkfilechooserwidget_folder_changed_callback( GtkWidget
*WXUNUSED( widget
), wxGtkFileCtrl
*fileCtrl
)
240 if ( fileCtrl
->m_ignoreNextFolderChangeEvent
)
242 fileCtrl
->m_ignoreNextFolderChangeEvent
= false;
246 GenerateFolderChangedEvent( fileCtrl
, fileCtrl
);
249 fileCtrl
->m_checkNextSelEvent
= true;
253 // wxGtkFileCtrl implementation
255 IMPLEMENT_DYNAMIC_CLASS( wxGtkFileCtrl
, wxControl
)
257 void wxGtkFileCtrl::Init()
260 m_checkNextSelEvent
= false;
262 // ignore the first folder change event which is fired upon startup.
263 m_ignoreNextFolderChangeEvent
= true;
266 bool wxGtkFileCtrl::Create( wxWindow
*parent
,
268 const wxString
& defaultDirectory
,
269 const wxString
& defaultFileName
,
270 const wxString
& wildCard
,
274 const wxString
& name
)
276 if ( !PreCreation( parent
, pos
, size
) ||
277 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
) )
279 wxFAIL_MSG( wxT( "wxGtkFileCtrl creation failed" ) );
283 GtkFileChooserAction gtkAction
;
285 if ( style
& wxFC_SAVE
)
287 gtkAction
= GTK_FILE_CHOOSER_ACTION_SAVE
;
289 else if ( style
& wxFC_OPEN
)
291 gtkAction
= GTK_FILE_CHOOSER_ACTION_OPEN
;
294 m_widget
= gtk_alignment_new ( 0, 0, 1, 1 );
295 m_fcWidget
= GTK_FILE_CHOOSER( gtk_file_chooser_widget_new( GTK_FILE_CHOOSER_ACTION_OPEN
) );
296 gtk_widget_show ( GTK_WIDGET( m_fcWidget
) );
297 gtk_container_add ( GTK_CONTAINER ( m_widget
), GTK_WIDGET( m_fcWidget
) );
299 m_focusWidget
= GTK_WIDGET( m_fcWidget
);
301 g_signal_connect ( m_fcWidget
, "file-activated",
302 G_CALLBACK ( gtkfilechooserwidget_file_activated_callback
),
305 g_signal_connect ( m_fcWidget
, "current-folder-changed",
306 G_CALLBACK ( gtkfilechooserwidget_folder_changed_callback
),
309 g_signal_connect ( m_fcWidget
, "selection-changed",
310 G_CALLBACK ( gtkfilechooserwidget_selection_changed_callback
),
313 m_fc
.SetWidget( m_fcWidget
);
315 if ( style
& wxFC_MULTIPLE
)
316 gtk_file_chooser_set_select_multiple( m_fcWidget
, true );
318 SetWildcard( wildCard
);
320 // if defaultDir is specified it should contain the directory and
321 // defaultFileName should contain the default name of the file, however if
322 // directory is not given, defaultFileName contains both
324 if ( defaultDirectory
.empty() )
325 fn
.Assign( defaultFileName
);
326 else if ( !defaultFileName
.empty() )
327 fn
.Assign( defaultDirectory
, defaultFileName
);
329 fn
.AssignDir( defaultDirectory
);
331 // set the initial file name and/or directory
332 const wxString dir
= fn
.GetPath();
335 gtk_file_chooser_set_current_folder( m_fcWidget
,
339 const wxString fname
= fn
.GetFullName();
340 if ( style
& wxFC_SAVE
)
342 if ( !fname
.empty() )
344 gtk_file_chooser_set_current_name( m_fcWidget
,
350 if ( !fname
.empty() )
352 gtk_file_chooser_set_filename( m_fcWidget
,
353 fn
.GetFullPath().fn_str() );
357 m_parent
->DoAddChild( this );
359 PostCreation( size
);
364 bool wxGtkFileCtrl::SetPath( const wxString
& path
)
366 return m_fc
.SetPath( path
);
369 bool wxGtkFileCtrl::SetDirectory( const wxString
& dir
)
371 return m_fc
.SetDirectory( dir
);
374 bool wxGtkFileCtrl::SetFilename( const wxString
& name
)
376 if ( !gtk_check_version( 2, 4, 0 ) )
378 if ( HasFlag( wxFC_SAVE
) )
380 gtk_file_chooser_set_current_name( m_fcWidget
, wxGTK_CONV( name
) );
384 return SetPath( wxFileName( GetDirectory(), name
).GetFullPath() );
390 void wxGtkFileCtrl::SetWildcard( const wxString
& wildCard
)
392 m_wildCard
= wildCard
;
394 m_fc
.SetWildcard( wildCard
);
397 void wxGtkFileCtrl::SetFilterIndex( int filterIndex
)
399 m_fc
.SetFilterIndex( filterIndex
);
402 wxString
wxGtkFileCtrl::GetPath() const
404 return m_fc
.GetPath();
407 void wxGtkFileCtrl::GetPaths( wxArrayString
& paths
) const
409 m_fc
.GetPaths( paths
);
412 wxString
wxGtkFileCtrl::GetDirectory() const
414 return m_fc
.GetDirectory();
417 wxString
wxGtkFileCtrl::GetFilename() const
419 return m_fc
.GetFilename();
422 void wxGtkFileCtrl::GetFilenames( wxArrayString
& files
) const
424 m_fc
.GetFilenames( files
);
427 void wxGtkFileCtrl::ShowHidden(const bool show
)
429 gtk_file_chooser_set_show_hidden( m_fcWidget
, ( show
== true ) ? TRUE
: FALSE
);
432 #endif // wxUSE_FILECTRL