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>
36 #include "prefs_display_header.h"
37 #include "prefs_common.h"
38 #include "manage_window.h"
39 #include "alertpanel.h"
40 #include "displayheader.h"
44 static struct DisplayHeader {
48 GtkWidget *cancel_btn;
53 GtkWidget *headers_clist;
54 GtkWidget *hidden_headers_clist;
56 GtkWidget *other_headers;
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_header_create (void);
74 static void prefs_display_header_set_dialog (void);
75 static void prefs_display_header_set_list (void);
76 static gint prefs_display_header_clist_set_row (gboolean hidden);
78 /* callback functions */
79 static void prefs_display_header_register_cb (GtkButton *btn,
80 gpointer hidden_data);
81 static void prefs_display_header_delete_cb (GtkButton *btn,
83 static void prefs_display_header_up (void);
84 static void prefs_display_header_down (void);
86 static void prefs_display_header_key_pressed (GtkWidget *widget,
89 static void prefs_display_header_ok (void);
90 static void prefs_display_header_cancel (void);
91 static gint prefs_display_header_deleted(GtkWidget *widget, GdkEventAny *event,
94 static gchar *defaults[] =
115 "-Content-Transfer-Encoding",
123 static void prefs_display_header_set_default(void)
126 DisplayHeaderProp *dp;
128 for(i = 0; i < sizeof(defaults) / sizeof(defaults[0]); i++) {
129 dp = display_header_prop_read_str(defaults[i]);
130 prefs_common.disphdr_list =
131 g_slist_append(prefs_common.disphdr_list, dp);
135 void prefs_display_header_open(void)
137 if (!dispheader.window) {
138 prefs_display_header_create();
141 manage_window_set_transient(GTK_WINDOW(dispheader.window));
142 gtk_widget_grab_focus(dispheader.ok_btn);
144 prefs_display_header_set_dialog();
146 gtk_widget_show(dispheader.window);
149 static void prefs_display_header_create(void)
155 GtkWidget *cancel_btn;
156 GtkWidget *confirm_area;
161 GtkWidget *hdr_label;
162 GtkWidget *hdr_combo;
170 GtkWidget *clist_hbox;
171 GtkWidget *clist_hbox1;
172 GtkWidget *clist_hbox2;
173 GtkWidget *clist_scrolledwin;
174 GtkWidget *headers_clist;
175 GtkWidget *hidden_headers_clist;
177 GtkWidget *checkbtn_other_headers;
181 debug_print(_("Creating display header setting window...\n"));
183 window = gtk_window_new (GTK_WINDOW_DIALOG);
184 gtk_container_set_border_width (GTK_CONTAINER (window), 8);
185 gtk_window_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
186 gtk_window_set_modal (GTK_WINDOW (window), TRUE);
187 gtk_window_set_policy (GTK_WINDOW (window), FALSE, TRUE, FALSE);
189 vbox = gtk_vbox_new (FALSE, 6);
190 gtk_widget_show (vbox);
191 gtk_container_add (GTK_CONTAINER (window), vbox);
193 btn_hbox = gtk_hbox_new (FALSE, 8);
194 gtk_widget_show (btn_hbox);
195 gtk_box_pack_end (GTK_BOX (vbox), btn_hbox, FALSE, FALSE, 0);
197 gtkut_button_set_create(&confirm_area, &ok_btn, _("OK"),
198 &cancel_btn, _("Cancel"), NULL, NULL);
199 gtk_widget_show (confirm_area);
200 gtk_box_pack_end (GTK_BOX(btn_hbox), confirm_area, FALSE, FALSE, 0);
201 gtk_widget_grab_default (ok_btn);
203 gtk_window_set_title (GTK_WINDOW(window),
204 _("Display header setting"));
205 gtk_signal_connect (GTK_OBJECT(window), "delete_event",
206 GTK_SIGNAL_FUNC(prefs_display_header_deleted),
208 gtk_signal_connect (GTK_OBJECT(window), "key_press_event",
209 GTK_SIGNAL_FUNC(prefs_display_header_key_pressed),
211 gtk_signal_connect (GTK_OBJECT(window), "focus_in_event",
212 GTK_SIGNAL_FUNC(manage_window_focus_in), NULL);
213 gtk_signal_connect (GTK_OBJECT(window), "focus_out_event",
214 GTK_SIGNAL_FUNC(manage_window_focus_out), NULL);
215 gtk_signal_connect (GTK_OBJECT(ok_btn), "clicked",
216 GTK_SIGNAL_FUNC(prefs_display_header_ok),
218 gtk_signal_connect (GTK_OBJECT(cancel_btn), "clicked",
219 GTK_SIGNAL_FUNC(prefs_display_header_cancel),
222 vbox1 = gtk_vbox_new (FALSE, VSPACING);
223 gtk_widget_show (vbox1);
224 gtk_box_pack_start (GTK_BOX (vbox), vbox1, TRUE, TRUE, 0);
225 gtk_container_set_border_width (GTK_CONTAINER (vbox1), 2);
227 hbox1 = gtk_hbox_new (FALSE, 8);
228 gtk_widget_show (hbox1);
229 gtk_box_pack_start (GTK_BOX (vbox1), hbox1, FALSE, TRUE, 0);
231 hdr_label = gtk_label_new (_("Header name"));
232 gtk_widget_show (hdr_label);
233 gtk_box_pack_start (GTK_BOX (hbox1), hdr_label, FALSE, FALSE, 0);
235 hdr_combo = gtk_combo_new ();
236 gtk_widget_show (hdr_combo);
237 gtk_box_pack_start (GTK_BOX (hbox1), hdr_combo, TRUE, TRUE, 0);
238 gtk_widget_set_usize (hdr_combo, 150, -1);
239 gtkut_combo_set_items (GTK_COMBO (hdr_combo),
240 "From", "To", "Cc", "Subject", "Date",
241 "Reply-To", "Sender", "User-Agent", "X-Mailer",
244 clist_hbox = gtk_hbox_new (FALSE, 8);
245 gtk_widget_show (clist_hbox);
246 gtk_box_pack_start (GTK_BOX (vbox1), clist_hbox, TRUE, TRUE, 0);
248 /* display headers list */
250 clist_hbox1 = gtk_hbox_new (FALSE, 8);
251 gtk_widget_show (clist_hbox1);
252 gtk_box_pack_start (GTK_BOX (clist_hbox), clist_hbox1, TRUE, TRUE, 0);
254 clist_scrolledwin = gtk_scrolled_window_new (NULL, NULL);
255 gtk_widget_set_usize (clist_scrolledwin, 200, 210);
256 gtk_widget_show (clist_scrolledwin);
257 gtk_box_pack_start (GTK_BOX (clist_hbox1), clist_scrolledwin,
259 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (clist_scrolledwin),
260 GTK_POLICY_AUTOMATIC,
261 GTK_POLICY_AUTOMATIC);
263 title[0] = _("Displayed Headers");
264 headers_clist = gtk_clist_new_with_titles(1, title);
265 gtk_widget_show (headers_clist);
266 gtk_container_add (GTK_CONTAINER (clist_scrolledwin), headers_clist);
267 gtk_clist_set_selection_mode (GTK_CLIST (headers_clist),
268 GTK_SELECTION_BROWSE);
269 gtk_clist_set_reorderable (GTK_CLIST (headers_clist), TRUE);
270 gtk_clist_set_use_drag_icons (GTK_CLIST (headers_clist), FALSE);
271 GTK_WIDGET_UNSET_FLAGS (GTK_CLIST (headers_clist)->column[0].button,
274 btn_vbox = gtk_vbox_new (FALSE, 8);
275 gtk_widget_show (btn_vbox);
276 gtk_box_pack_start (GTK_BOX (clist_hbox1), btn_vbox, FALSE, FALSE, 0);
278 reg_btn = gtk_button_new_with_label (_("Add"));
279 gtk_widget_show (reg_btn);
280 gtk_box_pack_start (GTK_BOX (btn_vbox), reg_btn, FALSE, TRUE, 0);
281 gtk_signal_connect (GTK_OBJECT (reg_btn), "clicked",
282 GTK_SIGNAL_FUNC (prefs_display_header_register_cb),
284 del_btn = gtk_button_new_with_label (_("Delete"));
285 gtk_widget_show (del_btn);
286 gtk_box_pack_start (GTK_BOX (btn_vbox), del_btn, FALSE, TRUE, 0);
287 gtk_signal_connect (GTK_OBJECT (del_btn), "clicked",
288 GTK_SIGNAL_FUNC (prefs_display_header_delete_cb),
291 up_btn = gtk_button_new_with_label (_("Up"));
292 gtk_widget_show (up_btn);
293 gtk_box_pack_start (GTK_BOX (btn_vbox), up_btn, FALSE, FALSE, 0);
294 gtk_signal_connect (GTK_OBJECT (up_btn), "clicked",
295 GTK_SIGNAL_FUNC (prefs_display_header_up), NULL);
297 down_btn = gtk_button_new_with_label (_("Down"));
298 gtk_widget_show (down_btn);
299 gtk_box_pack_start (GTK_BOX (btn_vbox), down_btn, FALSE, FALSE, 0);
300 gtk_signal_connect (GTK_OBJECT (down_btn), "clicked",
301 GTK_SIGNAL_FUNC (prefs_display_header_down), NULL);
303 /* hidden headers list */
305 clist_hbox2 = gtk_hbox_new (FALSE, 8);
306 gtk_widget_show (clist_hbox2);
307 gtk_box_pack_start (GTK_BOX (clist_hbox), clist_hbox2, TRUE, TRUE, 0);
309 clist_scrolledwin = gtk_scrolled_window_new (NULL, NULL);
310 gtk_widget_set_usize (clist_scrolledwin, 200, 210);
311 gtk_widget_show (clist_scrolledwin);
312 gtk_box_pack_start (GTK_BOX (clist_hbox2), clist_scrolledwin,
314 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (clist_scrolledwin),
315 GTK_POLICY_AUTOMATIC,
316 GTK_POLICY_AUTOMATIC);
318 title[0] = _("Hidden headers");
319 hidden_headers_clist = gtk_clist_new_with_titles(1, title);
320 gtk_widget_show (hidden_headers_clist);
321 gtk_container_add (GTK_CONTAINER (clist_scrolledwin),
322 hidden_headers_clist);
323 gtk_clist_set_selection_mode (GTK_CLIST (hidden_headers_clist),
324 GTK_SELECTION_BROWSE);
325 gtk_clist_set_auto_sort(GTK_CLIST (hidden_headers_clist), TRUE);
326 GTK_WIDGET_UNSET_FLAGS (GTK_CLIST (hidden_headers_clist)->
327 column[0].button, GTK_CAN_FOCUS);
329 btn_vbox = gtk_vbox_new (FALSE, 8);
330 gtk_widget_show (btn_vbox);
331 gtk_box_pack_start (GTK_BOX (clist_hbox2), btn_vbox, FALSE, FALSE, 0);
333 reg_btn = gtk_button_new_with_label (_("Add"));
334 gtk_widget_show (reg_btn);
335 gtk_box_pack_start (GTK_BOX (btn_vbox), reg_btn, FALSE, TRUE, 0);
336 gtk_signal_connect (GTK_OBJECT (reg_btn), "clicked",
338 (prefs_display_header_register_cb),
340 del_btn = gtk_button_new_with_label (_("Delete"));
341 gtk_widget_show (del_btn);
342 gtk_box_pack_start (GTK_BOX (btn_vbox), del_btn, FALSE, TRUE, 0);
343 gtk_signal_connect (GTK_OBJECT (del_btn), "clicked",
344 GTK_SIGNAL_FUNC (prefs_display_header_delete_cb),
345 (void *) hidden_headers_clist);
347 PACK_CHECK_BUTTON (btn_hbox, checkbtn_other_headers,
348 _("Show other headers"));
349 SET_TOGGLE_SENSITIVITY (checkbtn_other_headers, clist_hbox2);
351 gtk_widget_show_all(window);
353 dispheader.window = window;
354 dispheader.ok_btn = ok_btn;
355 dispheader.cancel_btn = cancel_btn;
357 dispheader.hdr_combo = hdr_combo;
358 dispheader.hdr_entry = GTK_COMBO (hdr_combo)->entry;
360 dispheader.headers_clist = headers_clist;
361 dispheader.hidden_headers_clist = hidden_headers_clist;
363 dispheader.other_headers = checkbtn_other_headers;
366 void prefs_display_header_read_config(void)
370 gchar buf[PREFSBUFSIZE];
371 DisplayHeaderProp *dp;
373 debug_print(_("Reading configuration for displaying headers...\n"));
375 rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
376 DISPLAY_HEADER_RC, NULL);
377 if ((fp = fopen(rcpath, "r")) == NULL) {
378 if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
380 prefs_common.disphdr_list = NULL;
381 prefs_display_header_set_default();
386 /* remove all previous headers list */
387 while (prefs_common.disphdr_list != NULL) {
388 dp = (DisplayHeaderProp *)prefs_common.disphdr_list->data;
389 display_header_prop_free(dp);
390 prefs_common.disphdr_list =
391 g_slist_remove(prefs_common.disphdr_list, dp);
394 while (fgets(buf, sizeof(buf), fp) != NULL) {
396 dp = display_header_prop_read_str(buf);
398 prefs_common.disphdr_list =
399 g_slist_append(prefs_common.disphdr_list, dp);
405 void prefs_display_header_write_config(void)
411 debug_print(_("Writing configuration for displaying headers...\n"));
413 rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
414 DISPLAY_HEADER_RC, NULL);
416 if ((pfile = prefs_write_open(rcpath)) == NULL) {
417 g_warning(_("failed to write configuration to file\n"));
422 for (cur = prefs_common.disphdr_list; cur != NULL;
424 DisplayHeaderProp *dp = (DisplayHeaderProp *)cur->data;
427 dpstr = display_header_prop_get_str(dp);
428 if (fputs(dpstr, pfile->fp) == EOF ||
429 fputc('\n', pfile->fp) == EOF) {
430 FILE_OP_ERROR(rcpath, "fputs || fputc");
431 prefs_write_close_revert(pfile);
441 if (prefs_write_close(pfile) < 0) {
442 g_warning(_("failed to write configuration to file\n"));
447 static void prefs_display_header_set_dialog(void)
449 GtkCList *clist = GTK_CLIST(dispheader.headers_clist);
450 GtkCList *hidden_clist = GTK_CLIST(dispheader.hidden_headers_clist);
455 gtk_clist_freeze(clist);
456 gtk_clist_freeze(hidden_clist);
458 gtk_clist_clear(clist);
459 gtk_clist_clear(hidden_clist);
461 for (cur = prefs_common.disphdr_list; cur != NULL;
463 DisplayHeaderProp *dp = (DisplayHeaderProp *)cur->data;
465 dp_str[0] = dp->name;
468 row = gtk_clist_append(hidden_clist, dp_str);
469 gtk_clist_set_row_data(hidden_clist, row, dp);
471 row = gtk_clist_append(clist, dp_str);
472 gtk_clist_set_row_data(clist, row, dp);
476 gtk_clist_thaw(hidden_clist);
477 gtk_clist_thaw(clist);
479 gtk_toggle_button_set_active
480 (GTK_TOGGLE_BUTTON(dispheader.other_headers),
481 prefs_common.show_other_header);
484 static void prefs_display_header_set_list()
487 DisplayHeaderProp *dp;
489 g_slist_free(prefs_common.disphdr_list);
490 prefs_common.disphdr_list = NULL;
492 while ((dp = gtk_clist_get_row_data
493 (GTK_CLIST(dispheader.headers_clist), row)) != NULL) {
494 prefs_common.disphdr_list =
495 g_slist_append(prefs_common.disphdr_list, dp);
500 while ((dp = gtk_clist_get_row_data
501 (GTK_CLIST(dispheader.hidden_headers_clist), row)) != NULL) {
502 prefs_common.disphdr_list =
503 g_slist_append(prefs_common.disphdr_list, dp);
508 static gint prefs_display_header_find_header(GtkCList *clist,
512 DisplayHeaderProp *dp;
514 while ((dp = gtk_clist_get_row_data(clist, row)) != NULL) {
515 if (g_strcasecmp(dp->name, header) == 0)
523 static gint prefs_display_header_clist_set_row(gboolean hidden)
526 DisplayHeaderProp *dp;
531 entry_text = gtk_entry_get_text(GTK_ENTRY(dispheader.hdr_entry));
532 if (entry_text[0] == '\0') {
533 alertpanel_error(_("Header name is not set."));
538 clist = GTK_CLIST(dispheader.hidden_headers_clist);
540 clist = GTK_CLIST(dispheader.headers_clist);
542 if (prefs_display_header_find_header(clist, entry_text) != -1) {
543 alertpanel_error(_("This header is already in the list."));
547 dp = g_new0(DisplayHeaderProp, 1);
549 dp->name = g_strdup(entry_text);
552 dp_str[0] = dp->name;
553 row = gtk_clist_append(clist, dp_str);
554 gtk_clist_set_row_data(clist, row, dp);
556 prefs_display_header_set_list();
561 static void prefs_display_header_register_cb(GtkButton *btn,
562 gpointer hidden_data)
564 gboolean hidden = (gboolean)hidden_data;
566 prefs_display_header_clist_set_row(hidden);
569 static void prefs_display_header_delete_cb(GtkButton *btn, gpointer clist_data)
571 GtkCList *clist = GTK_CLIST(clist_data);
572 DisplayHeaderProp *dp;
575 if (!clist->selection) return;
576 row = GPOINTER_TO_INT(clist->selection->data);
578 dp = gtk_clist_get_row_data(clist, row);
579 display_header_prop_free(dp);
580 gtk_clist_remove(clist, row);
581 prefs_common.disphdr_list =
582 g_slist_remove(prefs_common.disphdr_list, dp);
585 static void prefs_display_header_up(void)
587 GtkCList *clist = GTK_CLIST(dispheader.headers_clist);
590 if (!clist->selection) return;
592 row = GPOINTER_TO_INT(clist->selection->data);
594 gtk_clist_row_move(clist, row, row - 1);
595 prefs_display_header_set_list();
599 static void prefs_display_header_down(void)
601 GtkCList *clist = GTK_CLIST(dispheader.headers_clist);
604 if (!clist->selection) return;
606 row = GPOINTER_TO_INT(clist->selection->data);
607 if (row >= 0 && row < clist->rows - 1) {
608 gtk_clist_row_move(clist, row, row + 1);
609 prefs_display_header_set_list();
613 static void prefs_display_header_key_pressed(GtkWidget *widget,
617 if (event && event->keyval == GDK_Escape)
618 prefs_display_header_cancel();
621 static void prefs_display_header_ok(void)
623 prefs_common.show_other_header =
624 gtk_toggle_button_get_active
625 (GTK_TOGGLE_BUTTON(dispheader.other_headers));
626 prefs_display_header_write_config();
627 gtk_widget_hide(dispheader.window);
630 static void prefs_display_header_cancel(void)
632 prefs_display_header_read_config();
633 gtk_widget_hide(dispheader.window);
636 static gint prefs_display_header_deleted(GtkWidget *widget, GdkEventAny *event,
639 prefs_display_header_cancel();