Statistics
| Revision:

root / src / filesel.c @ 1967

History | View | Annotate | Download (7.5 kB)

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