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_row_moved (GtkCList *clist,
91 static void prefs_display_header_key_pressed (GtkWidget *widget,
94 static void prefs_display_header_ok (void);
95 static void prefs_display_header_cancel (void);
96 static gint prefs_display_header_deleted (GtkWidget *widget,
100 static gchar *defaults[] =
121 "-Content-Transfer-Encoding",
129 static void prefs_display_header_set_default(void)
132 DisplayHeaderProp *dp;
134 for(i = 0; i < sizeof(defaults) / sizeof(defaults[0]); i++) {
135 dp = display_header_prop_read_str(defaults[i]);
136 prefs_common.disphdr_list =
137 g_slist_append(prefs_common.disphdr_list, dp);
141 void prefs_display_header_open(void)
143 if (!dispheader.window) {
144 prefs_display_header_create();
147 manage_window_set_transient(GTK_WINDOW(dispheader.window));
148 gtk_widget_grab_focus(dispheader.ok_btn);
150 prefs_display_header_set_dialog();
152 gtk_widget_show(dispheader.window);
155 static void prefs_display_header_create(void)
161 GtkWidget *cancel_btn;
162 GtkWidget *confirm_area;
167 GtkWidget *hdr_label;
168 GtkWidget *hdr_combo;
176 GtkWidget *clist_hbox;
177 GtkWidget *clist_hbox1;
178 GtkWidget *clist_hbox2;
179 GtkWidget *clist_scrolledwin;
180 GtkWidget *headers_clist;
181 GtkWidget *hidden_headers_clist;
183 GtkWidget *checkbtn_other_headers;
187 debug_print(_("Creating display header setting window...\n"));
189 window = gtk_window_new (GTK_WINDOW_DIALOG);
190 gtk_container_set_border_width (GTK_CONTAINER (window), 8);
191 gtk_window_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
192 gtk_window_set_modal (GTK_WINDOW (window), TRUE);
193 gtk_window_set_policy (GTK_WINDOW (window), FALSE, TRUE, FALSE);
195 vbox = gtk_vbox_new (FALSE, 6);
196 gtk_widget_show (vbox);
197 gtk_container_add (GTK_CONTAINER (window), vbox);
199 btn_hbox = gtk_hbox_new (FALSE, 8);
200 gtk_widget_show (btn_hbox);
201 gtk_box_pack_end (GTK_BOX (vbox), btn_hbox, FALSE, FALSE, 0);
203 gtkut_button_set_create(&confirm_area, &ok_btn, _("OK"),
204 &cancel_btn, _("Cancel"), NULL, NULL);
205 gtk_widget_show (confirm_area);
206 gtk_box_pack_end (GTK_BOX(btn_hbox), confirm_area, FALSE, FALSE, 0);
207 gtk_widget_grab_default (ok_btn);
209 gtk_window_set_title (GTK_WINDOW(window),
210 _("Display header setting"));
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(window), "delete_event",
216 GTK_SIGNAL_FUNC(prefs_display_header_deleted),
218 gtk_signal_connect (GTK_OBJECT(window), "key_press_event",
219 GTK_SIGNAL_FUNC(prefs_display_header_key_pressed),
221 gtk_signal_connect (GTK_OBJECT(ok_btn), "clicked",
222 GTK_SIGNAL_FUNC(prefs_display_header_ok),
224 gtk_signal_connect (GTK_OBJECT(cancel_btn), "clicked",
225 GTK_SIGNAL_FUNC(prefs_display_header_cancel),
228 vbox1 = gtk_vbox_new (FALSE, VSPACING);
229 gtk_widget_show (vbox1);
230 gtk_box_pack_start (GTK_BOX (vbox), vbox1, TRUE, TRUE, 0);
231 gtk_container_set_border_width (GTK_CONTAINER (vbox1), 2);
233 hbox1 = gtk_hbox_new (FALSE, 8);
234 gtk_widget_show (hbox1);
235 gtk_box_pack_start (GTK_BOX (vbox1), hbox1, FALSE, TRUE, 0);
237 hdr_label = gtk_label_new (_("Header name"));
238 gtk_widget_show (hdr_label);
239 gtk_box_pack_start (GTK_BOX (hbox1), hdr_label, FALSE, FALSE, 0);
241 hdr_combo = gtk_combo_new ();
242 gtk_widget_show (hdr_combo);
243 gtk_box_pack_start (GTK_BOX (hbox1), hdr_combo, TRUE, TRUE, 0);
244 gtk_widget_set_usize (hdr_combo, 150, -1);
245 gtkut_combo_set_items (GTK_COMBO (hdr_combo),
246 "From", "To", "Cc", "Subject", "Date",
247 "Reply-To", "Sender", "User-Agent", "X-Mailer",
250 clist_hbox = gtk_hbox_new (FALSE, 10);
251 gtk_widget_show (clist_hbox);
252 gtk_box_pack_start (GTK_BOX (vbox1), clist_hbox, TRUE, TRUE, 0);
254 /* display headers list */
256 clist_hbox1 = gtk_hbox_new (FALSE, 8);
257 gtk_widget_show (clist_hbox1);
258 gtk_box_pack_start (GTK_BOX (clist_hbox), clist_hbox1, TRUE, TRUE, 0);
260 clist_scrolledwin = gtk_scrolled_window_new (NULL, NULL);
261 gtk_widget_set_usize (clist_scrolledwin, 200, 210);
262 gtk_widget_show (clist_scrolledwin);
263 gtk_box_pack_start (GTK_BOX (clist_hbox1), clist_scrolledwin,
265 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (clist_scrolledwin),
266 GTK_POLICY_AUTOMATIC,
267 GTK_POLICY_AUTOMATIC);
269 title[0] = _("Displayed Headers");
270 headers_clist = gtk_clist_new_with_titles(1, title);
271 gtk_widget_show (headers_clist);
272 gtk_container_add (GTK_CONTAINER (clist_scrolledwin), headers_clist);
273 gtk_clist_set_selection_mode (GTK_CLIST (headers_clist),
274 GTK_SELECTION_BROWSE);
275 gtk_clist_set_reorderable (GTK_CLIST (headers_clist), TRUE);
276 gtk_clist_set_use_drag_icons (GTK_CLIST (headers_clist), FALSE);
277 GTK_WIDGET_UNSET_FLAGS (GTK_CLIST (headers_clist)->column[0].button,
279 gtk_signal_connect_after
280 (GTK_OBJECT (headers_clist), "row_move",
281 GTK_SIGNAL_FUNC (prefs_display_header_row_moved), NULL);
283 btn_vbox = gtk_vbox_new (FALSE, 8);
284 gtk_widget_show (btn_vbox);
285 gtk_box_pack_start (GTK_BOX (clist_hbox1), btn_vbox, FALSE, FALSE, 0);
287 reg_btn = gtk_button_new_with_label (_("Add"));
288 gtk_widget_show (reg_btn);
289 gtk_box_pack_start (GTK_BOX (btn_vbox), reg_btn, FALSE, TRUE, 0);
290 gtk_signal_connect (GTK_OBJECT (reg_btn), "clicked",
291 GTK_SIGNAL_FUNC (prefs_display_header_register_cb),
293 del_btn = gtk_button_new_with_label (_("Delete"));
294 gtk_widget_show (del_btn);
295 gtk_box_pack_start (GTK_BOX (btn_vbox), del_btn, FALSE, TRUE, 0);
296 gtk_signal_connect (GTK_OBJECT (del_btn), "clicked",
297 GTK_SIGNAL_FUNC (prefs_display_header_delete_cb),
300 up_btn = gtk_button_new_with_label (_("Up"));
301 gtk_widget_show (up_btn);
302 gtk_box_pack_start (GTK_BOX (btn_vbox), up_btn, FALSE, FALSE, 0);
303 gtk_signal_connect (GTK_OBJECT (up_btn), "clicked",
304 GTK_SIGNAL_FUNC (prefs_display_header_up), NULL);
306 down_btn = gtk_button_new_with_label (_("Down"));
307 gtk_widget_show (down_btn);
308 gtk_box_pack_start (GTK_BOX (btn_vbox), down_btn, FALSE, FALSE, 0);
309 gtk_signal_connect (GTK_OBJECT (down_btn), "clicked",
310 GTK_SIGNAL_FUNC (prefs_display_header_down), NULL);
312 /* hidden headers list */
314 clist_hbox2 = gtk_hbox_new (FALSE, 8);
315 gtk_widget_show (clist_hbox2);
316 gtk_box_pack_start (GTK_BOX (clist_hbox), clist_hbox2, TRUE, TRUE, 0);
318 clist_scrolledwin = gtk_scrolled_window_new (NULL, NULL);
319 gtk_widget_set_usize (clist_scrolledwin, 200, 210);
320 gtk_widget_show (clist_scrolledwin);
321 gtk_box_pack_start (GTK_BOX (clist_hbox2), clist_scrolledwin,
323 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (clist_scrolledwin),
324 GTK_POLICY_AUTOMATIC,
325 GTK_POLICY_AUTOMATIC);
327 title[0] = _("Hidden headers");
328 hidden_headers_clist = gtk_clist_new_with_titles(1, title);
329 gtk_widget_show (hidden_headers_clist);
330 gtk_container_add (GTK_CONTAINER (clist_scrolledwin),
331 hidden_headers_clist);
332 gtk_clist_set_selection_mode (GTK_CLIST (hidden_headers_clist),
333 GTK_SELECTION_BROWSE);
334 gtk_clist_set_auto_sort(GTK_CLIST (hidden_headers_clist), TRUE);
335 GTK_WIDGET_UNSET_FLAGS (GTK_CLIST (hidden_headers_clist)->
336 column[0].button, GTK_CAN_FOCUS);
338 btn_vbox = gtk_vbox_new (FALSE, 8);
339 gtk_widget_show (btn_vbox);
340 gtk_box_pack_start (GTK_BOX (clist_hbox2), btn_vbox, FALSE, FALSE, 0);
342 reg_btn = gtk_button_new_with_label (_("Add"));
343 gtk_widget_show (reg_btn);
344 gtk_box_pack_start (GTK_BOX (btn_vbox), reg_btn, FALSE, TRUE, 0);
345 gtk_signal_connect (GTK_OBJECT (reg_btn), "clicked",
347 (prefs_display_header_register_cb),
349 del_btn = gtk_button_new_with_label (_("Delete"));
350 gtk_widget_show (del_btn);
351 gtk_box_pack_start (GTK_BOX (btn_vbox), del_btn, FALSE, TRUE, 0);
352 gtk_signal_connect (GTK_OBJECT (del_btn), "clicked",
353 GTK_SIGNAL_FUNC (prefs_display_header_delete_cb),
354 (void *) hidden_headers_clist);
356 PACK_CHECK_BUTTON (btn_hbox, checkbtn_other_headers,
357 _("Show all unspecified headers"));
358 SET_TOGGLE_SENSITIVITY (checkbtn_other_headers, clist_hbox2);
360 gtk_widget_show_all(window);
362 dispheader.window = window;
363 dispheader.ok_btn = ok_btn;
364 dispheader.cancel_btn = cancel_btn;
366 dispheader.hdr_combo = hdr_combo;
367 dispheader.hdr_entry = GTK_COMBO (hdr_combo)->entry;
369 dispheader.headers_clist = headers_clist;
370 dispheader.hidden_headers_clist = hidden_headers_clist;
372 dispheader.other_headers = checkbtn_other_headers;
375 void prefs_display_header_read_config(void)
379 gchar buf[PREFSBUFSIZE];
380 DisplayHeaderProp *dp;
382 debug_print(_("Reading configuration for displaying headers...\n"));
384 rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
385 DISPLAY_HEADER_RC, NULL);
386 if ((fp = fopen(rcpath, "r")) == NULL) {
387 if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
389 prefs_common.disphdr_list = NULL;
390 prefs_display_header_set_default();
395 /* remove all previous headers list */
396 while (prefs_common.disphdr_list != NULL) {
397 dp = (DisplayHeaderProp *)prefs_common.disphdr_list->data;
398 display_header_prop_free(dp);
399 prefs_common.disphdr_list =
400 g_slist_remove(prefs_common.disphdr_list, dp);
403 while (fgets(buf, sizeof(buf), fp) != NULL) {
405 dp = display_header_prop_read_str(buf);
407 prefs_common.disphdr_list =
408 g_slist_append(prefs_common.disphdr_list, dp);
414 void prefs_display_header_write_config(void)
420 debug_print(_("Writing configuration for displaying headers...\n"));
422 rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
423 DISPLAY_HEADER_RC, NULL);
425 if ((pfile = prefs_write_open(rcpath)) == NULL) {
426 g_warning(_("failed to write configuration to file\n"));
431 for (cur = prefs_common.disphdr_list; cur != NULL;
433 DisplayHeaderProp *dp = (DisplayHeaderProp *)cur->data;
436 dpstr = display_header_prop_get_str(dp);
437 if (fputs(dpstr, pfile->fp) == EOF ||
438 fputc('\n', pfile->fp) == EOF) {
439 FILE_OP_ERROR(rcpath, "fputs || fputc");
440 prefs_write_close_revert(pfile);
450 if (prefs_write_close(pfile) < 0) {
451 g_warning(_("failed to write configuration to file\n"));
456 static void prefs_display_header_set_dialog(void)
458 GtkCList *clist = GTK_CLIST(dispheader.headers_clist);
459 GtkCList *hidden_clist = GTK_CLIST(dispheader.hidden_headers_clist);
464 gtk_clist_freeze(clist);
465 gtk_clist_freeze(hidden_clist);
467 gtk_clist_clear(clist);
468 gtk_clist_clear(hidden_clist);
470 for (cur = prefs_common.disphdr_list; cur != NULL;
472 DisplayHeaderProp *dp = (DisplayHeaderProp *)cur->data;
474 dp_str[0] = dp->name;
477 row = gtk_clist_append(hidden_clist, dp_str);
478 gtk_clist_set_row_data(hidden_clist, row, dp);
480 row = gtk_clist_append(clist, dp_str);
481 gtk_clist_set_row_data(clist, row, dp);
485 gtk_clist_thaw(hidden_clist);
486 gtk_clist_thaw(clist);
488 gtk_toggle_button_set_active
489 (GTK_TOGGLE_BUTTON(dispheader.other_headers),
490 prefs_common.show_other_header);
493 static void prefs_display_header_set_list()
496 DisplayHeaderProp *dp;
498 g_slist_free(prefs_common.disphdr_list);
499 prefs_common.disphdr_list = NULL;
501 while ((dp = gtk_clist_get_row_data
502 (GTK_CLIST(dispheader.headers_clist), row)) != NULL) {
503 prefs_common.disphdr_list =
504 g_slist_append(prefs_common.disphdr_list, dp);
509 while ((dp = gtk_clist_get_row_data
510 (GTK_CLIST(dispheader.hidden_headers_clist), row)) != NULL) {
511 prefs_common.disphdr_list =
512 g_slist_append(prefs_common.disphdr_list, dp);
517 static gint prefs_display_header_find_header(GtkCList *clist,
521 DisplayHeaderProp *dp;
523 while ((dp = gtk_clist_get_row_data(clist, row)) != NULL) {
524 if (g_strcasecmp(dp->name, header) == 0)
532 static gint prefs_display_header_clist_set_row(gboolean hidden)
535 DisplayHeaderProp *dp;
540 entry_text = gtk_entry_get_text(GTK_ENTRY(dispheader.hdr_entry));
541 if (entry_text[0] == '\0') {
542 alertpanel_error(_("Header name is not set."));
547 clist = GTK_CLIST(dispheader.hidden_headers_clist);
549 clist = GTK_CLIST(dispheader.headers_clist);
551 if (prefs_display_header_find_header(clist, entry_text) != -1) {
552 alertpanel_error(_("This header is already in the list."));
556 dp = g_new0(DisplayHeaderProp, 1);
558 dp->name = g_strdup(entry_text);
561 dp_str[0] = dp->name;
562 row = gtk_clist_append(clist, dp_str);
563 gtk_clist_set_row_data(clist, row, dp);
565 prefs_display_header_set_list();
570 static void prefs_display_header_register_cb(GtkButton *btn,
571 gpointer hidden_data)
573 gboolean hidden = (gboolean)hidden_data;
575 prefs_display_header_clist_set_row(hidden);
578 static void prefs_display_header_delete_cb(GtkButton *btn, gpointer clist_data)
580 GtkCList *clist = GTK_CLIST(clist_data);
581 DisplayHeaderProp *dp;
584 if (!clist->selection) return;
585 row = GPOINTER_TO_INT(clist->selection->data);
587 dp = gtk_clist_get_row_data(clist, row);
588 display_header_prop_free(dp);
589 gtk_clist_remove(clist, row);
590 prefs_common.disphdr_list =
591 g_slist_remove(prefs_common.disphdr_list, dp);
594 static void prefs_display_header_up(void)
596 GtkCList *clist = GTK_CLIST(dispheader.headers_clist);
599 if (!clist->selection) return;
601 row = GPOINTER_TO_INT(clist->selection->data);
603 gtk_clist_row_move(clist, row, row - 1);
606 static void prefs_display_header_down(void)
608 GtkCList *clist = GTK_CLIST(dispheader.headers_clist);
611 if (!clist->selection) return;
613 row = GPOINTER_TO_INT(clist->selection->data);
614 if (row >= 0 && row < clist->rows - 1)
615 gtk_clist_row_move(clist, row, row + 1);
618 static void prefs_display_header_row_moved(GtkCList *clist, gint source_row,
619 gint dest_row, gpointer data)
621 prefs_display_header_set_list();
624 static void prefs_display_header_key_pressed(GtkWidget *widget,
628 if (event && event->keyval == GDK_Escape)
629 prefs_display_header_cancel();
632 static void prefs_display_header_ok(void)
634 prefs_common.show_other_header =
635 gtk_toggle_button_get_active
636 (GTK_TOGGLE_BUTTON(dispheader.other_headers));
637 prefs_display_header_write_config();
638 gtk_widget_hide(dispheader.window);
641 static void prefs_display_header_cancel(void)
643 prefs_display_header_read_config();
644 gtk_widget_hide(dispheader.window);
647 static gint prefs_display_header_deleted(GtkWidget *widget, GdkEventAny *event,
650 prefs_display_header_cancel();