2 * Claws Mail -- a GTK based, lightweight, and fast e-mail client
3 * Copyright (C) 2004-2022 the Claws Mail team
4 * Copyright (C) 2014-2015 Charles Lehner
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; withouNULL, t even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "claws-features.h"
27 #include <gdk/gdkkeysyms.h>
29 #include <glib/gi18n.h>
32 #include "gtk/gtkutils.h"
33 #include "gtk/combobox.h"
34 #include "gtk/inputdialog.h"
35 #include "gtk/manage_window.h"
36 #include "alertpanel.h"
40 #include "mainwindow.h"
41 #include "managesieve.h"
42 #include "sieve_editor.h"
43 #include "sieve_prefs.h"
44 #include "sieve_manager.h"
53 SieveManagerPage
*page
;
59 SieveManagerPage
*page
;
63 static void filter_got_load_error(SieveSession
*session
, gpointer data
);
64 static void account_changed(GtkWidget
*widget
, SieveManagerPage
*page
);
65 static void sieve_manager_close(GtkWidget
*widget
, SieveManagerPage
*page
);
66 static gboolean
sieve_manager_deleted(GtkWidget
*widget
, GdkEvent
*event
,
67 SieveManagerPage
*page
);
68 static void filter_set_active(SieveManagerPage
*page
, gchar
*filter_name
);
69 gboolean
filter_find_by_name (GtkTreeModel
*model
, GtkTreeIter
*iter
,
71 static void got_session_error(SieveSession
*session
, const gchar
*msg
,
72 SieveManagerPage
*page
);
74 static GSList
*manager_pages
= NULL
;
77 * Perform a command on all manager pages for a given session
79 #define manager_sessions_foreach(cur, session, page) \
80 for(cur = manager_pages; cur != NULL; cur = cur->next) \
81 if ((page = (SieveManagerPage *)cur->data) && \
82 page->active_session == session)
84 void sieve_managers_done()
86 GSList
*list
= manager_pages
;
88 g_slist_free_full(list
, (GDestroyNotify
)sieve_manager_done
);
91 static void filters_list_clear(SieveManagerPage
*page
)
93 GtkListStore
*list_store
= GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(page
->filters_list
)));
94 gtk_list_store_clear(list_store
);
95 page
->got_list
= FALSE
;
98 static void filters_list_delete_filter(SieveManagerPage
*page
, gchar
*name
)
101 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(page
->filters_list
));
103 if (!filter_find_by_name(model
, &iter
, name
))
106 gtk_list_store_remove(GTK_LIST_STORE(model
), &iter
);
110 static void filters_list_rename_filter(SieveManagerPage
*page
,
111 gchar
*name_old
, char *name_new
)
114 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(page
->filters_list
));
116 if (!filter_find_by_name(model
, &iter
, name_old
))
119 gtk_list_store_set(GTK_LIST_STORE(model
), &iter
,
120 FILTER_NAME
, name_new
,
124 static void filters_list_insert_filter(SieveManagerPage
*page
,
127 GtkListStore
*list_store
= GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(page
->filters_list
)));
130 gtk_list_store_append(list_store
, &iter
);
131 gtk_list_store_set(list_store
, &iter
,
132 FILTER_NAME
, filter
->name
,
133 FILTER_ACTIVE
, filter
->active
,
137 static gchar
*filters_list_get_selected_filter(GtkWidget
*list_view
)
139 GtkTreeSelection
*selector
;
144 selector
= gtk_tree_view_get_selection(GTK_TREE_VIEW(list_view
));
146 if (!gtk_tree_selection_get_selected(selector
, &model
, &iter
))
149 gtk_tree_model_get(model
, &iter
, FILTER_NAME
, &res
, -1);
154 static void filter_add(GtkWidget
*widget
, SieveManagerPage
*page
)
156 SieveSession
*session
= page
->active_session
;
157 SieveEditorPage
*editor
;
160 gchar
*filter_name
= input_dialog(_("Add Sieve script"),
161 _("Enter name for a new Sieve filter script."), "");
162 if (!filter_name
|| !filter_name
[0])
165 editor
= sieve_editor_get(session
, filter_name
);
167 /* TODO: show error that filter already exists */
168 sieve_editor_present(editor
);
170 sieve_editor_load(editor
,
171 (sieve_session_cb_fn
)filter_got_load_error
, page
);
173 editor
= sieve_editor_new(session
, filter_name
);
174 editor
->is_new
= TRUE
;
175 sieve_editor_show(editor
);
179 static void filter_got_load_error(SieveSession
*session
, gpointer data
)
181 SieveManagerPage
*page
= data
;
183 got_session_error(session
, _("Unable to get script contents"), page
);
186 static void filter_edit(GtkWidget
*widget
, SieveManagerPage
*page
)
188 SieveEditorPage
*editor
;
189 SieveSession
*session
= page
->active_session
;
195 filter_name
= filters_list_get_selected_filter(page
->filters_list
);
199 editor
= sieve_editor_get(session
, filter_name
);
201 sieve_editor_present(editor
);
204 editor
= sieve_editor_new(session
, filter_name
);
205 /* filter_name becomes ownership of newly created
206 * SieveEditorPage, so we do not need to free it here. */
207 sieve_editor_load(editor
,
208 (sieve_session_cb_fn
)filter_got_load_error
, page
);
212 static void filter_renamed(SieveSession
*session
, gboolean abort
,
213 gboolean success
, CommandDataRename
*data
)
215 SieveManagerPage
*page
= data
->page
;
219 } else if (!success
) {
220 got_session_error(session
, "Unable to rename script", page
);
222 manager_sessions_foreach(cur
, session
, page
) {
223 filters_list_rename_filter(page
, data
->name_old
,
227 g_free(data
->name_old
);
228 g_free(data
->name_new
);
232 static void filter_rename(GtkWidget
*widget
, SieveManagerPage
*page
)
234 CommandDataRename
*cmd_data
;
235 gchar
*name_old
, *name_new
;
236 SieveSession
*session
;
238 name_old
= filters_list_get_selected_filter(page
->filters_list
);
242 session
= page
->active_session
;
246 name_new
= input_dialog(_("Add Sieve script"),
247 _("Enter new name for the script."), name_old
);
251 cmd_data
= g_new(CommandDataRename
, 1);
252 cmd_data
->name_new
= name_new
;
253 cmd_data
->name_old
= name_old
;
254 cmd_data
->page
= page
;
255 sieve_session_rename_script(session
, name_old
, name_new
,
256 (sieve_session_data_cb_fn
)filter_renamed
, (gpointer
)cmd_data
);
259 static void filter_activated(SieveSession
*session
, gboolean abort
,
260 const gchar
*err
, CommandDataName
*cmd_data
)
262 SieveManagerPage
*page
= cmd_data
->page
;
267 got_session_error(session
, err
, page
);
269 manager_sessions_foreach(cur
, session
, page
) {
270 filter_set_active(page
, cmd_data
->filter_name
);
273 g_free(cmd_data
->filter_name
);
277 static void sieve_set_active_filter(SieveManagerPage
*page
, gchar
*filter_name
)
279 SieveSession
*session
;
280 CommandDataName
*cmd_data
;
282 session
= page
->active_session
;
283 cmd_data
= g_new(CommandDataName
, 1);
284 cmd_data
->filter_name
= filter_name
;
285 cmd_data
->page
= page
;
287 sieve_session_set_active_script(session
, filter_name
,
288 (sieve_session_data_cb_fn
)filter_activated
, cmd_data
);
291 static void filter_deleted(SieveSession
*session
, gboolean abort
,
292 const gchar
*err_msg
,
293 CommandDataName
*cmd_data
)
295 SieveManagerPage
*page
= cmd_data
->page
;
299 } else if (err_msg
) {
300 got_session_error(session
, err_msg
, page
);
302 manager_sessions_foreach(cur
, session
, page
) {
303 filters_list_delete_filter(page
,
304 cmd_data
->filter_name
);
307 g_free(cmd_data
->filter_name
);
312 static void filter_delete(GtkWidget
*widget
, SieveManagerPage
*page
)
316 SieveSession
*session
;
317 CommandDataName
*cmd_data
;
319 filter_name
= filters_list_get_selected_filter(page
->filters_list
);
320 if (filter_name
== NULL
)
323 session
= page
->active_session
;
327 g_snprintf(buf
, sizeof(buf
),
328 _("Do you really want to delete the filter '%s'?"), filter_name
);
329 if (alertpanel_full(_("Delete filter"), buf
,
330 NULL
, _("_Cancel"), "edit-delete", _("_Delete"), NULL
, NULL
,
331 ALERTFOCUS_FIRST
, FALSE
, NULL
, ALERT_WARNING
) != G_ALERTALTERNATE
)
334 cmd_data
= g_new(CommandDataName
, 1);
335 cmd_data
->filter_name
= filter_name
;
336 cmd_data
->page
= page
;
338 sieve_session_delete_script(session
, filter_name
,
339 (sieve_session_data_cb_fn
)filter_deleted
, cmd_data
);
343 * select a filter in the list
345 * return TRUE is successfully selected, FALSE otherwise
348 static gboolean
filter_select (GtkWidget
*list_view
, GtkTreeModel
*model
,
351 GtkTreeSelection
*selection
;
354 selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(list_view
));
355 gtk_tree_selection_select_iter(selection
, iter
);
356 path
= gtk_tree_model_get_path(model
, iter
);
357 if (path
== NULL
) return FALSE
;
358 gtk_tree_view_set_cursor(GTK_TREE_VIEW(list_view
), path
, NULL
, FALSE
);
359 gtk_tree_path_free(path
);
364 * find matching filter. return FALSE on match
366 static gboolean
filter_search_equal_fn (GtkTreeModel
*model
, gint column
,
367 const gchar
*key
, GtkTreeIter
*iter
, gpointer search_data
)
369 SieveManagerPage
*page
= (SieveManagerPage
*)search_data
;
372 if (!key
) return TRUE
;
374 gtk_tree_model_get (model
, iter
, FILTER_NAME
, &filter_name
, -1);
376 if (strncmp (key
, filter_name
, strlen(key
)) != 0) return TRUE
;
377 return !filter_select(page
->filters_list
, model
, iter
);
381 * search for a filter row by its name. return true if found.
383 gboolean
filter_find_by_name (GtkTreeModel
*model
, GtkTreeIter
*iter
,
388 if (!gtk_tree_model_get_iter_first (model
, iter
))
392 gtk_tree_model_get (model
, iter
, FILTER_NAME
, &name
, -1);
393 if (strcmp(filter_name
, name
) == 0) {
396 } while (gtk_tree_model_iter_next (model
, iter
));
400 static gboolean
filter_set_inactive(GtkTreeModel
*model
,
401 GtkTreePath
*path
, GtkTreeIter
*iter
, gpointer data
)
403 gtk_list_store_set(GTK_LIST_STORE(model
), iter
,
404 FILTER_ACTIVE
, FALSE
,
410 * Set the active filter in the table.
411 * @param filter_name The filter to make active (may be null)
413 static void filter_set_active(SieveManagerPage
*page
, gchar
*filter_name
)
416 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(page
->filters_list
));
418 /* Deactivate all filters */
419 gtk_tree_model_foreach(model
, filter_set_inactive
, NULL
);
421 /* Set active filter */
423 if (!filter_find_by_name (model
, &iter
, filter_name
))
426 gtk_list_store_set(GTK_LIST_STORE(model
), &iter
,
432 static void filter_active_toggled(GtkCellRendererToggle
*widget
,
434 SieveManagerPage
*page
)
439 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(page
->filters_list
));
441 if (!gtk_tree_model_get_iter_from_string(model
, &iter
, path
))
444 /* get existing value */
445 gtk_tree_model_get(model
, &iter
,
446 FILTER_NAME
, &filter_name
,
447 FILTER_ACTIVE
, &active
,
450 sieve_set_active_filter(page
, active
? NULL
: filter_name
);
453 static void filter_double_clicked(GtkTreeView
*list_view
,
454 GtkTreePath
*path
, GtkTreeViewColumn
*column
,
455 SieveManagerPage
*page
)
457 filter_edit(GTK_WIDGET(list_view
), page
);
460 static void filters_create_list_view_columns(SieveManagerPage
*page
,
461 GtkWidget
*list_view
)
463 GtkTreeViewColumn
*column
;
464 GtkCellRenderer
*renderer
;
468 renderer
= gtk_cell_renderer_text_new();
469 column
= gtk_tree_view_column_new_with_attributes
470 (_("Name"), renderer
,
473 gtk_tree_view_append_column(GTK_TREE_VIEW(list_view
), column
);
474 gtk_tree_view_column_set_expand(column
, TRUE
);
477 renderer
= gtk_cell_renderer_toggle_new();
478 g_object_set(renderer
,
482 column
= gtk_tree_view_column_new_with_attributes
483 (_("Active"), renderer
,
484 "active", FILTER_ACTIVE
,
486 gtk_tree_view_append_column(GTK_TREE_VIEW(list_view
), column
);
487 gtk_tree_view_column_set_alignment (column
, 0.5);
489 /* the column header needs a widget to have a tooltip */
490 label
= gtk_label_new(gtk_tree_view_column_get_title(column
));
491 gtk_widget_show(label
);
492 gtk_tree_view_column_set_widget(column
, label
);
494 _("An account can only have one active script at a time."));
496 g_signal_connect(G_OBJECT(renderer
), "toggled",
497 G_CALLBACK(filter_active_toggled
), page
);
499 gtk_tree_view_set_search_column(GTK_TREE_VIEW(list_view
), FILTER_NAME
);
500 gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(list_view
),
501 filter_search_equal_fn
, page
, NULL
);
505 static GtkListStore
* filters_create_data_store(void)
507 return gtk_list_store_new(N_FILTER_COLUMNS
,
508 G_TYPE_STRING
, /* FILTER_NAME */
509 G_TYPE_BOOLEAN
, /* FILTER_ACTIVE */
513 static GtkWidget
*filters_list_view_create(SieveManagerPage
*page
)
515 GtkTreeView
*list_view
;
516 GtkTreeSelection
*selector
;
517 GtkListStore
*store
= filters_create_data_store();
519 list_view
= GTK_TREE_VIEW(gtk_tree_view_new_with_model(GTK_TREE_MODEL(store
)));
520 g_object_unref(G_OBJECT(store
));
522 selector
= gtk_tree_view_get_selection(list_view
);
523 gtk_tree_selection_set_mode(selector
, GTK_SELECTION_BROWSE
);
525 /* create the columns */
526 filters_create_list_view_columns(page
, GTK_WIDGET(list_view
));
528 /* set a double click listener */
529 g_signal_connect(G_OBJECT(list_view
), "row_activated",
530 G_CALLBACK(filter_double_clicked
),
533 return GTK_WIDGET(list_view
);
536 static gboolean
manager_key_pressed(GtkWidget
*widget
, GdkEventKey
*event
,
539 SieveManagerPage
* page
= (SieveManagerPage
*) data
;
541 if (event
&& event
->keyval
== GDK_KEY_Escape
)
542 sieve_manager_done(page
);
547 static void size_allocate_cb(GtkWidget
*widget
, GtkAllocation
*allocation
)
549 cm_return_if_fail(allocation
!= NULL
);
551 gtk_window_get_size(GTK_WINDOW(widget
),
552 &sieve_config
.manager_win_width
, &sieve_config
.manager_win_height
);
555 static void got_session_error(SieveSession
*session
, const gchar
*msg
,
556 SieveManagerPage
*page
)
558 if (!g_slist_find(manager_pages
, page
))
560 if (page
->active_session
!= session
)
562 gtk_label_set_text(GTK_LABEL(page
->status_text
), msg
);
565 static void sieve_manager_on_error(SieveSession
*session
,
566 const gchar
*msg
, gpointer user_data
)
568 SieveManagerPage
*page
= (SieveManagerPage
*)user_data
;
569 got_session_error(session
, msg
, page
);
572 static void sieve_manager_on_connected(SieveSession
*session
,
573 gboolean connected
, gpointer user_data
)
575 SieveManagerPage
*page
= (SieveManagerPage
*)user_data
;
576 if (page
->active_session
!= session
)
579 gtk_widget_set_sensitive(GTK_WIDGET(page
->vbox_buttons
), FALSE
);
580 gtk_label_set_text(GTK_LABEL(page
->status_text
),
581 _("Unable to connect"));
585 static void got_filter_listed(SieveSession
*session
, gboolean abort
,
586 SieveScript
*script
, SieveManagerPage
*page
)
591 got_session_error(session
, "Unable to list scripts", page
);
595 /* done receiving list */
596 page
->got_list
= TRUE
;
597 gtk_widget_set_sensitive(GTK_WIDGET(page
->vbox_buttons
), TRUE
);
598 gtk_label_set_text(GTK_LABEL(page
->status_text
), "");
601 filters_list_insert_filter(page
, script
);
605 * An account was selected from the menu. Get its list of scripts.
607 static void account_changed(GtkWidget
*widget
, SieveManagerPage
*page
)
610 PrefsAccount
*account
;
611 SieveSession
*session
;
613 if (page
->accounts_menu
== NULL
)
616 account_id
= combobox_get_active_data(GTK_COMBO_BOX(page
->accounts_menu
));
617 account
= account_find_from_id(account_id
);
620 session
= page
->active_session
= sieve_session_get_for_account(account
);
621 sieve_session_handle_status(session
,
622 sieve_manager_on_error
,
623 sieve_manager_on_connected
,
625 filters_list_clear(page
);
626 if (session_is_connected(SESSION(session
))) {
627 gtk_label_set_text(GTK_LABEL(page
->status_text
),
628 _("Listing scripts..."));
630 gtk_label_set_text(GTK_LABEL(page
->status_text
),
633 sieve_session_list_scripts(session
,
634 (sieve_session_data_cb_fn
)got_filter_listed
, (gpointer
)page
);
637 static SieveManagerPage
*sieve_manager_page_new()
639 SieveManagerPage
*page
;
641 GtkWidget
*hbox
, *vbox
, *vbox_allbuttons
, *vbox_buttons
;
642 GtkWidget
*accounts_menu
;
644 GtkWidget
*scrolledwin
;
645 GtkWidget
*list_view
;
647 GtkWidget
*status_text
;
650 GList
*account_list
, *cur
;
652 SieveAccountConfig
*config
;
653 PrefsAccount
*default_account
= NULL
;
655 static GdkGeometry geometry
;
657 page
= g_new0(SieveManagerPage
, 1);
661 window
= gtkut_window_new(GTK_WINDOW_TOPLEVEL
, "sievemanager");
662 gtk_container_set_border_width (GTK_CONTAINER (window
), 8);
663 gtk_window_set_title (GTK_WINDOW (window
), _("Manage Sieve Filters"));
664 gtk_window_set_type_hint(GTK_WINDOW(window
), GDK_WINDOW_TYPE_HINT_DIALOG
);
665 MANAGE_WINDOW_SIGNALS_CONNECT (window
);
667 g_signal_connect (G_OBJECT (window
), "key_press_event",
668 G_CALLBACK (manager_key_pressed
), page
);
669 g_signal_connect (G_OBJECT(window
), "size_allocate",
670 G_CALLBACK (size_allocate_cb
), NULL
);
671 g_signal_connect (G_OBJECT(window
), "delete_event",
672 G_CALLBACK (sieve_manager_deleted
), page
);
674 if (!geometry
.min_height
) {
675 geometry
.min_width
= 350;
676 geometry
.min_height
= 280;
679 gtk_window_set_geometry_hints(GTK_WINDOW(window
), NULL
, &geometry
,
681 gtk_window_set_default_size(GTK_WINDOW(window
), sieve_config
.manager_win_width
,
682 sieve_config
.manager_win_height
);
683 gtk_window_set_type_hint(GTK_WINDOW(window
),
684 GDK_WINDOW_TYPE_HINT_DIALOG
);
686 vbox
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, 10);
687 gtk_container_add (GTK_CONTAINER (window
), vbox
);
689 hbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 8);
690 gtk_box_pack_start (GTK_BOX (vbox
), hbox
, FALSE
, FALSE
, 0);
694 label
= gtk_label_new (_("Account"));
695 gtk_box_pack_start (GTK_BOX (hbox
), label
, FALSE
, FALSE
, 0);
697 accounts_menu
= gtkut_sc_combobox_create(NULL
, FALSE
);
698 menu
= GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(accounts_menu
)));
699 gtk_box_pack_start (GTK_BOX (hbox
), accounts_menu
, FALSE
, FALSE
, 0);
700 g_signal_connect (G_OBJECT(accounts_menu
), "changed",
701 G_CALLBACK (account_changed
), page
);
703 account_list
= account_get_list();
704 for (cur
= account_list
; cur
!= NULL
; cur
= cur
->next
) {
705 ap
= (PrefsAccount
*)cur
->data
;
706 config
= sieve_prefs_account_get_config(ap
);
707 if (config
->enable
) {
708 COMBOBOX_ADD (menu
, ap
->account_name
, ap
->account_id
);
709 if (!default_account
|| ap
->is_default
)
710 default_account
= ap
;
712 sieve_prefs_account_free_config(config
);
715 if (!default_account
) {
716 gtk_widget_destroy(label
);
717 gtk_widget_destroy(accounts_menu
);
718 accounts_menu
= NULL
;
722 status_text
= gtk_label_new ("");
723 gtk_box_pack_start (GTK_BOX (hbox
), status_text
, FALSE
, FALSE
, 0);
724 gtk_label_set_justify (GTK_LABEL (status_text
), GTK_JUSTIFY_LEFT
);
728 hbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 8);
729 gtk_box_pack_start (GTK_BOX (vbox
), hbox
, TRUE
, TRUE
, 0);
730 gtk_container_set_border_width (GTK_CONTAINER (hbox
), 2);
734 scrolledwin
= gtk_scrolled_window_new (NULL
, NULL
);
735 gtk_box_pack_start (GTK_BOX (hbox
), scrolledwin
, TRUE
, TRUE
, 0);
736 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwin
),
737 GTK_POLICY_AUTOMATIC
,
738 GTK_POLICY_AUTOMATIC
);
740 list_view
= filters_list_view_create(page
);
741 gtk_container_add(GTK_CONTAINER(scrolledwin
), list_view
);
745 vbox_allbuttons
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, 8);
746 gtk_box_pack_start (GTK_BOX (hbox
), vbox_allbuttons
, FALSE
, FALSE
, 0);
748 /* buttons that depend on there being a connection */
749 vbox_buttons
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, 8);
750 gtk_widget_set_sensitive(vbox_buttons
, FALSE
);
751 gtk_box_pack_start (GTK_BOX (vbox_allbuttons
), vbox_buttons
, FALSE
, FALSE
, 0);
754 btn
= gtk_button_new_with_mnemonic("_New");
755 gtk_box_pack_start (GTK_BOX (vbox_buttons
), btn
, FALSE
, FALSE
, 0);
756 g_signal_connect (G_OBJECT(btn
), "clicked",
757 G_CALLBACK (filter_add
), page
);
760 btn
= gtk_button_new_with_mnemonic("_Edit");
761 gtk_box_pack_start (GTK_BOX (vbox_buttons
), btn
, FALSE
, FALSE
, 0);
762 g_signal_connect (G_OBJECT(btn
), "clicked",
763 G_CALLBACK (filter_edit
), page
);
766 btn
= gtkut_stock_button("edit-delete", _("D_elete"));
767 gtk_box_pack_start (GTK_BOX (vbox_buttons
), btn
, FALSE
, FALSE
, 0);
768 g_signal_connect (G_OBJECT(btn
), "clicked",
769 G_CALLBACK (filter_delete
), page
);
772 btn
= gtk_button_new_with_mnemonic(_("_Rename"));
773 gtk_box_pack_start (GTK_BOX (vbox_buttons
), btn
, FALSE
, FALSE
, 0);
774 g_signal_connect (G_OBJECT(btn
), "clicked",
775 G_CALLBACK (filter_rename
), page
);
778 btn
= gtkut_stock_button("view-refresh", "_Refresh");
779 gtk_box_pack_end (GTK_BOX (vbox_allbuttons
), btn
, FALSE
, FALSE
, 0);
780 g_signal_connect (G_OBJECT(btn
), "clicked",
781 G_CALLBACK (account_changed
), page
);
783 /* bottom area stuff */
785 gtkut_stock_button_set_create(&hbox
,
786 &btn
, "window-close", _("_Close"),
787 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
790 gtk_box_pack_end (GTK_BOX (vbox
), hbox
, FALSE
, FALSE
, 0);
791 gtk_widget_grab_default (btn
);
792 g_signal_connect (G_OBJECT (btn
), "clicked",
793 G_CALLBACK (sieve_manager_close
), page
);
795 page
->window
= window
;
796 page
->accounts_menu
= accounts_menu
;
797 page
->filters_list
= list_view
;
798 page
->status_text
= status_text
;
799 page
->vbox_buttons
= vbox_buttons
;
801 /* select default (first) account */
802 if (default_account
) {
803 combobox_select_by_data(GTK_COMBO_BOX(accounts_menu
),
804 default_account
->account_id
);
806 gtk_label_set_text(GTK_LABEL(status_text
),
807 _("To use Sieve, enable it in an account's preferences."));
813 static gboolean
sieve_manager_deleted(GtkWidget
*widget
, GdkEvent
*event
,
814 SieveManagerPage
*page
)
816 sieve_manager_done(page
);
820 static void sieve_manager_close(GtkWidget
*widget
, SieveManagerPage
*page
)
822 sieve_manager_done(page
);
825 void sieve_manager_done(SieveManagerPage
*page
)
827 manager_pages
= g_slist_remove(manager_pages
, page
);
828 sieve_sessions_discard_callbacks(page
);
829 gtk_widget_destroy(page
->window
);
833 void sieve_manager_show()
835 SieveManagerPage
*page
= sieve_manager_page_new();
836 manager_pages
= g_slist_prepend(manager_pages
, page
);
837 gtk_widget_show_all(page
->window
);
840 void sieve_manager_script_created(SieveSession
*session
, const gchar
*name
)
842 SieveManagerPage
*page
;
843 SieveScript script
= {.name
= (gchar
*)name
};
846 manager_sessions_foreach(cur
, session
, page
) {
847 filters_list_insert_filter(page
, &script
);