Statistics
| Revision:

root / src / filesel.c @ 3070

History | View | Annotate | Download (8.8 kB)

1 1 hiro
/*
2 1 hiro
 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 3043 hiro
 * Copyright (C) 1999-2012 Hiroyuki Yamamoto
4 1 hiro
 *
5 1 hiro
 * This program is free software; you can redistribute it and/or modify
6 1 hiro
 * it under the terms of the GNU General Public License as published by
7 1 hiro
 * the Free Software Foundation; either version 2 of the License, or
8 1 hiro
 * (at your option) any later version.
9 1 hiro
 *
10 1 hiro
 * This program is distributed in the hope that it will be useful,
11 1 hiro
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 1 hiro
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 1 hiro
 * GNU General Public License for more details.
14 1 hiro
 *
15 1 hiro
 * You should have received a copy of the GNU General Public License
16 1 hiro
 * along with this program; if not, write to the Free Software
17 1 hiro
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 1 hiro
 */
19 1 hiro
20 1 hiro
#include <glib.h>
21 128 hiro
#include <glib/gi18n.h>
22 1 hiro
#include <gdk/gdkkeysyms.h>
23 1621 hiro
#include <gtk/gtkversion.h>
24 128 hiro
#include <gtk/gtkfilechooserdialog.h>
25 176 hiro
#include <gtk/gtkexpander.h>
26 128 hiro
#include <gtk/gtkstock.h>
27 1 hiro
28 1 hiro
#include "main.h"
29 1 hiro
#include "filesel.h"
30 1 hiro
#include "manage_window.h"
31 128 hiro
#include "alertpanel.h"
32 128 hiro
#include "utils.h"
33 422 hiro
#include "prefs_common.h"
34 1741 hiro
#include "inc.h"
35 1 hiro
36 3043 hiro
37 156 hiro
static GSList *filesel_select_file_full        (const gchar                *title,
38 156 hiro
                                         const gchar                *file,
39 156 hiro
                                         GtkFileChooserAction         action,
40 156 hiro
                                         gboolean                 multiple);
41 1 hiro
42 156 hiro
static GtkWidget *filesel_create        (const gchar                *title,
43 156 hiro
                                         GtkFileChooserAction         action);
44 156 hiro
45 176 hiro
static void filesel_save_expander_set_expanded           (GtkWidget        *dialog,
46 176 hiro
                                                    gboolean         expanded);
47 176 hiro
static gboolean filesel_save_expander_get_expanded (GtkWidget        *dialog);
48 156 hiro
49 1622 hiro
#if GTK_CHECK_VERSION(2, 8, 0)
50 1622 hiro
static GtkFileChooserConfirmation filesel_confirm_overwrite_cb
51 1622 hiro
                                        (GtkFileChooser                *chooser,
52 1622 hiro
                                         gpointer                 data);
53 1622 hiro
#endif
54 1622 hiro
55 3043 hiro
56 128 hiro
gchar *filesel_select_file(const gchar *title, const gchar *file,
57 128 hiro
                           GtkFileChooserAction action)
58 1 hiro
{
59 156 hiro
        GSList *list;
60 156 hiro
        gchar *selected = NULL;
61 156 hiro
62 156 hiro
        list = filesel_select_file_full(title, file, action, FALSE);
63 156 hiro
        if (list) {
64 156 hiro
                selected = (gchar *)list->data;
65 156 hiro
                slist_free_strings(list->next);
66 156 hiro
        }
67 156 hiro
        g_slist_free(list);
68 156 hiro
69 156 hiro
        return selected;
70 156 hiro
}
71 156 hiro
72 156 hiro
GSList *filesel_select_files(const gchar *title, const gchar *file,
73 156 hiro
                             GtkFileChooserAction action)
74 156 hiro
{
75 156 hiro
        return filesel_select_file_full(title, file, action, TRUE);
76 156 hiro
}
77 156 hiro
78 3043 hiro
static void filesel_change_dir_for_action(GtkFileChooserAction action)
79 3043 hiro
{
80 3043 hiro
        const gchar *cwd = NULL;
81 3043 hiro
82 3043 hiro
        switch (action) {
83 3043 hiro
        case GTK_FILE_CHOOSER_ACTION_OPEN:
84 3043 hiro
                if (prefs_common.prev_open_dir &&
85 3043 hiro
                    is_dir_exist(prefs_common.prev_open_dir))
86 3043 hiro
                        cwd = prefs_common.prev_open_dir;
87 3043 hiro
                else {
88 3043 hiro
                        g_free(prefs_common.prev_open_dir);
89 3043 hiro
                        prefs_common.prev_open_dir = NULL;
90 3043 hiro
                }
91 3043 hiro
                break;
92 3043 hiro
        case GTK_FILE_CHOOSER_ACTION_SAVE:
93 3043 hiro
                if (prefs_common.prev_save_dir &&
94 3043 hiro
                    is_dir_exist(prefs_common.prev_save_dir))
95 3043 hiro
                        cwd = prefs_common.prev_save_dir;
96 3043 hiro
                else {
97 3043 hiro
                        g_free(prefs_common.prev_save_dir);
98 3043 hiro
                        prefs_common.prev_save_dir = NULL;
99 3043 hiro
                }
100 3043 hiro
                break;
101 3043 hiro
        case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER:
102 3043 hiro
                if (prefs_common.prev_folder_dir &&
103 3043 hiro
                    is_dir_exist(prefs_common.prev_folder_dir))
104 3043 hiro
                        cwd = prefs_common.prev_folder_dir;
105 3043 hiro
                else {
106 3043 hiro
                        g_free(prefs_common.prev_folder_dir);
107 3043 hiro
                        prefs_common.prev_folder_dir = NULL;
108 3043 hiro
                }
109 3043 hiro
                break;
110 3043 hiro
        default:
111 3043 hiro
                break;
112 3043 hiro
        }
113 3043 hiro
114 3043 hiro
        if (cwd)
115 3043 hiro
                change_dir(cwd);
116 3043 hiro
        else
117 3043 hiro
                change_dir(get_document_dir());
118 3043 hiro
}
119 3043 hiro
120 3043 hiro
static void filesel_save_dir_for_action(GtkFileChooserAction action,
121 3043 hiro
                                        const gchar *cwd)
122 3043 hiro
{
123 3043 hiro
        switch (action) {
124 3043 hiro
        case GTK_FILE_CHOOSER_ACTION_OPEN:
125 3043 hiro
                g_free(prefs_common.prev_open_dir);
126 3043 hiro
                prefs_common.prev_open_dir = g_strdup(cwd);
127 3043 hiro
                break;
128 3043 hiro
        case GTK_FILE_CHOOSER_ACTION_SAVE:
129 3043 hiro
                g_free(prefs_common.prev_save_dir);
130 3043 hiro
                prefs_common.prev_save_dir = g_strdup(cwd);
131 3043 hiro
                break;
132 3043 hiro
        case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER:
133 3043 hiro
                g_free(prefs_common.prev_folder_dir);
134 3043 hiro
                prefs_common.prev_folder_dir = g_strdup(cwd);
135 3043 hiro
                break;
136 3043 hiro
        default:
137 3043 hiro
                break;
138 3043 hiro
        }
139 3043 hiro
}
140 3043 hiro
141 156 hiro
static GSList *filesel_select_file_full(const gchar *title, const gchar *file,
142 156 hiro
                                        GtkFileChooserAction action,
143 156 hiro
                                        gboolean multiple)
144 156 hiro
{
145 165 hiro
        gchar *cwd;
146 128 hiro
        GtkWidget *dialog;
147 135 hiro
        gchar *prev_dir;
148 176 hiro
        static gboolean save_expander_expanded = FALSE;
149 156 hiro
        GSList *list = NULL;
150 1 hiro
151 135 hiro
        prev_dir = g_get_current_dir();
152 135 hiro
153 3043 hiro
        filesel_change_dir_for_action(action);
154 165 hiro
155 128 hiro
        dialog = filesel_create(title, action);
156 1 hiro
157 128 hiro
        manage_window_set_transient(GTK_WINDOW(dialog));
158 1 hiro
159 128 hiro
        if (file)
160 128 hiro
                gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog),
161 128 hiro
                                                  file);
162 1 hiro
163 156 hiro
        gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog),
164 156 hiro
                                             multiple);
165 156 hiro
166 176 hiro
        if (action == GTK_FILE_CHOOSER_ACTION_SAVE && save_expander_expanded) {
167 176 hiro
                filesel_save_expander_set_expanded
168 176 hiro
                        (dialog, save_expander_expanded);
169 176 hiro
        }
170 176 hiro
171 1621 hiro
#if GTK_CHECK_VERSION(2, 8, 0)
172 1621 hiro
        if (action == GTK_FILE_CHOOSER_ACTION_SAVE) {
173 1621 hiro
                gtk_file_chooser_set_do_overwrite_confirmation
174 1621 hiro
                        (GTK_FILE_CHOOSER(dialog), TRUE);
175 1622 hiro
                g_signal_connect(GTK_FILE_CHOOSER(dialog), "confirm-overwrite",
176 1622 hiro
                                 G_CALLBACK(filesel_confirm_overwrite_cb),
177 1622 hiro
                                 NULL);
178 1621 hiro
        }
179 1621 hiro
#endif
180 1621 hiro
181 128 hiro
        gtk_widget_show(dialog);
182 99 hiro
183 841 hiro
        change_dir(prev_dir);
184 841 hiro
        g_free(prev_dir);
185 841 hiro
186 1741 hiro
        inc_lock();
187 1741 hiro
188 128 hiro
        if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
189 156 hiro
                list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog));
190 156 hiro
                if (list) {
191 156 hiro
                        cwd = gtk_file_chooser_get_current_folder
192 156 hiro
                                (GTK_FILE_CHOOSER(dialog));
193 3043 hiro
                        if (cwd) {
194 3043 hiro
                                filesel_save_dir_for_action(action, cwd);
195 3043 hiro
                                g_free(cwd);
196 3043 hiro
                        }
197 128 hiro
                }
198 1 hiro
        }
199 1 hiro
200 1741 hiro
        inc_unlock();
201 1741 hiro
202 176 hiro
        if (action == GTK_FILE_CHOOSER_ACTION_SAVE)
203 176 hiro
                save_expander_expanded =
204 176 hiro
                        filesel_save_expander_get_expanded(dialog);
205 176 hiro
206 128 hiro
        manage_window_focus_out(dialog, NULL, NULL);
207 128 hiro
        gtk_widget_destroy(dialog);
208 1 hiro
209 156 hiro
        return list;
210 128 hiro
}
211 1 hiro
212 128 hiro
gchar *filesel_save_as(const gchar *file)
213 128 hiro
{
214 128 hiro
        gchar *filename;
215 1 hiro
216 128 hiro
        filename = filesel_select_file(_("Save as"), file,
217 128 hiro
                                       GTK_FILE_CHOOSER_ACTION_SAVE);
218 1 hiro
219 1621 hiro
#if !GTK_CHECK_VERSION(2, 8, 0)
220 128 hiro
        if (filename && is_file_exist(filename)) {
221 128 hiro
                AlertValue aval;
222 1 hiro
223 1622 hiro
                aval = alertpanel(_("Overwrite existing file"),
224 1622 hiro
                                  _("The file already exists. Do you want to replace it?"),
225 1623 hiro
                                  GTK_STOCK_YES, GTK_STOCK_NO, NULL);
226 128 hiro
                if (G_ALERTDEFAULT != aval) {
227 128 hiro
                        g_free(filename);
228 128 hiro
                        filename = NULL;
229 1 hiro
                }
230 1 hiro
        }
231 1621 hiro
#endif
232 1 hiro
233 1 hiro
        return filename;
234 1 hiro
}
235 1 hiro
236 601 hiro
gchar *filesel_select_dir(const gchar *dir)
237 601 hiro
{
238 601 hiro
        GSList *list;
239 601 hiro
        gchar *selected = NULL;
240 601 hiro
241 2399 hiro
        list = filesel_select_file_full(_("Select folder"), dir,
242 601 hiro
                                        GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
243 601 hiro
                                        FALSE);
244 601 hiro
        if (list) {
245 601 hiro
                selected = (gchar *)list->data;
246 601 hiro
                slist_free_strings(list->next);
247 601 hiro
        }
248 601 hiro
        g_slist_free(list);
249 601 hiro
250 601 hiro
        return selected;
251 601 hiro
}
252 601 hiro
253 128 hiro
static GtkWidget *filesel_create(const gchar *title,
254 128 hiro
                                 GtkFileChooserAction action)
255 1 hiro
{
256 128 hiro
        GtkWidget *dialog;
257 1 hiro
258 422 hiro
        if (prefs_common.comply_gnome_hig)
259 422 hiro
                dialog = gtk_file_chooser_dialog_new
260 422 hiro
                        (title, NULL, action,
261 422 hiro
                         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
262 601 hiro
                         (action == GTK_FILE_CHOOSER_ACTION_SAVE ||
263 601 hiro
                          action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
264 601 hiro
                         ? GTK_STOCK_SAVE : GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
265 422 hiro
                         NULL);
266 422 hiro
        else
267 422 hiro
                dialog = gtk_file_chooser_dialog_new
268 422 hiro
                        (title, NULL, action,
269 601 hiro
                         (action == GTK_FILE_CHOOSER_ACTION_SAVE ||
270 601 hiro
                          action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
271 601 hiro
                         ? GTK_STOCK_SAVE : GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
272 422 hiro
                         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
273 422 hiro
                         NULL);
274 915 hiro
        gtk_window_set_position(GTK_WINDOW(dialog),
275 915 hiro
                                GTK_WIN_POS_CENTER_ON_PARENT);
276 128 hiro
        gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
277 128 hiro
        gtk_window_set_wmclass
278 128 hiro
                (GTK_WINDOW(dialog), "file_selection", "Sylpheed");
279 165 hiro
        gtk_dialog_set_default_response
280 165 hiro
                (GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
281 1 hiro
282 128 hiro
        MANAGE_WINDOW_SIGNALS_CONNECT(dialog);
283 1 hiro
284 128 hiro
        return dialog;
285 1 hiro
}
286 176 hiro
287 176 hiro
static void container_foreach_cb(GtkWidget *widget, gpointer data)
288 176 hiro
{
289 176 hiro
        GtkWidget **expander = (GtkWidget **)data;
290 176 hiro
291 176 hiro
        if (*expander == NULL) {
292 176 hiro
                if (GTK_IS_EXPANDER(widget))
293 176 hiro
                        *expander = widget;
294 176 hiro
                else if (GTK_IS_CONTAINER(widget))
295 176 hiro
                        gtk_container_foreach(GTK_CONTAINER(widget),
296 176 hiro
                                              container_foreach_cb, data);
297 176 hiro
        }
298 176 hiro
}
299 176 hiro
300 176 hiro
static void filesel_save_expander_set_expanded(GtkWidget *dialog,
301 176 hiro
                                               gboolean expanded)
302 176 hiro
{
303 176 hiro
        GtkWidget *expander = NULL;
304 176 hiro
305 176 hiro
        gtk_container_foreach(GTK_CONTAINER(dialog), container_foreach_cb,
306 176 hiro
                              &expander);
307 176 hiro
        if (expander)
308 176 hiro
                gtk_expander_set_expanded(GTK_EXPANDER(expander), expanded);
309 176 hiro
}
310 176 hiro
311 176 hiro
static gboolean filesel_save_expander_get_expanded(GtkWidget *dialog)
312 176 hiro
{
313 176 hiro
        GtkWidget *expander = NULL;
314 176 hiro
315 176 hiro
        gtk_container_foreach(GTK_CONTAINER(dialog), container_foreach_cb,
316 176 hiro
                              &expander);
317 176 hiro
        if (expander)
318 176 hiro
                return gtk_expander_get_expanded(GTK_EXPANDER(expander));
319 176 hiro
        else
320 176 hiro
                return FALSE;
321 176 hiro
}
322 1622 hiro
323 1622 hiro
#if GTK_CHECK_VERSION(2, 8, 0)
324 1622 hiro
static GtkFileChooserConfirmation filesel_confirm_overwrite_cb
325 1622 hiro
                                        (GtkFileChooser                *chooser,
326 1622 hiro
                                         gpointer                 data)
327 1622 hiro
{
328 1622 hiro
        gchar *filename;
329 1622 hiro
        GtkFileChooserConfirmation ret =
330 1622 hiro
                GTK_FILE_CHOOSER_CONFIRMATION_ACCEPT_FILENAME;
331 1622 hiro
332 1622 hiro
        filename = gtk_file_chooser_get_filename(chooser);
333 1622 hiro
334 1622 hiro
        if (filename && is_file_exist(filename)) {
335 1622 hiro
                AlertValue aval;
336 1622 hiro
337 1622 hiro
                aval = alertpanel(_("Overwrite existing file"),
338 1622 hiro
                                  _("The file already exists. Do you want to replace it?"),
339 1623 hiro
                                  GTK_STOCK_YES, GTK_STOCK_NO, NULL);
340 1622 hiro
                if (G_ALERTDEFAULT == aval)
341 1622 hiro
                        ret = GTK_FILE_CHOOSER_CONFIRMATION_ACCEPT_FILENAME;
342 1622 hiro
                else
343 1622 hiro
                        ret = GTK_FILE_CHOOSER_CONFIRMATION_SELECT_AGAIN;
344 1622 hiro
        }
345 1622 hiro
346 1622 hiro
        g_free(filename);
347 1622 hiro
348 1622 hiro
        return ret;
349 1622 hiro
}
350 1622 hiro
#endif