2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2001 Hiroyuki Yamamoto
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.
28 #include <gdk/gdkkeysyms.h>
37 #include "prefs_display_headers.h"
38 #include "prefs_common.h"
39 #include "mainwindow.h"
40 #include "foldersel.h"
41 #include "manage_window.h"
44 #include "alertpanel.h"
46 #include "headers_display.h"
48 static struct Headers {
56 GtkWidget *headers_clist;
60 parameter name, default value, pointer to the prefs variable, data type,
61 pointer to the widget pointer,
62 pointer to the function for data setting,
63 pointer to the function for widget setting
67 #define VSPACING_NARROW 4
68 #define DEFAULT_ENTRY_WIDTH 80
69 #define PREFSBUFSIZE 1024
71 /* widget creating functions */
72 static void prefs_display_headers_create (void);
74 static void prefs_display_headers_set_dialog (void);
75 static void prefs_display_headers_set_list (void);
76 static gint prefs_display_headers_clist_set_row (gint row);
78 /* callback functions */
79 static void prefs_display_headers_select_dest_cb (void);
80 static void prefs_display_headers_register_cb (void);
81 static void prefs_display_headers_substitute_cb (void);
82 static void prefs_display_headers_delete_cb (void);
83 static void prefs_display_headers_up (void);
84 static void prefs_display_headers_down (void);
85 static void prefs_display_headers_select (GtkCList *clist,
90 static void prefs_display_headers_dest_radio_button_toggled (void);
91 static void prefs_display_headers_notrecv_radio_button_toggled (void);
93 static void prefs_display_headers_key_pressed (GtkWidget *widget,
96 static void prefs_display_headers_close (GtkButton *button);
98 GSList * prefs_display_headers = NULL;
100 static char * defaults[] =
115 "-Content-Transfer-Encoding",
122 static void prefs_display_headers_set_default(void)
126 for(i = 0 ; i < sizeof(defaults) / sizeof(char *) ; i++) {
127 HeaderDisplayProp * dp =
128 header_display_prop_read_str(defaults[i]);
129 prefs_display_headers =
130 g_slist_append(prefs_display_headers, dp);
134 void prefs_display_headers_open(void)
136 if (!headers.window) {
137 prefs_display_headers_create();
140 manage_window_set_transient(GTK_WINDOW(headers.window));
141 gtk_widget_grab_focus(headers.close_btn);
143 prefs_display_headers_set_dialog();
145 gtk_widget_show(headers.window);
148 static void prefs_display_headers_create(void)
152 GtkWidget *close_btn;
153 GtkWidget *confirm_area;
158 GtkWidget *hdr_label;
159 GtkWidget *hdr_combo;
160 GtkWidget *key_label;
161 GtkWidget *key_check;
167 GtkWidget *subst_btn;
171 GtkWidget *ch_scrolledwin;
172 GtkWidget *headers_clist;
178 gchar *title[] = {_("Custom headers")};
180 debug_print(_("Creating headers setting window...\n"));
182 window = gtk_window_new (GTK_WINDOW_DIALOG);
183 gtk_container_set_border_width (GTK_CONTAINER (window), 8);
184 gtk_window_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
185 gtk_window_set_modal (GTK_WINDOW (window), TRUE);
186 gtk_window_set_policy (GTK_WINDOW (window), FALSE, TRUE, FALSE);
188 vbox = gtk_vbox_new (FALSE, 6);
189 gtk_widget_show (vbox);
190 gtk_container_add (GTK_CONTAINER (window), vbox);
192 gtkut_button_set_create (&confirm_area, &close_btn, _("Close"),
193 NULL, NULL, NULL, NULL);
194 gtk_widget_show (confirm_area);
195 gtk_box_pack_end (GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
196 gtk_widget_grab_default (close_btn);
198 gtk_window_set_title (GTK_WINDOW(window),
199 _("Headers setting"));
200 gtk_signal_connect (GTK_OBJECT(window), "delete_event",
201 GTK_SIGNAL_FUNC(gtk_widget_hide_on_delete), NULL);
202 gtk_signal_connect (GTK_OBJECT(window), "key_press_event",
203 GTK_SIGNAL_FUNC(prefs_display_headers_key_pressed),
205 gtk_signal_connect (GTK_OBJECT(window), "focus_in_event",
206 GTK_SIGNAL_FUNC(manage_window_focus_in), NULL);
207 gtk_signal_connect (GTK_OBJECT(window), "focus_out_event",
208 GTK_SIGNAL_FUNC(manage_window_focus_out), NULL);
209 gtk_signal_connect (GTK_OBJECT(close_btn), "clicked",
210 GTK_SIGNAL_FUNC(prefs_display_headers_close),
213 vbox1 = gtk_vbox_new (FALSE, VSPACING);
214 gtk_widget_show (vbox1);
215 gtk_box_pack_start (GTK_BOX (vbox), vbox1, TRUE, TRUE, 0);
216 gtk_container_set_border_width (GTK_CONTAINER (vbox1), 2);
218 table1 = gtk_table_new (2, 2, FALSE);
219 gtk_widget_show (table1);
220 gtk_box_pack_start (GTK_BOX (vbox1), table1,
222 gtk_table_set_row_spacings (GTK_TABLE (table1), 8);
223 gtk_table_set_col_spacings (GTK_TABLE (table1), 8);
225 hdr_label = gtk_label_new (_("Header"));
226 gtk_widget_show (hdr_label);
227 gtk_table_attach (GTK_TABLE (table1), hdr_label, 0, 1, 0, 1,
228 GTK_EXPAND | GTK_SHRINK | GTK_FILL,
230 gtk_misc_set_alignment (GTK_MISC (hdr_label), 0, 0.5);
232 hdr_combo = gtk_combo_new ();
233 gtk_widget_show (hdr_combo);
234 gtk_table_attach (GTK_TABLE (table1), hdr_combo, 0, 1, 1, 2,
235 GTK_EXPAND | GTK_SHRINK | GTK_FILL,
237 gtk_widget_set_usize (hdr_combo, 150 /* 96 */, -1);
238 gtkut_combo_set_items (GTK_COMBO (hdr_combo),
239 "From", "To", "Subject", "Date", NULL);
241 key_label = gtk_label_new (_("Hide"));
242 gtk_widget_show (key_label);
243 gtk_table_attach (GTK_TABLE (table1), key_label, 1, 2, 0, 1,
244 GTK_EXPAND | GTK_SHRINK | GTK_FILL,
246 gtk_misc_set_alignment (GTK_MISC (key_label), 0, 0.5);
248 // key_entry = gtk_entry_new ();
249 key_check = gtk_check_button_new();
250 gtk_widget_show (key_check);
251 gtk_table_attach (GTK_TABLE (table1), key_check, 1, 2, 1, 2,
252 GTK_EXPAND | GTK_SHRINK | GTK_FILL,
255 /* register / substitute / delete */
257 reg_hbox = gtk_hbox_new (FALSE, 4);
258 gtk_widget_show (reg_hbox);
259 gtk_box_pack_start (GTK_BOX (vbox1), reg_hbox,
262 arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT);
263 gtk_widget_show (arrow);
264 gtk_box_pack_start (GTK_BOX (reg_hbox), arrow, FALSE, FALSE, 0);
265 gtk_widget_set_usize (arrow, -1, 16);
267 btn_hbox = gtk_hbox_new (TRUE, 4);
268 gtk_widget_show (btn_hbox);
269 gtk_box_pack_start (GTK_BOX (reg_hbox), btn_hbox, FALSE, FALSE, 0);
271 reg_btn = gtk_button_new_with_label (_("Add"));
272 gtk_widget_show (reg_btn);
273 gtk_box_pack_start (GTK_BOX (btn_hbox), reg_btn, FALSE, TRUE, 0);
274 gtk_signal_connect (GTK_OBJECT (reg_btn), "clicked",
276 (prefs_display_headers_register_cb), NULL);
278 subst_btn = gtk_button_new_with_label (_(" Substitute "));
279 gtk_widget_show (subst_btn);
280 gtk_box_pack_start (GTK_BOX (btn_hbox), subst_btn, FALSE, TRUE, 0);
281 gtk_signal_connect (GTK_OBJECT (subst_btn), "clicked",
283 (prefs_display_headers_substitute_cb),
286 del_btn = gtk_button_new_with_label (_("Delete"));
287 gtk_widget_show (del_btn);
288 gtk_box_pack_start (GTK_BOX (btn_hbox), del_btn, FALSE, TRUE, 0);
289 gtk_signal_connect (GTK_OBJECT (del_btn), "clicked",
290 GTK_SIGNAL_FUNC (prefs_display_headers_delete_cb),
294 ch_hbox = gtk_hbox_new (FALSE, 8);
295 gtk_widget_show (ch_hbox);
296 gtk_box_pack_start (GTK_BOX (vbox1), ch_hbox,
299 ch_scrolledwin = gtk_scrolled_window_new (NULL, NULL);
300 gtk_widget_set_usize (ch_scrolledwin, -1, 100);
301 gtk_widget_show (ch_scrolledwin);
302 gtk_box_pack_start (GTK_BOX (ch_hbox), ch_scrolledwin,
304 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (ch_scrolledwin),
305 GTK_POLICY_AUTOMATIC,
306 GTK_POLICY_AUTOMATIC);
308 headers_clist = gtk_clist_new_with_titles(1, title);
309 gtk_widget_show (headers_clist);
310 gtk_container_add (GTK_CONTAINER (ch_scrolledwin), headers_clist);
311 gtk_clist_set_column_width (GTK_CLIST (headers_clist), 0, 80);
312 gtk_clist_set_selection_mode (GTK_CLIST (headers_clist),
313 GTK_SELECTION_BROWSE);
314 GTK_WIDGET_UNSET_FLAGS (GTK_CLIST (headers_clist)->column[0].button,
316 gtk_signal_connect (GTK_OBJECT (headers_clist), "select_row",
317 GTK_SIGNAL_FUNC (prefs_display_headers_select),
321 btn_vbox = gtk_vbox_new (FALSE, 8);
322 gtk_widget_show (btn_vbox);
323 gtk_box_pack_start (GTK_BOX (ch_hbox), btn_vbox, FALSE, FALSE, 0);
325 up_btn = gtk_button_new_with_label (_("Up"));
326 gtk_widget_show (up_btn);
327 gtk_box_pack_start (GTK_BOX (btn_vbox), up_btn, FALSE, FALSE, 0);
328 gtk_signal_connect (GTK_OBJECT (up_btn), "clicked",
329 GTK_SIGNAL_FUNC (prefs_display_headers_up), NULL);
331 down_btn = gtk_button_new_with_label (_("Down"));
332 gtk_widget_show (down_btn);
333 gtk_box_pack_start (GTK_BOX (btn_vbox), down_btn, FALSE, FALSE, 0);
334 gtk_signal_connect (GTK_OBJECT (down_btn), "clicked",
335 GTK_SIGNAL_FUNC (prefs_display_headers_down), NULL);
338 gtk_widget_show_all(window);
340 headers.window = window;
341 headers.close_btn = close_btn;
343 headers.hdr_combo = hdr_combo;
344 headers.hdr_entry = GTK_COMBO (hdr_combo)->entry;
345 headers.key_check = key_check;
346 headers.headers_clist = headers_clist;
349 void prefs_display_headers_read_config(void)
353 gchar buf[PREFSBUFSIZE];
354 HeaderDisplayProp *dp;
356 debug_print(_("Reading configuration for displaying of headers...\n"));
358 rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
359 HEADERS_DISPLAY_RC, NULL);
360 if ((fp = fopen(rcpath, "r")) == NULL) {
361 if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
363 prefs_display_headers = NULL;
364 prefs_display_headers_set_default();
369 /* remove all previous headers list */
370 while (prefs_display_headers != NULL) {
371 dp = (HeaderDisplayProp *)prefs_display_headers->data;
372 header_display_prop_free(dp);
373 prefs_display_headers =
374 g_slist_remove(prefs_display_headers, dp);
377 while (fgets(buf, sizeof(buf), fp) != NULL) {
379 dp = header_display_prop_read_str(buf);
381 prefs_display_headers =
382 g_slist_append(prefs_display_headers, dp);
389 void prefs_display_headers_write_config(void)
394 gchar buf[PREFSBUFSIZE];
396 HeaderDisplayProp *dp;
398 debug_print(_("Writing configuration for displaying of headers...\n"));
400 rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
401 HEADERS_DISPLAY_RC, NULL);
403 if ((pfile = prefs_write_open(rcpath)) == NULL) {
404 g_warning(_("failed to write configuration to file\n"));
409 for (cur = prefs_display_headers; cur != NULL; cur = cur->next) {
410 HeaderDisplayProp *hdr = (HeaderDisplayProp *)cur->data;
413 dpstr = header_display_prop_get_str(hdr);
414 if (fputs(dpstr, pfile->fp) == EOF ||
415 fputc('\n', pfile->fp) == EOF) {
416 FILE_OP_ERROR(rcpath, "fputs || fputc");
417 prefs_write_close_revert(pfile);
427 if (prefs_write_close(pfile) < 0) {
428 g_warning(_("failed to write configuration to file\n"));
433 static void prefs_display_headers_set_dialog()
435 GtkCList *clist = GTK_CLIST(headers.headers_clist);
440 gtk_clist_freeze(clist);
441 gtk_clist_clear(clist);
443 dp_str[0] = _("(New)");
444 row = gtk_clist_append(clist, dp_str);
445 gtk_clist_set_row_data(clist, row, NULL);
447 for (cur = prefs_display_headers; cur != NULL; cur = cur->next) {
448 HeaderDisplayProp *dp = (HeaderDisplayProp *)cur->data;
451 dp_str[0] = g_strdup_printf("(%s)", dp->name);
453 dp_str[0] = g_strdup_printf("%s", dp->name);
454 row = gtk_clist_append(clist, dp_str);
455 gtk_clist_set_row_data(clist, row, dp);
460 gtk_clist_thaw(clist);
463 static void prefs_display_headers_set_list()
466 HeaderDisplayProp *dp;
468 g_slist_free(prefs_display_headers);
469 prefs_display_headers = NULL;
471 while ((dp = gtk_clist_get_row_data(GTK_CLIST(headers.headers_clist),
473 prefs_display_headers = g_slist_append(prefs_display_headers,
479 #define GET_ENTRY(entry) \
480 entry_text = gtk_entry_get_text(GTK_ENTRY(entry))
482 static gint prefs_display_headers_clist_set_row(gint row)
484 GtkCList *clist = GTK_CLIST(headers.headers_clist);
485 HeaderDisplayProp *dp;
489 g_return_val_if_fail(row != 0, -1);
491 GET_ENTRY(headers.hdr_entry);
492 if (entry_text[0] == '\0') {
493 alertpanel_error(_("Header name is not set."));
497 dp = g_new0(HeaderDisplayProp, 1);
499 dp->name = g_strdup(entry_text);
501 dp->hidden = gtk_toggle_button_get_active
502 (GTK_TOGGLE_BUTTON(headers.key_check));
505 dp_str[0] = g_strdup_printf("(%s)", dp->name);
507 dp_str[0] = g_strdup_printf("%s", dp->name);
510 row = gtk_clist_append(clist, dp_str);
512 HeaderDisplayProp *tmpdp;
514 gtk_clist_set_text(clist, row, 0, dp_str[0]);
515 tmpdp = gtk_clist_get_row_data(clist, row);
517 header_display_prop_free(tmpdp);
520 gtk_clist_set_row_data(clist, row, dp);
524 prefs_display_headers_set_list();
529 static void prefs_display_headers_register_cb(void)
531 prefs_display_headers_clist_set_row(-1);
534 static void prefs_display_headers_substitute_cb(void)
536 GtkCList *clist = GTK_CLIST(headers.headers_clist);
537 HeaderDisplayProp *dp;
540 if (!clist->selection) return;
542 row = GPOINTER_TO_INT(clist->selection->data);
543 if (row == 0) return;
545 dp = gtk_clist_get_row_data(clist, row);
548 prefs_display_headers_clist_set_row(row);
551 static void prefs_display_headers_delete_cb(void)
553 GtkCList *clist = GTK_CLIST(headers.headers_clist);
554 HeaderDisplayProp *dp;
557 if (!clist->selection) return;
558 row = GPOINTER_TO_INT(clist->selection->data);
559 if (row == 0) return;
561 if (alertpanel(_("Delete header"),
562 _("Do you really want to delete this header?"),
563 _("Yes"), _("No"), NULL) == G_ALERTALTERNATE)
566 dp = gtk_clist_get_row_data(clist, row);
567 header_display_prop_free(dp);
568 gtk_clist_remove(clist, row);
569 prefs_display_headers = g_slist_remove(prefs_display_headers, dp);
572 static void prefs_display_headers_up(void)
574 GtkCList *clist = GTK_CLIST(headers.headers_clist);
577 if (!clist->selection) return;
579 row = GPOINTER_TO_INT(clist->selection->data);
581 gtk_clist_row_move(clist, row, row - 1);
582 prefs_display_headers_set_list();
586 static void prefs_display_headers_down(void)
588 GtkCList *clist = GTK_CLIST(headers.headers_clist);
591 if (!clist->selection) return;
593 row = GPOINTER_TO_INT(clist->selection->data);
594 if (row > 0 && row < clist->rows - 1) {
595 gtk_clist_row_move(clist, row, row + 1);
596 prefs_display_headers_set_list();
600 #define ENTRY_SET_TEXT(entry, str) \
601 gtk_entry_set_text(GTK_ENTRY(entry), str ? str : "")
603 static void prefs_display_headers_select(GtkCList *clist, gint row,
604 gint column, GdkEvent *event)
606 HeaderDisplayProp *dp;
607 HeaderDisplayProp default_dp = { "", 0 };
609 dp = gtk_clist_get_row_data(clist, row);
613 ENTRY_SET_TEXT(headers.hdr_entry, dp->name);
614 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(headers.key_check),
618 static void prefs_display_headers_key_pressed(GtkWidget *widget,
622 if (event && event->keyval == GDK_Escape)
623 gtk_widget_hide(headers.window);
626 static void prefs_display_headers_close(GtkButton *button)
628 prefs_display_headers_write_config();
629 gtk_widget_hide(headers.window);