]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/filectrl.cpp
use const arrays for wxDC array parameters, closes #10712
[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
a82b0593 17#if wxUSE_FILECTRL && !defined(__WXUNIVERSAL__)
cc681534 18
89e5d5bb 19#include "wx/filectrl.h"
0cf3e587
VZ
20
21#include "wx/gtk/private.h"
0cf3e587 22#include "wx/filename.h"
6305f044 23#include "wx/scopeguard.h"
0cf3e587
VZ
24#include "wx/tokenzr.h"
25
26//-----------------------------------------------------------------------------
27// wxGtkFileChooser implementation
28//-----------------------------------------------------------------------------
29
30void wxGtkFileChooser::SetWidget(GtkFileChooser *w)
31{
32 // check arguments
33 wxASSERT( w );
34 wxASSERT( GTK_FILE_CHOOSER( w ) );
35
36 this->m_widget = w;
37}
38
39wxString wxGtkFileChooser::GetPath() const
40{
41 wxGtkString str( gtk_file_chooser_get_filename( m_widget ) );
42
260020e3 43 wxString string;
f069ac48 44 if (str)
b74d7c85 45 string = wxString::FromUTF8(str);
260020e3 46 return string;
0cf3e587
VZ
47}
48
49void wxGtkFileChooser::GetFilenames( wxArrayString& files ) const
50{
51 GetPaths( files );
52 for ( size_t n = 0; n < files.GetCount(); ++n )
53 {
54 const wxFileName file( files[n] );
55 files[n] = file.GetFullName();
56 }
57}
58
59void wxGtkFileChooser::GetPaths( wxArrayString& paths ) const
60{
61 paths.Empty();
62 if ( gtk_file_chooser_get_select_multiple( m_widget ) )
63 {
64 GSList *gpathsi = gtk_file_chooser_get_filenames( m_widget );
65 GSList *gpaths = gpathsi;
66 while ( gpathsi )
67 {
b74d7c85 68 wxString file(wxString::FromUTF8(static_cast<gchar *>(gpathsi->data)));
0cf3e587
VZ
69 paths.Add( file );
70 g_free( gpathsi->data );
71 gpathsi = gpathsi->next;
72 }
73
74 g_slist_free( gpaths );
75 }
76 else
77 paths.Add( GetPath() );
78}
79
80bool wxGtkFileChooser::SetPath( const wxString& path )
81{
b74d7c85
VZ
82 if ( path.empty() )
83 return true;
0cf3e587 84
d5027818 85 return gtk_file_chooser_set_filename( m_widget, path.utf8_str() ) != 0;
0cf3e587
VZ
86}
87
88bool wxGtkFileChooser::SetDirectory( const wxString& dir )
89{
b74d7c85 90 return gtk_file_chooser_set_current_folder( m_widget, dir.utf8_str() ) != 0;
0cf3e587
VZ
91}
92
93wxString wxGtkFileChooser::GetDirectory() const
94{
95 const wxGtkString str( gtk_file_chooser_get_current_folder( m_widget ) );
b74d7c85 96 return wxString::FromUTF8(str);
0cf3e587
VZ
97}
98
99wxString wxGtkFileChooser::GetFilename() const
100{
101 return wxFileName( GetPath() ).GetFullName();
102}
103
104void wxGtkFileChooser::SetWildcard( const wxString& wildCard )
105{
20380343
RR
106 m_wildcards.Empty();
107
0cf3e587
VZ
108 // parse filters
109 wxArrayString wildDescriptions, wildFilters;
110
111 if ( !wxParseCommonDialogsFilter( wildCard, wildDescriptions, wildFilters ) )
112 {
113 wxFAIL_MSG( wxT( "wxGtkFileChooser::SetWildcard - bad wildcard string" ) );
114 }
115 else
116 {
117 // Parsing went fine. Set m_wildCard to be returned by wxGtkFileChooserBase::GetWildcard
118 GtkFileChooser* chooser = m_widget;
119
120 // empty current filter list:
121 GSList* ifilters = gtk_file_chooser_list_filters( chooser );
122 GSList* filters = ifilters;
123
6305f044
VZ
124 m_ignoreNextFilterEvent = true;
125 wxON_BLOCK_EXIT_SET(m_ignoreNextFilterEvent, false);
126
0cf3e587
VZ
127 while ( ifilters )
128 {
129 gtk_file_chooser_remove_filter( chooser, GTK_FILE_FILTER( ifilters->data ) );
130 ifilters = ifilters->next;
131 }
132 g_slist_free( filters );
133
134 if (!wildCard.empty())
135 {
136 // add parsed to GtkChooser
137 for ( size_t n = 0; n < wildFilters.GetCount(); ++n )
138 {
139 GtkFileFilter* filter = gtk_file_filter_new();
140
141 gtk_file_filter_set_name( filter, wxGTK_CONV_SYS( wildDescriptions[n] ) );
142
143 wxStringTokenizer exttok( wildFilters[n], wxT( ";" ) );
03647350 144
81d6a507 145 int n1 = 1;
0cf3e587
VZ
146 while ( exttok.HasMoreTokens() )
147 {
148 wxString token = exttok.GetNextToken();
149 gtk_file_filter_add_pattern( filter, wxGTK_CONV_SYS( token ) );
03647350 150
81d6a507 151 if (n1 == 1)
20380343 152 m_wildcards.Add( token ); // Only add first pattern to list, used later when saving
81d6a507 153 n1++;
0cf3e587
VZ
154 }
155
156 gtk_file_chooser_add_filter( chooser, filter );
157 }
158
159 // Reset the filter index
160 SetFilterIndex( 0 );
161 }
162 }
163}
164
165void wxGtkFileChooser::SetFilterIndex( int filterIndex )
166{
167 gpointer filter;
168 GtkFileChooser *chooser = m_widget;
169 GSList *filters = gtk_file_chooser_list_filters( chooser );
170
171 filter = g_slist_nth_data( filters, filterIndex );
172
173 if ( filter != NULL )
174 {
175 gtk_file_chooser_set_filter( chooser, GTK_FILE_FILTER( filter ) );
176 }
177 else
178 {
179 wxFAIL_MSG( wxT( "wxGtkFileChooser::SetFilterIndex - bad filter index" ) );
180 }
181
182 g_slist_free( filters );
183}
184
185int wxGtkFileChooser::GetFilterIndex() const
186{
187 GtkFileChooser *chooser = m_widget;
188 GtkFileFilter *filter = gtk_file_chooser_get_filter( chooser );
189 GSList *filters = gtk_file_chooser_list_filters( chooser );
190 const gint index = g_slist_index( filters, filter );
191 g_slist_free( filters );
192
193 if ( index == -1 )
194 {
195 wxFAIL_MSG( wxT( "wxGtkFileChooser::GetFilterIndex - bad filter index returned by gtk+" ) );
196 return 0;
197 }
198 else
199 return index;
74ab5f5b 200}
0cf3e587 201
6305f044
VZ
202bool wxGtkFileChooser::HasFilterChoice() const
203{
204 return gtk_file_chooser_get_filter( m_widget ) != NULL;
205}
206
0cf3e587
VZ
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
6305f044
VZ
263extern "C"
264{
265 static void
266 gtkfilechooserwidget_notify_callback( GObject *WXUNUSED( gobject ), GParamSpec *arg1, wxGtkFileCtrl *fileCtrl )
267 {
268 const char *name = g_param_spec_get_name (arg1);
269 if ( strcmp( name, "filter" ) == 0 &&
270 fileCtrl->HasFilterChoice() &&
271 !fileCtrl->GTKShouldIgnoreNextFilterEvent() )
272 {
273 GenerateFilterChangedEvent( fileCtrl, fileCtrl );
274 }
275 }
276}
277
0cf3e587
VZ
278// wxGtkFileCtrl implementation
279
280IMPLEMENT_DYNAMIC_CLASS( wxGtkFileCtrl, wxControl )
281
8ab75332
PC
282wxGtkFileCtrl::~wxGtkFileCtrl()
283{
284 if (m_fcWidget)
285 GTKDisconnect(m_fcWidget);
286}
287
0cf3e587
VZ
288void wxGtkFileCtrl::Init()
289{
0cf3e587
VZ
290 m_checkNextSelEvent = false;
291
292 // ignore the first folder change event which is fired upon startup.
293 m_ignoreNextFolderChangeEvent = true;
294}
295
296bool wxGtkFileCtrl::Create( wxWindow *parent,
297 wxWindowID id,
298 const wxString& defaultDirectory,
299 const wxString& defaultFileName,
300 const wxString& wildCard,
301 long style,
302 const wxPoint& pos,
303 const wxSize& size,
304 const wxString& name )
305{
306 if ( !PreCreation( parent, pos, size ) ||
307 !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ) )
308 {
309 wxFAIL_MSG( wxT( "wxGtkFileCtrl creation failed" ) );
310 return false;
311 }
312
260020e3 313 GtkFileChooserAction gtkAction = GTK_FILE_CHOOSER_ACTION_OPEN;
0cf3e587
VZ
314
315 if ( style & wxFC_SAVE )
0cf3e587 316 gtkAction = GTK_FILE_CHOOSER_ACTION_SAVE;
0cf3e587
VZ
317
318 m_widget = gtk_alignment_new ( 0, 0, 1, 1 );
9ff9d30c 319 g_object_ref(m_widget);
260020e3 320 m_fcWidget = GTK_FILE_CHOOSER( gtk_file_chooser_widget_new(gtkAction) );
0cf3e587
VZ
321 gtk_widget_show ( GTK_WIDGET( m_fcWidget ) );
322 gtk_container_add ( GTK_CONTAINER ( m_widget ), GTK_WIDGET( m_fcWidget ) );
323
324 m_focusWidget = GTK_WIDGET( m_fcWidget );
325
326 g_signal_connect ( m_fcWidget, "file-activated",
327 G_CALLBACK ( gtkfilechooserwidget_file_activated_callback ),
328 this );
329
330 g_signal_connect ( m_fcWidget, "current-folder-changed",
331 G_CALLBACK ( gtkfilechooserwidget_folder_changed_callback ),
332 this );
333
334 g_signal_connect ( m_fcWidget, "selection-changed",
335 G_CALLBACK ( gtkfilechooserwidget_selection_changed_callback ),
336 this );
337
6305f044
VZ
338 g_signal_connect ( m_fcWidget, "notify",
339 G_CALLBACK ( gtkfilechooserwidget_notify_callback ),
340 this );
341
0cf3e587
VZ
342 m_fc.SetWidget( m_fcWidget );
343
344 if ( style & wxFC_MULTIPLE )
345 gtk_file_chooser_set_select_multiple( m_fcWidget, true );
346
347 SetWildcard( wildCard );
348
349 // if defaultDir is specified it should contain the directory and
350 // defaultFileName should contain the default name of the file, however if
351 // directory is not given, defaultFileName contains both
352 wxFileName fn;
353 if ( defaultDirectory.empty() )
354 fn.Assign( defaultFileName );
355 else if ( !defaultFileName.empty() )
356 fn.Assign( defaultDirectory, defaultFileName );
357 else
358 fn.AssignDir( defaultDirectory );
359
360 // set the initial file name and/or directory
361 const wxString dir = fn.GetPath();
362 if ( !dir.empty() )
363 {
364 gtk_file_chooser_set_current_folder( m_fcWidget,
c282e47d 365 wxGTK_CONV_FN(dir) );
0cf3e587
VZ
366 }
367
368 const wxString fname = fn.GetFullName();
369 if ( style & wxFC_SAVE )
370 {
371 if ( !fname.empty() )
372 {
373 gtk_file_chooser_set_current_name( m_fcWidget,
c282e47d 374 wxGTK_CONV_FN(fname) );
0cf3e587
VZ
375 }
376 }
377 else // wxFC_OPEN
378 {
379 if ( !fname.empty() )
380 {
381 gtk_file_chooser_set_filename( m_fcWidget,
c282e47d 382 wxGTK_CONV_FN(fn.GetFullPath()) );
0cf3e587
VZ
383 }
384 }
385
386 m_parent->DoAddChild( this );
387
388 PostCreation( size );
389
390 return TRUE;
391}
392
393bool wxGtkFileCtrl::SetPath( const wxString& path )
394{
395 return m_fc.SetPath( path );
396}
397
398bool wxGtkFileCtrl::SetDirectory( const wxString& dir )
399{
400 return m_fc.SetDirectory( dir );
401}
402
403bool wxGtkFileCtrl::SetFilename( const wxString& name )
404{
700d08c1 405 if ( HasFlag( wxFC_SAVE ) )
0cf3e587 406 {
700d08c1
RR
407 gtk_file_chooser_set_current_name( m_fcWidget, wxGTK_CONV( name ) );
408 return true;
0cf3e587 409 }
700d08c1
RR
410 else
411 return SetPath( wxFileName( GetDirectory(), name ).GetFullPath() );
0cf3e587
VZ
412}
413
414void wxGtkFileCtrl::SetWildcard( const wxString& wildCard )
415{
416 m_wildCard = wildCard;
417
418 m_fc.SetWildcard( wildCard );
419}
420
421void wxGtkFileCtrl::SetFilterIndex( int filterIndex )
422{
423 m_fc.SetFilterIndex( filterIndex );
424}
425
426wxString wxGtkFileCtrl::GetPath() const
427{
428 return m_fc.GetPath();
429}
430
431void wxGtkFileCtrl::GetPaths( wxArrayString& paths ) const
432{
433 m_fc.GetPaths( paths );
434}
435
436wxString wxGtkFileCtrl::GetDirectory() const
437{
438 return m_fc.GetDirectory();
439}
440
441wxString wxGtkFileCtrl::GetFilename() const
442{
443 return m_fc.GetFilename();
444}
445
446void wxGtkFileCtrl::GetFilenames( wxArrayString& files ) const
447{
448 m_fc.GetFilenames( files );
449}
450
260020e3 451void wxGtkFileCtrl::ShowHidden(bool show)
0cf3e587 452{
89e5d5bb 453 gtk_file_chooser_set_show_hidden(m_fcWidget, show);
0cf3e587
VZ
454}
455
ff654490 456#endif // wxUSE_FILECTRL
cc681534 457
a82b0593 458#endif // wxUSE_FILECTRL && !defined(__WXUNIVERSAL__)