]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/filedlg.cpp
renamed Render's argument to not obfuscate its meaning
[wxWidgets.git] / src / gtk1 / filedlg.cpp
CommitLineData
c801d85f 1/////////////////////////////////////////////////////////////////////////////
3f6638b8 2// Name: gtk/filedlg.cpp
9755e73b
VS
3// Purpose: native implementation of wxFileDialog
4// Author: Robert Roebling, Zbigniew Zagorski
a81258be 5// Id: $Id$
9755e73b 6// Copyright: (c) 1998 Robert Roebling, 2004 Zbigniew Zagorski
65571936 7// Licence: wxWindows licence
c801d85f
KB
8/////////////////////////////////////////////////////////////////////////////
9
14f355c2 10#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
c801d85f
KB
11#pragma implementation "filedlg.h"
12#endif
13
14f355c2
VS
14// For compilers that support precompilation, includes "wx.h".
15#include "wx/wxprec.h"
16
9755e73b
VS
17#if wxUSE_FILEDLG && defined(__WXGTK24__)
18
c801d85f
KB
19#include "wx/filedlg.h"
20#include "wx/utils.h"
21#include "wx/intl.h"
9755e73b 22#include "wx/filename.h"
f3613896 23#include "wx/msgdlg.h"
c801d85f 24
071a2d78 25#include <gtk/gtk.h>
9755e73b 26#include "wx/gtk/private.h"
83624f79 27
acfd422a
RR
28//-----------------------------------------------------------------------------
29// idle system
30//-----------------------------------------------------------------------------
31
32extern void wxapp_install_idle_handler();
33extern bool g_isIdle;
34
291a8f20
RR
35//-----------------------------------------------------------------------------
36// "clicked" for OK-button
c801d85f
KB
37//-----------------------------------------------------------------------------
38
9755e73b 39static void gtk_filedialog_ok_callback(GtkWidget *widget, wxFileDialog *dialog)
c801d85f 40{
2748d251 41 int style = dialog->GetStyle();
9755e73b
VS
42 gchar* text = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(widget));
43 wxString filename(wxGTK_CONV_BACK(text));
035b704a 44
9755e73b 45 if ((style & wxSAVE) && (style & wxOVERWRITE_PROMPT))
bfc6fde4 46 {
9755e73b 47 if (wxFileExists(filename))
0e1399b3
VZ
48 {
49 wxString msg;
9755e73b
VS
50 msg.Printf(
51 _("File '%s' already exists, do you really want to overwrite it?"),
52 filename.c_str());
0e1399b3 53
9755e73b
VS
54 wxMessageDialog dlg(dialog, msg, _("Confirm"),
55 wxYES_NO | wxICON_QUESTION);
56 if (dlg.ShowModal() != wxID_YES)
0e1399b3
VZ
57 return;
58 }
83624f79 59 }
9755e73b 60 else if ((style & wxOPEN) && ( style & wxFILE_MUST_EXIST))
bfc6fde4 61 {
9755e73b 62 if (!wxFileExists( filename ))
bfc6fde4 63 {
9755e73b
VS
64 wxMessageDialog dlg(dialog,
65 _("Please choose an existing file."),
66 _("Error"), wxOK | wxICON_ERROR);
67 dlg.ShowModal();
bfc6fde4
VZ
68
69 return;
70 }
71 }
035b704a 72
3f6638b8 73 // change to the directory where the user went if asked
9755e73b 74 if (style & wxCHANGE_DIR)
3f6638b8
VZ
75 {
76 wxString cwd;
77 wxSplitPath(filename, &cwd, NULL, NULL);
78
9755e73b 79 if (cwd != wxGetCwd())
3f6638b8
VZ
80 {
81 wxSetWorkingDirectory(cwd);
82 }
83 }
84
9755e73b
VS
85 dialog->DoSetPath(filename);
86 dialog->UpdateFromDialog();
87
bfc6fde4 88 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK);
9755e73b
VS
89 event.SetEventObject(dialog);
90 dialog->GetEventHandler()->ProcessEvent(event);
ff7b1510 91}
c801d85f 92
291a8f20
RR
93//-----------------------------------------------------------------------------
94// "clicked" for Cancel-button
95//-----------------------------------------------------------------------------
96
9755e73b
VS
97static void gtk_filedialog_cancel_callback(GtkWidget *WXUNUSED(w),
98 wxFileDialog *dialog)
c801d85f 99{
bfc6fde4 100 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
9755e73b
VS
101 event.SetEventObject(dialog);
102 dialog->GetEventHandler()->ProcessEvent(event);
103}
104
105static void gtk_filedialog_response_callback(GtkWidget *w,
106 int response,
107 wxFileDialog *dialog)
108{
109 wxapp_install_idle_handler();
110
111 if (response == GTK_RESPONSE_CANCEL)
112 gtk_filedialog_cancel_callback(w, dialog);
113 else
114 gtk_filedialog_ok_callback(w, dialog);
ff7b1510 115}
c801d85f 116
291a8f20
RR
117//-----------------------------------------------------------------------------
118// wxFileDialog
119//-----------------------------------------------------------------------------
120
f74172ab 121IMPLEMENT_DYNAMIC_CLASS(wxFileDialog,wxFileDialogBase)
c801d85f 122
9755e73b
VS
123wxFileDialog::wxFileDialog(wxWindow *parent, const wxString& message,
124 const wxString& defaultDir,
125 const wxString& defaultFileName,
126 const wxString& wildCard,
127 long style, const wxPoint& pos)
128 : wxFileDialogBase(parent, message, defaultDir, defaultFileName,
129 wildCard, style, pos)
c801d85f 130{
83624f79
RR
131 m_needParent = FALSE;
132
9755e73b
VS
133 if (!PreCreation(parent, pos, wxDefaultSize) ||
134 !CreateBase(parent, wxID_ANY, pos, wxDefaultSize, style,
135 wxDefaultValidator, wxT("filedialog")))
4dcaf11a 136 {
9755e73b 137 wxFAIL_MSG( wxT("wxFileDialog creation failed") );
3f6638b8 138 return;
4dcaf11a 139 }
3f6638b8 140
9755e73b
VS
141 bool multiple = (style & wxMULTIPLE) == wxMULTIPLE;
142 GtkFileChooserAction gtk_action;
143 GtkWindow* gtk_parent = NULL;
144 if (parent)
145 gtk_parent = GTK_WINDOW(parent->m_widget);
146
147 gchar* ok_btn_stock;
148 if ((style & wxSAVE) == wxSAVE)
149 {
150 gtk_action = GTK_FILE_CHOOSER_ACTION_SAVE;
151 ok_btn_stock = GTK_STOCK_SAVE;
152 }
153 else
154 {
155 gtk_action = GTK_FILE_CHOOSER_ACTION_OPEN;
156 ok_btn_stock = GTK_STOCK_OPEN;
157 }
158 m_widget = gtk_file_chooser_dialog_new(
159 wxGTK_CONV(m_message),
160 gtk_parent,
161 gtk_action,
162 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
163 ok_btn_stock, GTK_RESPONSE_ACCEPT,
164 NULL);
165
166 gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(m_widget), multiple);
167
168 gtk_signal_connect(GTK_OBJECT(m_widget),
169 "response",
170 GTK_SIGNAL_FUNC(gtk_filedialog_response_callback),
171 (gpointer*)this);
172
173 m_path = m_dir;
174 if (!m_path.empty() && m_path.Last() != wxT('/'))
175 m_path += wxT('/');
176 m_path += m_fileName;
177 SetPath(m_path);
178
179 SetWildcard(wildCard);
180 SetFilterIndex(0);
181}
0e1399b3 182
9755e73b
VS
183void wxFileDialog::SetPath(const wxString& path)
184{
185 DoSetPath(path);
186 UpdateDialog();
187}
0e1399b3 188
9755e73b
VS
189void wxFileDialog::GetFilenames(wxArrayString& files) const
190{
191 GetPaths(files);
192 for (size_t n = 0; n < files.GetCount(); n++ )
193 {
194 wxString name,ext;
195 wxSplitPath(files[n], NULL, &name, &ext);
196 if (!ext.IsEmpty())
197 {
198 name += wxT(".");
199 name += ext;
200 }
201 files[n] = name;
202 }
203}
204void wxFileDialog::GetPaths(wxArrayString& paths) const
205{
206 paths.Empty();
207 if (GetWindowStyle() & wxMULTIPLE)
208 {
209 GSList *gpathsi =
210 gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(m_widget));
211 GSList *gpaths = gpathsi;
212 while (gpathsi)
213 {
214 wxString file = wxGTK_CONV_BACK((gchar*) gpathsi->data);
215 paths.Add(file);
216 g_free(gpathsi->data);
217 gpathsi = gpathsi->next;
218 }
219 if (gpaths)
220 g_slist_free(gpaths);
221 }
222 else
223 {
224 paths.Add(m_fileName);
225 }
226}
035b704a 227
9755e73b
VS
228void wxFileDialog::SetMessage(const wxString& message)
229{
230 m_message = message;
231 SetTitle(message);
232}
233
234void wxFileDialog::SetDirectory(const wxString& dir)
235{
236 wxFileName fn(dir,m_fileName);
237 SetPath(fn.GetFullPath());
238}
239
240void wxFileDialog::SetFilename(const wxString& name)
241{
242 m_fileName = name;
243 wxFileName fn(m_dir,name);
244 SetPath(fn.GetFullPath());
245}
035b704a 246
9755e73b
VS
247void wxFileDialog::SetWildcard(const wxString& wildCard)
248{
249 m_wildCard = wildCard;
250
251 GtkFileChooser* chooser = GTK_FILE_CHOOSER(m_widget);
252
253 // empty current filter list:
254 GSList* ifilters = gtk_file_chooser_list_filters(chooser);
255 GSList* filters = ifilters;
256 while (ifilters)
257 {
258 gtk_file_chooser_remove_filter(chooser,GTK_FILE_FILTER(ifilters->data));
259 ifilters = ifilters->next;
260 }
261 g_slist_free(filters);
262
263 // parse filters
264 wxArrayString wildDescriptions, wildFilters;
265 if (!wxParseCommonDialogsFilter(m_wildCard, wildDescriptions, wildFilters))
266 {
267 wxFAIL_MSG( wxT("Wrong file type description") );
268 }
269 else
270 {
271 // add parsed to GtkChooser
272 for (size_t n = 0; n < wildFilters.GetCount(); n++)
273 {
274 GtkFileFilter* filter = gtk_file_filter_new();
275 gtk_file_filter_set_name(filter,wxGTK_CONV(wildDescriptions[n]));
276 wxString after = wildFilters[n];
277 do
278 {
279 wxString ext = after.BeforeFirst(wxT(';'));
280 gtk_file_filter_add_pattern(filter,wxGTK_CONV(ext));
281 if (after.Find(wxT(';')) == wxNOT_FOUND)
282 break;
283 after = after.AfterLast(wxT(';'));
284 }
285 while (!after.empty());
286
287 gtk_file_chooser_add_filter(chooser, filter);
288 }
289 }
290}
a3622daa 291
9755e73b
VS
292void wxFileDialog::SetFilterIndex(int filterIndex)
293{
294 m_filterIndex = filterIndex;
c801d85f 295
9755e73b
VS
296 GtkFileChooser *chooser = GTK_FILE_CHOOSER(m_widget);
297 GSList *fnode = gtk_file_chooser_list_filters(chooser);
298 GSList *filters = fnode;
299 int i = 0;
300 while (fnode)
301 {
302 if (i == filterIndex)
303 {
304 gtk_file_chooser_set_filter(chooser, GTK_FILE_FILTER(fnode->data));
305 m_filterIndex = i;
306 break;
307 }
308 i++;
309 fnode = fnode->next;
310 }
311 g_slist_free(filters);
312}
3502e687 313
9755e73b
VS
314void wxFileDialog::UpdateFromDialog()
315{
316 // update filterIndex
317 GSList *fnode = gtk_file_chooser_list_filters(GTK_FILE_CHOOSER(m_widget));
318 GSList *filters = fnode;
319 GtkFileFilter *current =
320 gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(m_widget));
321
322 int i = 0;
323 m_filterIndex = 0;
324 while (fnode)
325 {
326 if (fnode->data == (gpointer)current)
327 {
328 m_filterIndex = i;
329 break;
330 }
331 i++;
332 fnode = fnode->next;
333 }
334 g_slist_free(filters);
335}
3f6638b8 336
9755e73b
VS
337void wxFileDialog::UpdateDialog()
338{
339
340 if (wxDirExists(m_path))
341 {
342 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(m_widget),
343 wxGTK_CONV(m_path));
344 }
345 else
346 {
347 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(m_widget),
348 wxGTK_CONV(m_path));
3f6638b8 349
9755e73b
VS
350 // pre-fill the filename, too:
351 if (GetWindowStyle() & wxSAVE)
352 {
353 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(m_widget),
354 wxGTK_CONV(m_fileName));
355 }
356 }
ff7b1510 357}
c801d85f 358
9755e73b 359void wxFileDialog::DoSetPath(const wxString& path)
3218cf58 360{
9755e73b 361 if (!path.empty())
3218cf58 362 {
9755e73b
VS
363 wxFileName fn(path);
364 fn.MakeAbsolute();
365 m_path = fn.GetFullPath();
366
3218cf58
VZ
367 wxString ext;
368 wxSplitPath(path, &m_dir, &m_fileName, &ext);
9755e73b 369 if (!ext.empty())
3f6638b8
VZ
370 {
371 m_fileName += wxT(".");
53daeada 372 m_fileName += ext;
3f6638b8 373 }
3218cf58 374 }
9755e73b
VS
375 else
376 {
377 m_path = path;
378 }
3218cf58
VZ
379}
380
9755e73b 381#endif // wxUSE_FILEDLG && defined(__WXGTK24__)