]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/filectrl.cpp
Fixed bug: wxPropertyGrid::Thaw() should no longer move the scroll bar when reselecti...
[wxWidgets.git] / src / gtk / filectrl.cpp
CommitLineData
0cf3e587
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: src/gtk/filectrl.cpp
3// Purpose: wxGtkFileCtrl Implementation
4// Author: Diaa M. Sami
5// Created: 2007-08-10
6// RCS-ID: $Id$
7// Copyright: (c) Diaa M. Sami
8// Licence: wxWindows licence
9///////////////////////////////////////////////////////////////////////////////
10
11#include "wx/wxprec.h"
12
13#ifdef __BORLANDC__
14#pragma hdrstop
15#endif
16
17#include "wx/filectrl.h"
18
a82b0593 19#if wxUSE_FILECTRL && !defined(__WXUNIVERSAL__)
cc681534 20
0cf3e587
VZ
21#ifndef WX_PRECOMP
22# include "wx/sizer.h"
23# include "wx/debug.h"
24#endif
25
26#include "wx/gtk/private.h"
27#include "wx/filedlg.h"
28#include "wx/filename.h"
29#include "wx/tokenzr.h"
30
31//-----------------------------------------------------------------------------
32// wxGtkFileChooser implementation
33//-----------------------------------------------------------------------------
34
35void wxGtkFileChooser::SetWidget(GtkFileChooser *w)
36{
37 // check arguments
38 wxASSERT( w );
39 wxASSERT( GTK_FILE_CHOOSER( w ) );
40
41 this->m_widget = w;
42}
43
44wxString wxGtkFileChooser::GetPath() const
45{
46 wxGtkString str( gtk_file_chooser_get_filename( m_widget ) );
47
260020e3
PC
48 wxString string;
49 if (str.c_str() != NULL)
50 string = wxConvFileName->cMB2WX(str);
51 return string;
0cf3e587
VZ
52}
53
54void wxGtkFileChooser::GetFilenames( wxArrayString& files ) const
55{
56 GetPaths( files );
57 for ( size_t n = 0; n < files.GetCount(); ++n )
58 {
59 const wxFileName file( files[n] );
60 files[n] = file.GetFullName();
61 }
62}
63
64void wxGtkFileChooser::GetPaths( wxArrayString& paths ) const
65{
66 paths.Empty();
67 if ( gtk_file_chooser_get_select_multiple( m_widget ) )
68 {
69 GSList *gpathsi = gtk_file_chooser_get_filenames( m_widget );
70 GSList *gpaths = gpathsi;
71 while ( gpathsi )
72 {
73 wxString file( wxConvFileName->cMB2WX( ( gchar* ) gpathsi->data ) );
74 paths.Add( file );
75 g_free( gpathsi->data );
76 gpathsi = gpathsi->next;
77 }
78
79 g_slist_free( gpaths );
80 }
81 else
82 paths.Add( GetPath() );
83}
84
85bool wxGtkFileChooser::SetPath( const wxString& path )
86{
87 if ( path.empty() ) return true;
88
89 return gtk_file_chooser_set_filename( m_widget,
90 wxConvFileName->cWX2MB( path.c_str() ) );
91}
92
93bool wxGtkFileChooser::SetDirectory( const wxString& dir )
94{
95 const gboolean b =
96 gtk_file_chooser_set_current_folder( m_widget,
97 wxConvFileName->cWX2MB( dir.c_str() ) );
260020e3 98 return b != 0;
0cf3e587
VZ
99}
100
101wxString wxGtkFileChooser::GetDirectory() const
102{
103 const wxGtkString str( gtk_file_chooser_get_current_folder( m_widget ) );
104 return wxString( str, *wxConvFileName );
105}
106
107wxString wxGtkFileChooser::GetFilename() const
108{
109 return wxFileName( GetPath() ).GetFullName();
110}
111
112void wxGtkFileChooser::SetWildcard( const wxString& wildCard )
113{
20380343
RR
114 m_wildcards.Empty();
115
0cf3e587
VZ
116 // parse filters
117 wxArrayString wildDescriptions, wildFilters;
118
119 if ( !wxParseCommonDialogsFilter( wildCard, wildDescriptions, wildFilters ) )
120 {
121 wxFAIL_MSG( wxT( "wxGtkFileChooser::SetWildcard - bad wildcard string" ) );
122 }
123 else
124 {
125 // Parsing went fine. Set m_wildCard to be returned by wxGtkFileChooserBase::GetWildcard
126 GtkFileChooser* chooser = m_widget;
127
128 // empty current filter list:
129 GSList* ifilters = gtk_file_chooser_list_filters( chooser );
130 GSList* filters = ifilters;
131
132 while ( ifilters )
133 {
134 gtk_file_chooser_remove_filter( chooser, GTK_FILE_FILTER( ifilters->data ) );
135 ifilters = ifilters->next;
136 }
137 g_slist_free( filters );
138
139 if (!wildCard.empty())
140 {
141 // add parsed to GtkChooser
142 for ( size_t n = 0; n < wildFilters.GetCount(); ++n )
143 {
144 GtkFileFilter* filter = gtk_file_filter_new();
145
146 gtk_file_filter_set_name( filter, wxGTK_CONV_SYS( wildDescriptions[n] ) );
147
148 wxStringTokenizer exttok( wildFilters[n], wxT( ";" ) );
03647350 149
81d6a507 150 int n1 = 1;
0cf3e587
VZ
151 while ( exttok.HasMoreTokens() )
152 {
153 wxString token = exttok.GetNextToken();
154 gtk_file_filter_add_pattern( filter, wxGTK_CONV_SYS( token ) );
03647350 155
81d6a507 156 if (n1 == 1)
20380343 157 m_wildcards.Add( token ); // Only add first pattern to list, used later when saving
81d6a507 158 n1++;
0cf3e587
VZ
159 }
160
161 gtk_file_chooser_add_filter( chooser, filter );
162 }
163
164 // Reset the filter index
165 SetFilterIndex( 0 );
166 }
167 }
168}
169
170void wxGtkFileChooser::SetFilterIndex( int filterIndex )
171{
172 gpointer filter;
173 GtkFileChooser *chooser = m_widget;
174 GSList *filters = gtk_file_chooser_list_filters( chooser );
175
176 filter = g_slist_nth_data( filters, filterIndex );
177
178 if ( filter != NULL )
179 {
180 gtk_file_chooser_set_filter( chooser, GTK_FILE_FILTER( filter ) );
181 }
182 else
183 {
184 wxFAIL_MSG( wxT( "wxGtkFileChooser::SetFilterIndex - bad filter index" ) );
185 }
186
187 g_slist_free( filters );
188}
189
190int wxGtkFileChooser::GetFilterIndex() const
191{
192 GtkFileChooser *chooser = m_widget;
193 GtkFileFilter *filter = gtk_file_chooser_get_filter( chooser );
194 GSList *filters = gtk_file_chooser_list_filters( chooser );
195 const gint index = g_slist_index( filters, filter );
196 g_slist_free( filters );
197
198 if ( index == -1 )
199 {
200 wxFAIL_MSG( wxT( "wxGtkFileChooser::GetFilterIndex - bad filter index returned by gtk+" ) );
201 return 0;
202 }
203 else
204 return index;
74ab5f5b 205}
0cf3e587
VZ
206
207//-----------------------------------------------------------------------------
208// end wxGtkFileChooser Implementation
209//-----------------------------------------------------------------------------
210
211#if wxUSE_FILECTRL
212
213// gtk signal handlers
214
215extern "C"
216{
217 static void
218 gtkfilechooserwidget_file_activated_callback( GtkWidget *WXUNUSED( widget ), wxGtkFileCtrl *fileCtrl )
219 {
220 GenerateFileActivatedEvent( fileCtrl, fileCtrl );
221 }
222}
223
224extern "C"
225{
226 static void
227 gtkfilechooserwidget_selection_changed_callback( GtkWidget *WXUNUSED( widget ), wxGtkFileCtrl *fileCtrl )
228 {
229 // check next selection event and ignore it if it has 0 files
230 // because such events are redundantly generated by gtk.
231 if ( fileCtrl->m_checkNextSelEvent )
232 {
233 wxArrayString filenames;
234 fileCtrl->GetFilenames( filenames );
235
236 if ( filenames.Count() != 0 )
237 fileCtrl->m_checkNextSelEvent = false;
238 }
239
240 if ( !fileCtrl->m_checkNextSelEvent )
241 GenerateSelectionChangedEvent( fileCtrl, fileCtrl );
242 }
243}
244
245extern "C"
246{
247 static void
248 gtkfilechooserwidget_folder_changed_callback( GtkWidget *WXUNUSED( widget ), wxGtkFileCtrl *fileCtrl )
249 {
250 if ( fileCtrl->m_ignoreNextFolderChangeEvent )
251 {
252 fileCtrl->m_ignoreNextFolderChangeEvent = false;
253 }
254 else
255 {
256 GenerateFolderChangedEvent( fileCtrl, fileCtrl );
257 }
258
259 fileCtrl->m_checkNextSelEvent = true;
260 }
261}
262
263// wxGtkFileCtrl implementation
264
265IMPLEMENT_DYNAMIC_CLASS( wxGtkFileCtrl, wxControl )
266
267void wxGtkFileCtrl::Init()
268{
0cf3e587
VZ
269 m_checkNextSelEvent = false;
270
271 // ignore the first folder change event which is fired upon startup.
272 m_ignoreNextFolderChangeEvent = true;
273}
274
275bool wxGtkFileCtrl::Create( wxWindow *parent,
276 wxWindowID id,
277 const wxString& defaultDirectory,
278 const wxString& defaultFileName,
279 const wxString& wildCard,
280 long style,
281 const wxPoint& pos,
282 const wxSize& size,
283 const wxString& name )
284{
285 if ( !PreCreation( parent, pos, size ) ||
286 !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ) )
287 {
288 wxFAIL_MSG( wxT( "wxGtkFileCtrl creation failed" ) );
289 return false;
290 }
291
260020e3 292 GtkFileChooserAction gtkAction = GTK_FILE_CHOOSER_ACTION_OPEN;
0cf3e587
VZ
293
294 if ( style & wxFC_SAVE )
0cf3e587 295 gtkAction = GTK_FILE_CHOOSER_ACTION_SAVE;
0cf3e587
VZ
296
297 m_widget = gtk_alignment_new ( 0, 0, 1, 1 );
9ff9d30c 298 g_object_ref(m_widget);
260020e3 299 m_fcWidget = GTK_FILE_CHOOSER( gtk_file_chooser_widget_new(gtkAction) );
0cf3e587
VZ
300 gtk_widget_show ( GTK_WIDGET( m_fcWidget ) );
301 gtk_container_add ( GTK_CONTAINER ( m_widget ), GTK_WIDGET( m_fcWidget ) );
302
303 m_focusWidget = GTK_WIDGET( m_fcWidget );
304
305 g_signal_connect ( m_fcWidget, "file-activated",
306 G_CALLBACK ( gtkfilechooserwidget_file_activated_callback ),
307 this );
308
309 g_signal_connect ( m_fcWidget, "current-folder-changed",
310 G_CALLBACK ( gtkfilechooserwidget_folder_changed_callback ),
311 this );
312
313 g_signal_connect ( m_fcWidget, "selection-changed",
314 G_CALLBACK ( gtkfilechooserwidget_selection_changed_callback ),
315 this );
316
317 m_fc.SetWidget( m_fcWidget );
318
319 if ( style & wxFC_MULTIPLE )
320 gtk_file_chooser_set_select_multiple( m_fcWidget, true );
321
322 SetWildcard( wildCard );
323
324 // if defaultDir is specified it should contain the directory and
325 // defaultFileName should contain the default name of the file, however if
326 // directory is not given, defaultFileName contains both
327 wxFileName fn;
328 if ( defaultDirectory.empty() )
329 fn.Assign( defaultFileName );
330 else if ( !defaultFileName.empty() )
331 fn.Assign( defaultDirectory, defaultFileName );
332 else
333 fn.AssignDir( defaultDirectory );
334
335 // set the initial file name and/or directory
336 const wxString dir = fn.GetPath();
337 if ( !dir.empty() )
338 {
339 gtk_file_chooser_set_current_folder( m_fcWidget,
340 dir.fn_str() );
341 }
342
343 const wxString fname = fn.GetFullName();
344 if ( style & wxFC_SAVE )
345 {
346 if ( !fname.empty() )
347 {
348 gtk_file_chooser_set_current_name( m_fcWidget,
349 fname.fn_str() );
350 }
351 }
352 else // wxFC_OPEN
353 {
354 if ( !fname.empty() )
355 {
356 gtk_file_chooser_set_filename( m_fcWidget,
357 fn.GetFullPath().fn_str() );
358 }
359 }
360
361 m_parent->DoAddChild( this );
362
363 PostCreation( size );
364
365 return TRUE;
366}
367
368bool wxGtkFileCtrl::SetPath( const wxString& path )
369{
370 return m_fc.SetPath( path );
371}
372
373bool wxGtkFileCtrl::SetDirectory( const wxString& dir )
374{
375 return m_fc.SetDirectory( dir );
376}
377
378bool wxGtkFileCtrl::SetFilename( const wxString& name )
379{
700d08c1 380 if ( HasFlag( wxFC_SAVE ) )
0cf3e587 381 {
700d08c1
RR
382 gtk_file_chooser_set_current_name( m_fcWidget, wxGTK_CONV( name ) );
383 return true;
0cf3e587 384 }
700d08c1
RR
385 else
386 return SetPath( wxFileName( GetDirectory(), name ).GetFullPath() );
0cf3e587
VZ
387}
388
389void wxGtkFileCtrl::SetWildcard( const wxString& wildCard )
390{
391 m_wildCard = wildCard;
392
393 m_fc.SetWildcard( wildCard );
394}
395
396void wxGtkFileCtrl::SetFilterIndex( int filterIndex )
397{
398 m_fc.SetFilterIndex( filterIndex );
399}
400
401wxString wxGtkFileCtrl::GetPath() const
402{
403 return m_fc.GetPath();
404}
405
406void wxGtkFileCtrl::GetPaths( wxArrayString& paths ) const
407{
408 m_fc.GetPaths( paths );
409}
410
411wxString wxGtkFileCtrl::GetDirectory() const
412{
413 return m_fc.GetDirectory();
414}
415
416wxString wxGtkFileCtrl::GetFilename() const
417{
418 return m_fc.GetFilename();
419}
420
421void wxGtkFileCtrl::GetFilenames( wxArrayString& files ) const
422{
423 m_fc.GetFilenames( files );
424}
425
260020e3 426void wxGtkFileCtrl::ShowHidden(bool show)
0cf3e587 427{
700d08c1 428 // gtk_file_chooser_set_show_hidden() is new in 2.6
33a56604 429 g_object_set (G_OBJECT (m_fcWidget), "show-hidden", show, NULL);
0cf3e587
VZ
430}
431
ff654490 432#endif // wxUSE_FILECTRL
cc681534 433
a82b0593 434#endif // wxUSE_FILECTRL && !defined(__WXUNIVERSAL__)