2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2004 Hiroyuki Yamamoto & the Sylpheed-Claws Team
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.
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.
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.
27 #include <glib/gi18n.h>
34 #include "folderview.h"
37 #include "alertpanel.h"
38 #include "foldersel.h"
39 #include "inputdialog.h"
42 #include "prefs_common.h"
43 #include "summaryview.h"
45 static void new_folder_cb(FolderView *folderview, guint action, GtkWidget *widget);
46 static void rename_folder_cb(FolderView *folderview, guint action, GtkWidget *widget);
47 static void move_folder_cb(FolderView *folderview, guint action, GtkWidget *widget);
48 static void imap_settings_cb(FolderView *folderview, guint action, GtkWidget *widget);
49 static void remove_server_cb(FolderView *folderview, guint action, GtkWidget *widget);
50 static void delete_folder_cb(FolderView *folderview, guint action, GtkWidget *widget);
51 static void update_tree_cb(FolderView *folderview, guint action, GtkWidget *widget);
52 static void download_cb(FolderView *folderview, guint action, GtkWidget *widget);
53 static void sync_cb(FolderView *folderview, guint action, GtkWidget *widget);
55 static GtkItemFactoryEntry imap_popup_entries[] =
57 {N_("/Create _new folder..."), NULL, new_folder_cb, 0, NULL},
58 {N_("/_Rename folder..."), NULL, rename_folder_cb, 0, NULL},
59 {N_("/M_ove folder..."), NULL, move_folder_cb, 0, NULL},
60 {N_("/_Delete folder"), NULL, delete_folder_cb, 0, NULL},
61 {N_("/---"), NULL, NULL, 0, "<Separator>"},
62 {N_("/Synchronise"), NULL, sync_cb, 0, NULL},
63 {N_("/Down_load messages"), NULL, download_cb, 0, NULL},
64 {N_("/---"), NULL, NULL, 0, "<Separator>"},
65 {N_("/_Check for new messages"), NULL, update_tree_cb, 0, NULL},
66 {N_("/R_ebuild folder tree"), NULL, update_tree_cb, 1, NULL},
67 {N_("/---"), NULL, NULL, 0, "<Separator>"},
68 {N_("/IMAP4 _account settings"), NULL, imap_settings_cb, 0, NULL},
69 {N_("/Remove _IMAP4 account"), NULL, remove_server_cb, 0, NULL},
70 {N_("/---"), NULL, NULL, 0, "<Separator>"},
73 static void set_sensitivity(GtkItemFactory *factory, FolderItem *item);
75 static FolderViewPopup imap_popup =
83 void imap_gtk_init(void)
87 n_entries = sizeof(imap_popup_entries) /
88 sizeof(imap_popup_entries[0]);
89 for (i = 0; i < n_entries; i++)
90 imap_popup.entries = g_slist_append(imap_popup.entries, &imap_popup_entries[i]);
92 folderview_register_popup(&imap_popup);
95 static void set_sensitivity(GtkItemFactory *factory, FolderItem *item)
97 gboolean folder_is_normal =
99 item->stype == F_NORMAL &&
100 !folder_has_parent_of_type(item, F_OUTBOX) &&
101 !folder_has_parent_of_type(item, F_DRAFT) &&
102 !folder_has_parent_of_type(item, F_QUEUE) &&
103 !folder_has_parent_of_type(item, F_TRASH);
104 #define SET_SENS(name, sens) \
105 menu_set_sensitive(factory, name, sens)
107 SET_SENS("/Create new folder...", TRUE);
108 SET_SENS("/Rename folder...", item->stype == F_NORMAL && folder_item_parent(item) != NULL);
109 SET_SENS("/Move folder...", folder_is_normal && folder_item_parent(item) != NULL);
110 SET_SENS("/Delete folder", item->stype == F_NORMAL && folder_item_parent(item) != NULL);
112 SET_SENS("/Check for new messages", folder_item_parent(item) == NULL);
113 SET_SENS("/Rebuild folder tree", folder_item_parent(item) == NULL);
115 SET_SENS("/Remove IMAP4 account", folder_item_parent(item) == NULL);
120 static void new_folder_cb(FolderView *folderview, guint action,
123 GtkCTree *ctree = GTK_CTREE(folderview->ctree);
125 FolderItem *new_item;
130 if (!folderview->selected) return;
132 item = gtk_ctree_node_get_row_data(ctree, folderview->selected);
133 g_return_if_fail(item != NULL);
134 g_return_if_fail(item->folder != NULL);
135 g_return_if_fail(item->folder->account != NULL);
137 new_folder = input_dialog
139 _("Input the name of new folder:\n"
140 "(if you want to create a folder to store subfolders,\n"
141 " append '/' at the end of the name)"),
143 if (!new_folder) return;
144 AUTORELEASE_STR(new_folder, {g_free(new_folder); return;});
146 p = strchr(new_folder, G_DIR_SEPARATOR);
147 if (p && *(p + 1) != '\0') {
148 alertpanel_error(_("'%c' can't be included in folder name."),
153 name = trim_string(new_folder, 32);
154 AUTORELEASE_STR(name, {g_free(name); return;});
156 /* find whether the directory already exists */
157 if (folder_find_child_item_by_name(item, new_folder)) {
158 alertpanel_error(_("The folder '%s' already exists."), name);
162 new_item = folder_create_folder(item, new_folder);
164 alertpanel_error(_("Can't create the folder '%s'."), name);
170 static void rename_folder_cb(FolderView *folderview, guint action,
182 item = folderview_get_selected_item(folderview);
183 g_return_if_fail(item != NULL);
184 g_return_if_fail(item->path != NULL);
185 g_return_if_fail(item->folder != NULL);
187 name = trim_string(item->name, 32);
188 message = g_strdup_printf(_("Input new name for '%s':"), name);
189 base = g_path_get_basename(item->path);
190 new_folder = input_dialog(_("Rename folder"), message, base);
194 if (!new_folder) return;
195 AUTORELEASE_STR(new_folder, {g_free(new_folder); return;});
198 TODO: check new name for IMAP namespace separator
199 if (strchr(new_folder, G_DIR_SEPARATOR) != NULL) {
200 alertpanel_error(_("`%c' can't be included in folder name."),
205 if (folder_find_child_item_by_name(folder_item_parent(item), new_folder)) {
206 name = trim_string(new_folder, 32);
207 alertpanel_error(_("The folder '%s' already exists."), name);
212 Xstrdup_a(old_path, item->path, {g_free(new_folder); return;});
214 old_id = folder_item_get_identifier(item);
216 if (folder_item_rename(item, new_folder) < 0) {
217 alertpanel_error(_("The folder could not be renamed.\n"
218 "The new folder name is not allowed."));
223 /* if (FOLDER_TYPE(item->folder) == F_MH)
224 prefs_filtering_rename_path(old_path, item->path); */
225 new_id = folder_item_get_identifier(item);
226 prefs_filtering_rename_path(old_id, new_id);
231 folder_item_prefs_save_config(item);
235 static void move_folder_cb(FolderView *folderview, guint action, GtkWidget *widget)
237 FolderItem *from_folder = NULL, *to_folder = NULL;
239 from_folder = folderview_get_selected_item(folderview);
240 if (!from_folder || from_folder->folder->klass != imap_get_class())
243 to_folder = foldersel_folder_sel(from_folder->folder, FOLDER_SEL_MOVE, NULL);
247 folderview_move_folder(folderview, from_folder, to_folder);
250 static void imap_settings_cb(FolderView *folderview, guint action, GtkWidget *widget)
254 item = folderview_get_selected_item(folderview);
258 account_open(item->folder->account);
261 static void remove_server_cb(FolderView *folderview, guint action, GtkWidget *widget)
263 GtkCTree *ctree = GTK_CTREE(folderview->ctree);
265 PrefsAccount *account;
270 if (!folderview->selected) return;
272 item = gtk_ctree_node_get_row_data(ctree, folderview->selected);
273 g_return_if_fail(item != NULL);
274 g_return_if_fail(item->folder != NULL);
275 g_return_if_fail(item->folder->account != NULL);
277 name = trim_string(item->folder->name, 32);
278 message = g_strdup_printf(_("Really delete IMAP4 account '%s'?"), name);
279 avalue = alertpanel_full(_("Delete IMAP4 account"), message,
280 GTK_STOCK_YES, GTK_STOCK_NO, NULL, FALSE,
281 NULL, ALERT_WARNING, G_ALERTALTERNATE);
285 if (avalue != G_ALERTDEFAULT) return;
287 if (folderview->opened == folderview->selected ||
288 gtk_ctree_is_ancestor(ctree,
289 folderview->selected,
290 folderview->opened)) {
291 summary_clear_all(folderview->summaryview);
292 folderview->opened = NULL;
295 account = item->folder->account;
296 folderview_unselect(folderview);
297 summary_clear_all(folderview->summaryview);
298 folder_destroy(item->folder);
299 account_destroy(account);
301 main_window_reflect_prefs_all();
305 static void delete_folder_cb(FolderView *folderview, guint action,
308 GtkCTree *ctree = GTK_CTREE(folderview->ctree);
310 gchar *message, *name;
315 if (!folderview->selected) return;
317 item = gtk_ctree_node_get_row_data(ctree, folderview->selected);
318 g_return_if_fail(item != NULL);
319 g_return_if_fail(item->path != NULL);
320 g_return_if_fail(item->folder != NULL);
322 name = trim_string(item->name, 32);
323 AUTORELEASE_STR(name, {g_free(name); return;});
324 message = g_strdup_printf
325 (_("All folders and messages under '%s' will be permanently deleted. "
326 "Recovery will not be possible.\n\n"
327 "Do you really want to delete?"), name);
328 avalue = alertpanel_full(_("Delete folder"), message,
329 GTK_STOCK_YES, GTK_STOCK_NO, NULL, FALSE,
330 NULL, ALERT_WARNING, G_ALERTALTERNATE);
332 if (avalue != G_ALERTDEFAULT) return;
334 Xstrdup_a(old_path, item->path, return);
335 old_id = folder_item_get_identifier(item);
337 if (folderview->opened == folderview->selected ||
338 gtk_ctree_is_ancestor(ctree,
339 folderview->selected,
340 folderview->opened)) {
341 summary_clear_all(folderview->summaryview);
342 folderview->opened = NULL;
345 if (item->folder->klass->remove_folder(item->folder, item) < 0) {
346 folder_item_scan(item);
347 alertpanel_error(_("Can't remove the folder '%s'."), name);
354 prefs_filtering_delete_path(old_id);
359 static void update_tree_cb(FolderView *folderview, guint action,
364 item = folderview_get_selected_item(folderview);
365 g_return_if_fail(item != NULL);
367 summary_show(folderview->summaryview, NULL);
369 g_return_if_fail(item->folder != NULL);
372 folderview_check_new(item->folder);
374 folderview_rescan_tree(item->folder);
377 static void sync_cb(FolderView *folderview, guint action,
382 item = folderview_get_selected_item(folderview);
383 g_return_if_fail(item != NULL);
384 folder_synchronise(item->folder);
387 void imap_gtk_synchronise(FolderItem *item)
389 MainWindow *mainwin = mainwindow_get_mainwindow();
390 FolderView *folderview = mainwin->folderview;
392 g_return_if_fail(item != NULL);
393 g_return_if_fail(item->folder != NULL);
395 main_window_cursor_wait(mainwin);
397 main_window_lock(mainwin);
398 gtk_widget_set_sensitive(folderview->ctree, FALSE);
399 main_window_progress_on(mainwin);
401 if (folder_item_fetch_all_msg(item) < 0) {
404 name = trim_string(item->name, 32);
405 alertpanel_error(_("Error occurred while downloading messages in '%s'."), name);
408 folder_set_ui_func(item->folder, NULL, NULL);
409 main_window_progress_off(mainwin);
410 gtk_widget_set_sensitive(folderview->ctree, TRUE);
411 main_window_unlock(mainwin);
413 main_window_cursor_normal(mainwin);
416 static void download_cb(FolderView *folderview, guint action,
419 GtkCTree *ctree = GTK_CTREE(folderview->ctree);
422 if (!folderview->selected) return;
424 item = gtk_ctree_node_get_row_data(ctree, folderview->selected);
425 imap_gtk_synchronise(item);
428 gboolean imap_gtk_should_override(void)
430 static time_t overridden_yes = 0;
431 static time_t overridden_no = 0;
432 gboolean answer = TRUE;
434 if (prefs_common.work_offline) {
435 if (time(NULL) - overridden_yes < 600)
437 else if (time(NULL) - overridden_no < 600)
440 answer = (alertpanel(_("Offline warning"),
441 _("You're working offline. Override during 10 minutes?"),
442 GTK_STOCK_YES, GTK_STOCK_NO, NULL) == G_ALERTDEFAULT);
445 overridden_yes = time(NULL);
447 overridden_no = time(NULL);