1 /////////////////////////////////////////////////////////////////////////////
2 // Name: gtk/filedlg.cpp
3 // Purpose: native implementation of wxFileDialog
4 // Author: Robert Roebling, Zbigniew Zagorski
6 // Copyright: (c) 1998 Robert Roebling, 2004 Zbigniew Zagorski
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
10 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
11 #pragma implementation "filedlg.h"
14 // For compilers that support precompilation, includes "wx.h".
15 #include "wx/wxprec.h"
17 #if wxUSE_FILEDLG && defined(__WXGTK24__)
19 #include "wx/filedlg.h"
22 #include "wx/filename.h"
25 #include "wx/gtk/private.h"
27 //-----------------------------------------------------------------------------
29 //-----------------------------------------------------------------------------
31 extern void wxapp_install_idle_handler();
34 //-----------------------------------------------------------------------------
35 // "clicked" for OK-button
36 //-----------------------------------------------------------------------------
38 static void gtk_filedialog_ok_callback(GtkWidget
*widget
, wxFileDialog
*dialog
)
40 int style
= dialog
->GetStyle();
41 gchar
* text
= gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(widget
));
42 wxString
filename(wxGTK_CONV_BACK(text
));
44 if ((style
& wxSAVE
) && (style
& wxOVERWRITE_PROMPT
))
46 if (wxFileExists(filename
))
50 _("File '%s' already exists, do you really want to overwrite it?"),
53 wxMessageDialog
dlg(dialog
, msg
, _("Confirm"),
54 wxYES_NO
| wxICON_QUESTION
);
55 if (dlg
.ShowModal() != wxID_YES
)
59 else if ((style
& wxOPEN
) && ( style
& wxFILE_MUST_EXIST
))
61 if (!wxFileExists( filename
))
63 wxMessageDialog
dlg(dialog
,
64 _("Please choose an existing file."),
65 _("Error"), wxOK
| wxICON_ERROR
);
72 // change to the directory where the user went if asked
73 if (style
& wxCHANGE_DIR
)
76 wxSplitPath(filename
, &cwd
, NULL
, NULL
);
78 if (cwd
!= wxGetCwd())
80 wxSetWorkingDirectory(cwd
);
84 dialog
->DoSetPath(filename
);
85 dialog
->UpdateFromDialog();
87 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, wxID_OK
);
88 event
.SetEventObject(dialog
);
89 dialog
->GetEventHandler()->ProcessEvent(event
);
92 //-----------------------------------------------------------------------------
93 // "clicked" for Cancel-button
94 //-----------------------------------------------------------------------------
96 static void gtk_filedialog_cancel_callback(GtkWidget
*WXUNUSED(w
),
99 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, wxID_CANCEL
);
100 event
.SetEventObject(dialog
);
101 dialog
->GetEventHandler()->ProcessEvent(event
);
104 static void gtk_filedialog_response_callback(GtkWidget
*w
,
106 wxFileDialog
*dialog
)
108 wxapp_install_idle_handler();
110 if (response
== GTK_RESPONSE_CANCEL
)
111 gtk_filedialog_cancel_callback(w
, dialog
);
113 gtk_filedialog_ok_callback(w
, dialog
);
116 //-----------------------------------------------------------------------------
118 //-----------------------------------------------------------------------------
120 IMPLEMENT_DYNAMIC_CLASS(wxFileDialog
,wxFileDialogBase
)
122 wxFileDialog::wxFileDialog(wxWindow
*parent
, const wxString
& message
,
123 const wxString
& defaultDir
,
124 const wxString
& defaultFileName
,
125 const wxString
& wildCard
,
126 long style
, const wxPoint
& pos
)
127 : wxFileDialogBase(parent
, message
, defaultDir
, defaultFileName
,
128 wildCard
, style
, pos
)
130 m_needParent
= FALSE
;
132 if (!PreCreation(parent
, pos
, wxDefaultSize
) ||
133 !CreateBase(parent
, wxID_ANY
, pos
, wxDefaultSize
, style
,
134 wxDefaultValidator
, wxT("filedialog")))
136 wxFAIL_MSG( wxT("wxFileDialog creation failed") );
140 bool multiple
= (style
& wxMULTIPLE
) == wxMULTIPLE
;
141 GtkFileChooserAction gtk_action
;
142 GtkWindow
* gtk_parent
= NULL
;
144 gtk_parent
= GTK_WINDOW(parent
->m_widget
);
147 if ((style
& wxSAVE
) == wxSAVE
)
149 gtk_action
= GTK_FILE_CHOOSER_ACTION_SAVE
;
150 ok_btn_stock
= GTK_STOCK_SAVE
;
154 gtk_action
= GTK_FILE_CHOOSER_ACTION_OPEN
;
155 ok_btn_stock
= GTK_STOCK_OPEN
;
157 m_widget
= gtk_file_chooser_dialog_new(
158 wxGTK_CONV(m_message
),
161 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
162 ok_btn_stock
, GTK_RESPONSE_ACCEPT
,
165 gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(m_widget
), multiple
);
167 gtk_signal_connect(GTK_OBJECT(m_widget
),
169 GTK_SIGNAL_FUNC(gtk_filedialog_response_callback
),
173 if (!m_path
.empty() && m_path
.Last() != wxT('/'))
175 m_path
+= m_fileName
;
178 SetWildcard(wildCard
);
182 void wxFileDialog::SetPath(const wxString
& path
)
188 void wxFileDialog::GetFilenames(wxArrayString
& files
) const
191 for (size_t n
= 0; n
< files
.GetCount(); n
++ )
194 wxSplitPath(files
[n
], NULL
, &name
, &ext
);
203 void wxFileDialog::GetPaths(wxArrayString
& paths
) const
206 if (GetWindowStyle() & wxMULTIPLE
)
209 gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(m_widget
));
210 GSList
*gpaths
= gpathsi
;
213 wxString file
= wxGTK_CONV_BACK((gchar
*) gpathsi
->data
);
215 g_free(gpathsi
->data
);
216 gpathsi
= gpathsi
->next
;
219 g_slist_free(gpaths
);
223 paths
.Add(m_fileName
);
227 void wxFileDialog::SetMessage(const wxString
& message
)
233 void wxFileDialog::SetDirectory(const wxString
& dir
)
235 wxFileName
fn(dir
,m_fileName
);
236 SetPath(fn
.GetFullPath());
239 void wxFileDialog::SetFilename(const wxString
& name
)
242 wxFileName
fn(m_dir
,name
);
243 SetPath(fn
.GetFullPath());
246 void wxFileDialog::SetWildcard(const wxString
& wildCard
)
248 m_wildCard
= wildCard
;
250 GtkFileChooser
* chooser
= GTK_FILE_CHOOSER(m_widget
);
252 // empty current filter list:
253 GSList
* ifilters
= gtk_file_chooser_list_filters(chooser
);
254 GSList
* filters
= ifilters
;
257 gtk_file_chooser_remove_filter(chooser
,GTK_FILE_FILTER(ifilters
->data
));
258 ifilters
= ifilters
->next
;
260 g_slist_free(filters
);
263 wxArrayString wildDescriptions
, wildFilters
;
264 if (!wxParseCommonDialogsFilter(m_wildCard
, wildDescriptions
, wildFilters
))
266 wxFAIL_MSG( wxT("Wrong file type description") );
270 // add parsed to GtkChooser
271 for (size_t n
= 0; n
< wildFilters
.GetCount(); n
++)
273 GtkFileFilter
* filter
= gtk_file_filter_new();
274 gtk_file_filter_set_name(filter
,wxGTK_CONV(wildDescriptions
[n
]));
275 wxString after
= wildFilters
[n
];
278 wxString ext
= after
.BeforeFirst(wxT(';'));
279 gtk_file_filter_add_pattern(filter
,wxGTK_CONV(ext
));
280 if (after
.Find(wxT(';')) == wxNOT_FOUND
)
282 after
= after
.AfterLast(wxT(';'));
284 while (!after
.empty());
286 gtk_file_chooser_add_filter(chooser
, filter
);
291 void wxFileDialog::SetFilterIndex(int filterIndex
)
293 m_filterIndex
= filterIndex
;
295 GtkFileChooser
*chooser
= GTK_FILE_CHOOSER(m_widget
);
296 GSList
*fnode
= gtk_file_chooser_list_filters(chooser
);
297 GSList
*filters
= fnode
;
301 if (i
== filterIndex
)
303 gtk_file_chooser_set_filter(chooser
, GTK_FILE_FILTER(fnode
->data
));
310 g_slist_free(filters
);
313 void wxFileDialog::UpdateFromDialog()
315 // update filterIndex
316 GSList
*fnode
= gtk_file_chooser_list_filters(GTK_FILE_CHOOSER(m_widget
));
317 GSList
*filters
= fnode
;
318 GtkFileFilter
*current
=
319 gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(m_widget
));
325 if (fnode
->data
== (gpointer
)current
)
333 g_slist_free(filters
);
336 void wxFileDialog::UpdateDialog()
339 if (wxDirExists(m_path
))
341 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(m_widget
),
346 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(m_widget
),
349 // pre-fill the filename, too:
350 if (GetWindowStyle() & wxSAVE
)
352 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(m_widget
),
353 wxGTK_CONV(m_fileName
));
358 void wxFileDialog::DoSetPath(const wxString
& path
)
364 m_path
= fn
.GetFullPath();
367 wxSplitPath(path
, &m_dir
, &m_fileName
, &ext
);
370 m_fileName
+= wxT(".");
380 #endif // wxUSE_FILEDLG && defined(__WXGTK24__)