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 (prefs_rc_is_readonly(DISPLAY_HEADER_RC))
146 if (!dispheader.window) {
147 prefs_display_header_create();
150 manage_window_set_transient(GTK_WINDOW(dispheader.window));
151 gtk_widget_grab_focus(dispheader.ok_btn);
153 prefs_display_header_set_dialog();
155 gtk_widget_show(dispheader.window);
158 static void prefs_display_header_create(void)
164 GtkWidget *cancel_btn;
165 GtkWidget *confirm_area;
170 GtkWidget *hdr_label;
171 GtkWidget *hdr_combo;
179 GtkWidget *clist_hbox;
180 GtkWidget *clist_hbox1;
181 GtkWidget *clist_hbox2;
182 GtkWidget *clist_scrolledwin;
183 GtkWidget *headers_clist;
184 GtkWidget *hidden_headers_clist;
186 GtkWidget *checkbtn_other_headers;
190 debug_print(_("Creating display header setting window...\n"));
192 window = gtk_window_new (GTK_WINDOW_DIALOG);
193 gtk_container_set_border_width (GTK_CONTAINER (window), 8);
194 gtk_window_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
195 gtk_window_set_modal (GTK_WINDOW (window), TRUE);
196 gtk_window_set_policy (GTK_WINDOW (window), FALSE, TRUE, FALSE);
198 vbox = gtk_vbox_new (FALSE, 6);
199 gtk_widget_show (vbox);
200 gtk_container_add (GTK_CONTAINER (window), vbox);
202 btn_hbox = gtk_hbox_new (FALSE, 8);
203 gtk_widget_show (btn_hbox);
204 gtk_box_pack_end (GTK_BOX (vbox), btn_hbox, FALSE, FALSE, 0);
206 gtkut_button_set_create(&confirm_area, &ok_btn, _("OK"),
207 &cancel_btn, _("Cancel"), NULL, NULL);
208 gtk_widget_show (confirm_area);
209 gtk_box_pack_end (GTK_BOX(btn_hbox), confirm_area, FALSE, FALSE, 0);
210 gtk_widget_grab_default (ok_btn);
212 gtk_window_set_title (GTK_WINDOW(window),
213 _("Display header setting"));
214 gtk_signal_connect (GTK_OBJECT(window), "focus_in_event",
215 GTK_SIGNAL_FUNC(manage_window_focus_in), NULL);
216 gtk_signal_connect (GTK_OBJECT(window), "focus_out_event",
217 GTK_SIGNAL_FUNC(manage_window_focus_out), NULL);
218 gtk_signal_connect (GTK_OBJECT(window), "delete_event",
219 GTK_SIGNAL_FUNC(prefs_display_header_deleted),
221 gtk_signal_connect (GTK_OBJECT(window), "key_press_event",
222 GTK_SIGNAL_FUNC(prefs_display_header_key_pressed),
224 gtk_signal_connect (GTK_OBJECT(ok_btn), "clicked",
225 GTK_SIGNAL_FUNC(prefs_display_header_ok),
227 gtk_signal_connect (GTK_OBJECT(cancel_btn), "clicked",
228 GTK_SIGNAL_FUNC(prefs_display_header_cancel),
231 vbox1 = gtk_vbox_new (FALSE, VSPACING);
232 gtk_widget_show (vbox1);
233 gtk_box_pack_start (GTK_BOX (vbox), vbox1, TRUE, TRUE, 0);
234 gtk_container_set_border_width (GTK_CONTAINER (vbox1), 2);
236 hbox1 = gtk_hbox_new (FALSE, 8);
237 gtk_widget_show (hbox1);
238 gtk_box_pack_start (GTK_BOX (vbox1), hbox1, FALSE, TRUE, 0);
240 hdr_label = gtk_label_new (_("Header name"));
241 gtk_widget_show (hdr_label);
242 gtk_box_pack_start (GTK_BOX (hbox1), hdr_label, FALSE, FALSE, 0);
244 hdr_combo = gtk_combo_new ();
245 gtk_widget_show (hdr_combo);
246 gtk_box_pack_start (GTK_BOX (hbox1), hdr_combo, TRUE, TRUE, 0);
247 gtk_widget_set_usize (hdr_combo, 150, -1);
248 gtkut_combo_set_items (GTK_COMBO (hdr_combo),
249 "From", "To", "Cc", "Subject", "Date",
250 "Reply-To", "Sender", "User-Agent", "X-Mailer",
253 clist_hbox = gtk_hbox_new (FALSE, 10);
254 gtk_widget_show (clist_hbox);
255 gtk_box_pack_start (GTK_BOX (vbox1), clist_hbox, TRUE, TRUE, 0);
257 /* display headers list */
259 clist_hbox1 = gtk_hbox_new (FALSE, 8);
260 gtk_widget_show (clist_hbox1);
261 gtk_box_pack_start (GTK_BOX (clist_hbox), clist_hbox1, TRUE, TRUE, 0);
263 clist_scrolledwin = gtk_scrolled_window_new (NULL, NULL);
264 gtk_widget_set_usize (clist_scrolledwin, 200, 210);
265 gtk_widget_show (clist_scrolledwin);
266 gtk_box_pack_start (GTK_BOX (clist_hbox1), clist_scrolledwin,
268 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (clist_scrolledwin),
269 GTK_POLICY_AUTOMATIC,
270 GTK_POLICY_AUTOMATIC);
272 title[0] = _("Displayed Headers");
273 headers_clist = gtk_clist_new_with_titles(1, title);
274 gtk_widget_show (headers_clist);
275 gtk_container_add (GTK_CONTAINER (clist_scrolledwin), headers_clist);
276 gtk_clist_set_selection_mode (GTK_CLIST (headers_clist),
277 GTK_SELECTION_BROWSE);
278 gtk_clist_set_reorderable (GTK_CLIST (headers_clist), TRUE);
279 gtk_clist_set_use_drag_icons (GTK_CLIST (headers_clist), FALSE);
280 GTK_WIDGET_UNSET_FLAGS (GTK_CLIST (headers_clist)->column[0].button,
282 gtk_signal_connect_after
283 (GTK_OBJECT (headers_clist), "row_move",
284 GTK_SIGNAL_FUNC (prefs_display_header_row_moved), NULL);
286 btn_vbox = gtk_vbox_new (FALSE, 8);
287 gtk_widget_show (btn_vbox);
288 gtk_box_pack_start (GTK_BOX (clist_hbox1), btn_vbox, FALSE, FALSE, 0);
290 reg_btn = gtk_button_new_with_label (_("Add"));
291 gtk_widget_show (reg_btn);
292 gtk_box_pack_start (GTK_BOX (btn_vbox), reg_btn, FALSE, TRUE, 0);
293 gtk_signal_connect (GTK_OBJECT (reg_btn), "clicked",
294 GTK_SIGNAL_FUNC (prefs_display_header_register_cb),
296 del_btn = gtk_button_new_with_label (_("Delete"));
297 gtk_widget_show (del_btn);
298 gtk_box_pack_start (GTK_BOX (btn_vbox), del_btn, FALSE, TRUE, 0);
299 gtk_signal_connect (GTK_OBJECT (del_btn), "clicked",
300 GTK_SIGNAL_FUNC (prefs_display_header_delete_cb),
303 up_btn = gtk_button_new_with_label (_("Up"));
304 gtk_widget_show (up_btn);
305 gtk_box_pack_start (GTK_BOX (btn_vbox), up_btn, FALSE, FALSE, 0);
306 gtk_signal_connect (GTK_OBJECT (up_btn), "clicked",
307 GTK_SIGNAL_FUNC (prefs_display_header_up), NULL);
309 down_btn = gtk_button_new_with_label (_("Down"));
310 gtk_widget_show (down_btn);
311 gtk_box_pack_start (GTK_BOX (btn_vbox), down_btn, FALSE, FALSE, 0);
312 gtk_signal_connect (GTK_OBJECT (down_btn), "clicked",
313 GTK_SIGNAL_FUNC (prefs_display_header_down), NULL);
315 /* hidden headers list */
317 clist_hbox2 = gtk_hbox_new (FALSE, 8);
318 gtk_widget_show (clist_hbox2);
319 gtk_box_pack_start (GTK_BOX (clist_hbox), clist_hbox2, TRUE, TRUE, 0);
321 clist_scrolledwin = gtk_scrolled_window_new (NULL, NULL);
322 gtk_widget_set_usize (clist_scrolledwin, 200, 210);
323 gtk_widget_show (clist_scrolledwin);
324 gtk_box_pack_start (GTK_BOX (clist_hbox2), clist_scrolledwin,
326 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (clist_scrolledwin),
327 GTK_POLICY_AUTOMATIC,
328 GTK_POLICY_AUTOMATIC);
330 title[0] = _("Hidden headers");
331 hidden_headers_clist = gtk_clist_new_with_titles(1, title);
332 gtk_widget_show (hidden_headers_clist);
333 gtk_container_add (GTK_CONTAINER (clist_scrolledwin),
334 hidden_headers_clist);
335 gtk_clist_set_selection_mode (GTK_CLIST (hidden_headers_clist),
336 GTK_SELECTION_BROWSE);
337 gtk_clist_set_auto_sort(GTK_CLIST (hidden_headers_clist), TRUE);
338 GTK_WIDGET_UNSET_FLAGS (GTK_CLIST (hidden_headers_clist)->
339 column[0].button, GTK_CAN_FOCUS);
341 btn_vbox = gtk_vbox_new (FALSE, 8);
342 gtk_widget_show (btn_vbox);
343 gtk_box_pack_start (GTK_BOX (clist_hbox2), btn_vbox, FALSE, FALSE, 0);
345 reg_btn = gtk_button_new_with_label (_("Add"));
346 gtk_widget_show (reg_btn);
347 gtk_box_pack_start (GTK_BOX (btn_vbox), reg_btn, FALSE, TRUE, 0);
348 gtk_signal_connect (GTK_OBJECT (reg_btn), "clicked",
350 (prefs_display_header_register_cb),
352 del_btn = gtk_button_new_with_label (_("Delete"));
353 gtk_widget_show (del_btn);
354 gtk_box_pack_start (GTK_BOX (btn_vbox), del_btn, FALSE, TRUE, 0);
355 gtk_signal_connect (GTK_OBJECT (del_btn), "clicked",
356 GTK_SIGNAL_FUNC (prefs_display_header_delete_cb),
357 (void *) hidden_headers_clist);
359 PACK_CHECK_BUTTON (btn_hbox, checkbtn_other_headers,
360 _("Show all unspecified headers"));
361 SET_TOGGLE_SENSITIVITY (checkbtn_other_headers, clist_hbox2);
363 gtk_widget_show_all(window);
365 dispheader.window = window;
366 dispheader.ok_btn = ok_btn;
367 dispheader.cancel_btn = cancel_btn;
369 dispheader.hdr_combo = hdr_combo;
370 dispheader.hdr_entry = GTK_COMBO (hdr_combo)->entry;
372 dispheader.headers_clist = headers_clist;
373 dispheader.hidden_headers_clist = hidden_headers_clist;
375 dispheader.other_headers = checkbtn_other_headers;
378 void prefs_display_header_read_config(void)
382 gchar buf[PREFSBUFSIZE];
383 DisplayHeaderProp *dp;
385 debug_print(_("Reading configuration for displaying headers...\n"));
387 rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
388 DISPLAY_HEADER_RC, NULL);
389 if ((fp = fopen(rcpath, "r")) == NULL) {
390 if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
392 prefs_common.disphdr_list = NULL;
393 prefs_display_header_set_default();
398 /* remove all previous headers list */
399 while (prefs_common.disphdr_list != NULL) {
400 dp = (DisplayHeaderProp *)prefs_common.disphdr_list->data;
401 display_header_prop_free(dp);
402 prefs_common.disphdr_list =
403 g_slist_remove(prefs_common.disphdr_list, dp);
406 while (fgets(buf, sizeof(buf), fp) != NULL) {
407 g_strdelimit(buf, "\r\n", '\0');
408 dp = display_header_prop_read_str(buf);
410 prefs_common.disphdr_list =
411 g_slist_append(prefs_common.disphdr_list, dp);
417 void prefs_display_header_write_config(void)
423 debug_print(_("Writing configuration for displaying headers...\n"));
425 rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
426 DISPLAY_HEADER_RC, NULL);
428 if ((pfile = prefs_write_open(rcpath)) == NULL) {
429 g_warning(_("failed to write configuration to file\n"));
434 for (cur = prefs_common.disphdr_list; cur != NULL;
436 DisplayHeaderProp *dp = (DisplayHeaderProp *)cur->data;
439 dpstr = display_header_prop_get_str(dp);
440 if (fputs(dpstr, pfile->fp) == EOF ||
441 fputc('\n', pfile->fp) == EOF) {
442 FILE_OP_ERROR(rcpath, "fputs || fputc");
443 prefs_write_close_revert(pfile);
453 if (prefs_write_close(pfile) < 0) {
454 g_warning(_("failed to write configuration to file\n"));
459 static void prefs_display_header_set_dialog(void)
461 GtkCList *clist = GTK_CLIST(dispheader.headers_clist);
462 GtkCList *hidden_clist = GTK_CLIST(dispheader.hidden_headers_clist);
467 gtk_clist_freeze(clist);
468 gtk_clist_freeze(hidden_clist);
470 gtk_clist_clear(clist);
471 gtk_clist_clear(hidden_clist);
473 for (cur = prefs_common.disphdr_list; cur != NULL;
475 DisplayHeaderProp *dp = (DisplayHeaderProp *)cur->data;
477 dp_str[0] = dp->name;
480 row = gtk_clist_append(hidden_clist, dp_str);
481 gtk_clist_set_row_data(hidden_clist, row, dp);
483 row = gtk_clist_append(clist, dp_str);
484 gtk_clist_set_row_data(clist, row, dp);
488 gtk_clist_thaw(hidden_clist);
489 gtk_clist_thaw(clist);
491 gtk_toggle_button_set_active
492 (GTK_TOGGLE_BUTTON(dispheader.other_headers),
493 prefs_common.show_other_header);
496 static void prefs_display_header_set_list()
499 DisplayHeaderProp *dp;
501 g_slist_free(prefs_common.disphdr_list);
502 prefs_common.disphdr_list = NULL;
504 while ((dp = gtk_clist_get_row_data
505 (GTK_CLIST(dispheader.headers_clist), row)) != NULL) {
506 prefs_common.disphdr_list =
507 g_slist_append(prefs_common.disphdr_list, dp);
512 while ((dp = gtk_clist_get_row_data
513 (GTK_CLIST(dispheader.hidden_headers_clist), row)) != NULL) {
514 prefs_common.disphdr_list =
515 g_slist_append(prefs_common.disphdr_list, dp);
520 static gint prefs_display_header_find_header(GtkCList *clist,
524 DisplayHeaderProp *dp;
526 while ((dp = gtk_clist_get_row_data(clist, row)) != NULL) {
527 if (g_strcasecmp(dp->name, header) == 0)
535 static gint prefs_display_header_clist_set_row(gboolean hidden)
538 DisplayHeaderProp *dp;
543 entry_text = gtk_entry_get_text(GTK_ENTRY(dispheader.hdr_entry));
544 if (entry_text[0] == '\0') {
545 alertpanel_error(_("Header name is not set."));
550 clist = GTK_CLIST(dispheader.hidden_headers_clist);
552 clist = GTK_CLIST(dispheader.headers_clist);
554 if (prefs_display_header_find_header(clist, entry_text) != -1) {
555 alertpanel_error(_("This header is already in the list."));
559 dp = g_new0(DisplayHeaderProp, 1);
561 dp->name = g_strdup(entry_text);
564 dp_str[0] = dp->name;
565 row = gtk_clist_append(clist, dp_str);
566 gtk_clist_set_row_data(clist, row, dp);
568 prefs_display_header_set_list();
573 static void prefs_display_header_register_cb(GtkButton *btn,
574 gpointer hidden_data)
576 gboolean hidden = (gboolean)hidden_data;
578 prefs_display_header_clist_set_row(hidden);
581 static void prefs_display_header_delete_cb(GtkButton *btn, gpointer clist_data)
583 GtkCList *clist = GTK_CLIST(clist_data);
584 DisplayHeaderProp *dp;
587 if (!clist->selection) return;
588 row = GPOINTER_TO_INT(clist->selection->data);
590 dp = gtk_clist_get_row_data(clist, row);
591 display_header_prop_free(dp);
592 gtk_clist_remove(clist, row);
593 prefs_common.disphdr_list =
594 g_slist_remove(prefs_common.disphdr_list, dp);
597 static void prefs_display_header_up(void)
599 GtkCList *clist = GTK_CLIST(dispheader.headers_clist);
602 if (!clist->selection) return;
604 row = GPOINTER_TO_INT(clist->selection->data);
606 gtk_clist_row_move(clist, row, row - 1);
609 static void prefs_display_header_down(void)
611 GtkCList *clist = GTK_CLIST(dispheader.headers_clist);
614 if (!clist->selection) return;
616 row = GPOINTER_TO_INT(clist->selection->data);
617 if (row >= 0 && row < clist->rows - 1)
618 gtk_clist_row_move(clist, row, row + 1);
621 static void prefs_display_header_row_moved(GtkCList *clist, gint source_row,
622 gint dest_row, gpointer data)
624 prefs_display_header_set_list();
627 static void prefs_display_header_key_pressed(GtkWidget *widget,
631 if (event && event->keyval == GDK_Escape)
632 prefs_display_header_cancel();
635 static void prefs_display_header_ok(void)
637 prefs_common.show_other_header =
638 gtk_toggle_button_get_active
639 (GTK_TOGGLE_BUTTON(dispheader.other_headers));
640 prefs_display_header_write_config();
641 gtk_widget_hide(dispheader.window);
644 static void prefs_display_header_cancel(void)
646 prefs_display_header_read_config();
647 gtk_widget_hide(dispheader.window);
650 static gint prefs_display_header_deleted(GtkWidget *widget, GdkEventAny *event,
653 prefs_display_header_cancel();