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