1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 1999-2005 Hiroyuki Yamamoto
4  *
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.
9  *
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.
14  *
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.
18  */
19 
20 #ifdef HAVE_CONFIG_H
21 #  include "config.h"
22 #endif
23 
24 #include "defs.h"
25 
26 #include <glib.h>
27 #include <glib/gi18n.h>
28 #include <gtk/gtk.h>
29 #include <gdk/gdkkeysyms.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <errno.h>
34 
35 #include "prefs.h"
36 #include "prefs_ui.h"
37 #include "prefs_display_header.h"
38 #include "prefs_common.h"
39 #include "manage_window.h"
40 #include "alertpanel.h"
41 #include "displayheader.h"
42 #include "utils.h"
43 #include "gtkutils.h"
44 
45 static struct DisplayHeader {
46 	GtkWidget *window;
47 
48 	GtkWidget *confirm_area;
49 	GtkWidget *ok_btn;
50 	GtkWidget *cancel_btn;
51 
52 	GtkWidget *hdr_combo;
53 	GtkWidget *hdr_entry;
54 	GtkWidget *key_check;
55 	GtkWidget *headers_clist;
56 	GtkWidget *hidden_headers_clist;
57 
58 	GtkWidget *other_headers;
59 } dispheader;
60 
61 /* widget creating functions */
62 static void prefs_display_header_create	(void);
63 
64 static void prefs_display_header_set_dialog	(void);
65 static void prefs_display_header_set_list	(void);
66 static gint prefs_display_header_clist_set_row	(gboolean hidden);
67 
68 /* callback functions */
69 static void prefs_display_header_register_cb	(GtkButton	*btn,
70 						 gpointer	 hidden_data);
71 static void prefs_display_header_delete_cb	(GtkButton	*btn,
72 						 gpointer	 clist_data);
73 static void prefs_display_header_up		(void);
74 static void prefs_display_header_down		(void);
75 
76 static void prefs_display_header_row_moved	(GtkCList	*clist,
77 						 gint		 source_row,
78 						 gint		 dest_row,
79 						 gpointer	 data);
80 
81 static gboolean prefs_display_header_key_pressed(GtkWidget	*widget,
82 						 GdkEventKey	*event,
83 						 gpointer	 data);
84 static void prefs_display_header_ok		(void);
85 static void prefs_display_header_cancel		(void);
86 static gint prefs_display_header_deleted	(GtkWidget	*widget,
87 						 GdkEventAny	*event,
88 						 gpointer	 data);
89 
90 static gchar *defaults[] =
91 {
92 	"From",
93 	"To",
94 	"Cc",
95 	"Reply-To",
96 	"Newsgroups",
97 	"Followup-To",
98 	"Subject",
99 	"Date",
100 	"Sender",
101 	"Organization",
102 	"X-Mailer",
103 	"X-Newsreader",
104 	"User-Agent",
105 	"-Received",
106 	"-Message-Id",
107 	"-In-Reply-To",
108 	"-References",
109 	"-Mime-Version",
110 	"-Content-Type",
111 	"-Content-Transfer-Encoding",
112 	"-X-UIDL",
113 	"-Precedence",
114 	"-Status",
115 	"-Priority",
116 	"-X-Face"
117 };
118 
prefs_display_header_set_default(void)119 static void prefs_display_header_set_default(void)
120 {
121 	gint i;
122 	DisplayHeaderProp *dp;
123 
124 	for(i = 0; i < sizeof(defaults) / sizeof(defaults[0]); i++) {
125 		dp = display_header_prop_read_str(defaults[i]);
126 		prefs_common.disphdr_list =
127 			g_slist_append(prefs_common.disphdr_list, dp);
128 	}
129 }
130 
prefs_display_header_open(void)131 void prefs_display_header_open(void)
132 {
133 	if (!dispheader.window) {
134 		prefs_display_header_create();
135 	}
136 
137 	gtkut_box_set_reverse_order(GTK_BOX(dispheader.confirm_area),
138 				    !prefs_common.comply_gnome_hig);
139 	manage_window_set_transient(GTK_WINDOW(dispheader.window));
140 	gtk_widget_grab_focus(dispheader.ok_btn);
141 
142 	prefs_display_header_set_dialog();
143 
144 	gtk_widget_show(dispheader.window);
145 }
146 
prefs_display_header_create(void)147 static void prefs_display_header_create(void)
148 {
149 	GtkWidget *window;
150 	GtkWidget *vbox;
151 	GtkWidget *btn_hbox;
152 	GtkWidget *confirm_area;
153 	GtkWidget *ok_btn;
154 	GtkWidget *cancel_btn;
155 
156 	GtkWidget *vbox1;
157 
158 	GtkWidget *hbox1;
159 	GtkWidget *hdr_label;
160 	GtkWidget *hdr_combo;
161 
162 	GtkWidget *btn_vbox;
163 	GtkWidget *reg_btn;
164 	GtkWidget *del_btn;
165 	GtkWidget *up_btn;
166 	GtkWidget *down_btn;
167 
168 	GtkWidget *clist_hbox;
169 	GtkWidget *clist_hbox1;
170 	GtkWidget *clist_hbox2;
171 	GtkWidget *clist_scrolledwin;
172 	GtkWidget *headers_clist;
173 	GtkWidget *hidden_headers_clist;
174 
175 	GtkWidget *checkbtn_other_headers;
176 
177 	gchar *title[1];
178 
179 	debug_print(_("Creating display header setting window...\n"));
180 
181 	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
182 	gtk_container_set_border_width (GTK_CONTAINER (window), 8);
183 	gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
184 	gtk_window_set_modal (GTK_WINDOW (window), TRUE);
185 	gtk_window_set_policy (GTK_WINDOW (window), FALSE, TRUE, FALSE);
186 
187 	vbox = gtk_vbox_new (FALSE, 6);
188 	gtk_widget_show (vbox);
189 	gtk_container_add (GTK_CONTAINER (window), vbox);
190 
191 	btn_hbox = gtk_hbox_new (FALSE, 8);
192 	gtk_widget_show (btn_hbox);
193 	gtk_box_pack_end (GTK_BOX (vbox), btn_hbox, FALSE, FALSE, 0);
194 
195 	gtkut_stock_button_set_create(&confirm_area, &ok_btn, GTK_STOCK_OK,
196 				      &cancel_btn, GTK_STOCK_CANCEL,
197 				      NULL, NULL);
198 	gtk_widget_show (confirm_area);
199 	gtk_box_pack_end (GTK_BOX(btn_hbox), confirm_area, FALSE, FALSE, 0);
200 	gtk_widget_grab_default (ok_btn);
201 
202 	gtk_window_set_title (GTK_WINDOW(window),
203 			      _("Display header setting"));
204 	MANAGE_WINDOW_SIGNALS_CONNECT(window);
205 	g_signal_connect (G_OBJECT(window), "delete_event",
206 			  G_CALLBACK(prefs_display_header_deleted), NULL);
207 	g_signal_connect (G_OBJECT(window), "key_press_event",
208 			  G_CALLBACK(prefs_display_header_key_pressed), NULL);
209 	g_signal_connect (G_OBJECT(ok_btn), "clicked",
210 			  G_CALLBACK(prefs_display_header_ok), NULL);
211 	g_signal_connect (G_OBJECT(cancel_btn), "clicked",
212 			  G_CALLBACK(prefs_display_header_cancel), NULL);
213 
214 	vbox1 = gtk_vbox_new (FALSE, VSPACING);
215 	gtk_widget_show (vbox1);
216 	gtk_box_pack_start (GTK_BOX (vbox), vbox1, TRUE, TRUE, 0);
217 	gtk_container_set_border_width (GTK_CONTAINER (vbox1), 2);
218 
219 	hbox1 = gtk_hbox_new (FALSE, 8);
220 	gtk_widget_show (hbox1);
221 	gtk_box_pack_start (GTK_BOX (vbox1), hbox1, FALSE, TRUE, 0);
222 
223 	hdr_label = gtk_label_new (_("Header name"));
224 	gtk_widget_show (hdr_label);
225 	gtk_box_pack_start (GTK_BOX (hbox1), hdr_label, FALSE, FALSE, 0);
226 
227 	hdr_combo = gtk_combo_new ();
228 	gtk_widget_show (hdr_combo);
229 	gtk_box_pack_start (GTK_BOX (hbox1), hdr_combo, TRUE, TRUE, 0);
230 	gtk_widget_set_size_request (hdr_combo, 150, -1);
231 	gtkut_combo_set_items (GTK_COMBO (hdr_combo),
232 			       "From", "To", "Cc", "Subject", "Date",
233 			       "Reply-To", "Sender", "User-Agent", "X-Mailer",
234 			       NULL);
235 
236 	clist_hbox = gtk_hbox_new (FALSE, 10);
237 	gtk_widget_show (clist_hbox);
238 	gtk_box_pack_start (GTK_BOX (vbox1), clist_hbox, TRUE, TRUE, 0);
239 
240 	/* display headers list */
241 
242 	clist_hbox1 = gtk_hbox_new (FALSE, 8);
243 	gtk_widget_show (clist_hbox1);
244 	gtk_box_pack_start (GTK_BOX (clist_hbox), clist_hbox1, TRUE, TRUE, 0);
245 
246 	clist_scrolledwin = gtk_scrolled_window_new (NULL, NULL);
247 	gtk_widget_set_size_request (clist_scrolledwin, 200, 210);
248 	gtk_widget_show (clist_scrolledwin);
249 	gtk_box_pack_start (GTK_BOX (clist_hbox1), clist_scrolledwin,
250 			    TRUE, TRUE, 0);
251 	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (clist_scrolledwin),
252 					GTK_POLICY_AUTOMATIC,
253 					GTK_POLICY_AUTOMATIC);
254 
255 	title[0] = _("Displayed Headers");
256 	headers_clist = gtk_clist_new_with_titles(1, title);
257 	gtk_widget_show (headers_clist);
258 	gtk_container_add (GTK_CONTAINER (clist_scrolledwin), headers_clist);
259 	gtk_clist_set_selection_mode (GTK_CLIST (headers_clist),
260 				      GTK_SELECTION_BROWSE);
261 	gtk_clist_set_reorderable (GTK_CLIST (headers_clist), TRUE);
262 	gtk_clist_set_use_drag_icons (GTK_CLIST (headers_clist), FALSE);
263 	gtkut_clist_set_redraw (GTK_CLIST (headers_clist));
264 	GTK_WIDGET_UNSET_FLAGS (GTK_CLIST (headers_clist)->column[0].button,
265 				GTK_CAN_FOCUS);
266 	g_signal_connect_after
267 		(G_OBJECT (headers_clist), "row_move",
268 		 G_CALLBACK (prefs_display_header_row_moved), NULL);
269 
270 	btn_vbox = gtk_vbox_new (FALSE, 8);
271 	gtk_widget_show (btn_vbox);
272 	gtk_box_pack_start (GTK_BOX (clist_hbox1), btn_vbox, FALSE, FALSE, 0);
273 
274 	reg_btn = gtk_button_new_with_label (_("Add"));
275 	gtk_widget_show (reg_btn);
276 	gtk_box_pack_start (GTK_BOX (btn_vbox), reg_btn, FALSE, TRUE, 0);
277 	g_signal_connect (G_OBJECT (reg_btn), "clicked",
278 			  G_CALLBACK (prefs_display_header_register_cb),
279 			  GINT_TO_POINTER(FALSE));
280 	del_btn = gtk_button_new_with_label (_("Delete"));
281 	gtk_widget_show (del_btn);
282 	gtk_box_pack_start (GTK_BOX (btn_vbox), del_btn, FALSE, TRUE, 0);
283 	g_signal_connect (G_OBJECT (del_btn), "clicked",
284 			  G_CALLBACK (prefs_display_header_delete_cb),
285 			  headers_clist);
286 
287 	up_btn = gtk_button_new_with_label (_("Up"));
288 	gtk_widget_show (up_btn);
289 	gtk_box_pack_start (GTK_BOX (btn_vbox), up_btn, FALSE, FALSE, 0);
290 	g_signal_connect (G_OBJECT (up_btn), "clicked",
291 			  G_CALLBACK (prefs_display_header_up), NULL);
292 
293 	down_btn = gtk_button_new_with_label (_("Down"));
294 	gtk_widget_show (down_btn);
295 	gtk_box_pack_start (GTK_BOX (btn_vbox), down_btn, FALSE, FALSE, 0);
296 	g_signal_connect (G_OBJECT (down_btn), "clicked",
297 			  G_CALLBACK (prefs_display_header_down), NULL);
298 
299 	/* hidden headers list */
300 
301 	clist_hbox2 = gtk_hbox_new (FALSE, 8);
302 	gtk_widget_show (clist_hbox2);
303 	gtk_box_pack_start (GTK_BOX (clist_hbox), clist_hbox2, TRUE, TRUE, 0);
304 
305 	clist_scrolledwin = gtk_scrolled_window_new (NULL, NULL);
306 	gtk_widget_set_size_request (clist_scrolledwin, 200, 210);
307 	gtk_widget_show (clist_scrolledwin);
308 	gtk_box_pack_start (GTK_BOX (clist_hbox2), clist_scrolledwin,
309 			    TRUE, TRUE, 0);
310 	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (clist_scrolledwin),
311 					GTK_POLICY_AUTOMATIC,
312 					GTK_POLICY_AUTOMATIC);
313 
314 	title[0] = _("Hidden headers");
315 	hidden_headers_clist = gtk_clist_new_with_titles(1, title);
316 	gtk_widget_show (hidden_headers_clist);
317 	gtk_container_add (GTK_CONTAINER (clist_scrolledwin),
318 			   hidden_headers_clist);
319 	gtk_clist_set_selection_mode (GTK_CLIST (hidden_headers_clist),
320 				      GTK_SELECTION_BROWSE);
321 	gtk_clist_set_auto_sort(GTK_CLIST (hidden_headers_clist), TRUE);
322 	gtkut_clist_set_redraw (GTK_CLIST (hidden_headers_clist));
323 	GTK_WIDGET_UNSET_FLAGS (GTK_CLIST (hidden_headers_clist)->
324 				column[0].button, GTK_CAN_FOCUS);
325 
326 	btn_vbox = gtk_vbox_new (FALSE, 8);
327 	gtk_widget_show (btn_vbox);
328 	gtk_box_pack_start (GTK_BOX (clist_hbox2), btn_vbox, FALSE, FALSE, 0);
329 
330 	reg_btn = gtk_button_new_with_label (_("Add"));
331 	gtk_widget_show (reg_btn);
332 	gtk_box_pack_start (GTK_BOX (btn_vbox), reg_btn, FALSE, TRUE, 0);
333 	g_signal_connect (G_OBJECT (reg_btn), "clicked",
334 			  G_CALLBACK (prefs_display_header_register_cb),
335 			  GINT_TO_POINTER (TRUE));
336 	del_btn = gtk_button_new_with_label (_("Delete"));
337 	gtk_widget_show (del_btn);
338 	gtk_box_pack_start (GTK_BOX (btn_vbox), del_btn, FALSE, TRUE, 0);
339 	g_signal_connect (G_OBJECT (del_btn), "clicked",
340 			  G_CALLBACK (prefs_display_header_delete_cb),
341 			  hidden_headers_clist);
342 
343 	PACK_CHECK_BUTTON (btn_hbox, checkbtn_other_headers,
344 			   _("Show all unspecified headers"));
345 	SET_TOGGLE_SENSITIVITY (checkbtn_other_headers, clist_hbox2);
346 
347 	gtk_widget_show_all(window);
348 
349 	dispheader.window        = window;
350 
351 	dispheader.confirm_area  = confirm_area;
352 	dispheader.ok_btn        = ok_btn;
353 	dispheader.cancel_btn    = cancel_btn;
354 
355 	dispheader.hdr_combo     = hdr_combo;
356 	dispheader.hdr_entry     = GTK_COMBO (hdr_combo)->entry;
357 
358 	dispheader.headers_clist        = headers_clist;
359 	dispheader.hidden_headers_clist = hidden_headers_clist;
360 
361 	dispheader.other_headers = checkbtn_other_headers;
362 }
363 
prefs_display_header_read_config(void)364 void prefs_display_header_read_config(void)
365 {
366 	gchar *rcpath;
367 	FILE *fp;
368 	gchar buf[PREFSBUFSIZE];
369 	DisplayHeaderProp *dp;
370 
371 	debug_print(_("Reading configuration for displaying headers...\n"));
372 
373 	rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
374 			     DISPLAY_HEADER_RC, NULL);
375 	if ((fp = g_fopen(rcpath, "rb")) == NULL) {
376 		if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
377 		g_free(rcpath);
378 		prefs_common.disphdr_list = NULL;
379 		prefs_display_header_set_default();
380 		return;
381 	}
382 	g_free(rcpath);
383 
384 	/* remove all previous headers list */
385 	while (prefs_common.disphdr_list != NULL) {
386 		dp = (DisplayHeaderProp *)prefs_common.disphdr_list->data;
387 		display_header_prop_free(dp);
388 		prefs_common.disphdr_list =
389 			g_slist_remove(prefs_common.disphdr_list, dp);
390 	}
391 
392 	while (fgets(buf, sizeof(buf), fp) != NULL) {
393 		g_strchomp(buf);
394 		dp = display_header_prop_read_str(buf);
395 		if (dp)
396 			prefs_common.disphdr_list =
397 				g_slist_append(prefs_common.disphdr_list, dp);
398 	}
399 
400 	fclose(fp);
401 }
402 
prefs_display_header_write_config(void)403 void prefs_display_header_write_config(void)
404 {
405 	gchar *rcpath;
406 	PrefFile *pfile;
407 	GSList *cur;
408 
409 	debug_print(_("Writing configuration for displaying headers...\n"));
410 
411 	rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
412 			     DISPLAY_HEADER_RC, NULL);
413 
414 	if ((pfile = prefs_file_open(rcpath)) == NULL) {
415 		g_warning(_("failed to write configuration to file\n"));
416 		g_free(rcpath);
417 		return;
418 	}
419 
420 	for (cur = prefs_common.disphdr_list; cur != NULL;
421 	     cur = cur->next) {
422 		DisplayHeaderProp *dp = (DisplayHeaderProp *)cur->data;
423 		gchar *dpstr;
424 
425 		dpstr = display_header_prop_get_str(dp);
426 		if (fputs(dpstr, pfile->fp) == EOF ||
427 		    fputc('\n', pfile->fp) == EOF) {
428 			FILE_OP_ERROR(rcpath, "fputs || fputc");
429 			prefs_file_close_revert(pfile);
430 			g_free(rcpath);
431 			g_free(dpstr);
432 			return;
433 		}
434 		g_free(dpstr);
435 	}
436 
437 	g_free(rcpath);
438 
439 	if (prefs_file_close(pfile) < 0) {
440 		g_warning(_("failed to write configuration to file\n"));
441 		return;
442 	}
443 }
444 
prefs_display_header_set_dialog(void)445 static void prefs_display_header_set_dialog(void)
446 {
447 	GtkCList *clist = GTK_CLIST(dispheader.headers_clist);
448 	GtkCList *hidden_clist = GTK_CLIST(dispheader.hidden_headers_clist);
449 	GSList *cur;
450 	gchar *dp_str[1];
451 	gint row;
452 
453 	gtk_clist_freeze(clist);
454 	gtk_clist_freeze(hidden_clist);
455 
456 	gtk_clist_clear(clist);
457 	gtk_clist_clear(hidden_clist);
458 
459 	for (cur = prefs_common.disphdr_list; cur != NULL;
460 	     cur = cur->next) {
461 		DisplayHeaderProp *dp = (DisplayHeaderProp *)cur->data;
462 
463 		dp_str[0] = dp->name;
464 
465 		if (dp->hidden) {
466 			row = gtk_clist_append(hidden_clist, dp_str);
467 			gtk_clist_set_row_data(hidden_clist, row, dp);
468 		} else {
469 			row = gtk_clist_append(clist, dp_str);
470 			gtk_clist_set_row_data(clist, row, dp);
471 		}
472 	}
473 
474 	gtk_clist_thaw(hidden_clist);
475 	gtk_clist_thaw(clist);
476 
477 	gtk_toggle_button_set_active
478 		(GTK_TOGGLE_BUTTON(dispheader.other_headers),
479 		 prefs_common.show_other_header);
480 }
481 
prefs_display_header_set_list()482 static void prefs_display_header_set_list()
483 {
484 	gint row = 0;
485 	DisplayHeaderProp *dp;
486 
487 	g_slist_free(prefs_common.disphdr_list);
488 	prefs_common.disphdr_list = NULL;
489 
490 	while ((dp = gtk_clist_get_row_data
491 		(GTK_CLIST(dispheader.headers_clist), row)) != NULL) {
492 		prefs_common.disphdr_list =
493 			g_slist_append(prefs_common.disphdr_list, dp);
494 		row++;
495 	}
496 
497 	row = 0;
498 	while ((dp = gtk_clist_get_row_data
499 		(GTK_CLIST(dispheader.hidden_headers_clist), row)) != NULL) {
500 		prefs_common.disphdr_list =
501 			g_slist_append(prefs_common.disphdr_list, dp);
502 		row++;
503 	}
504 }
505 
prefs_display_header_find_header(GtkCList * clist,const gchar * header)506 static gint prefs_display_header_find_header(GtkCList *clist,
507 					     const gchar *header)
508 {
509 	gint row = 0;
510 	DisplayHeaderProp *dp;
511 
512 	while ((dp = gtk_clist_get_row_data(clist, row)) != NULL) {
513 		if (g_ascii_strcasecmp(dp->name, header) == 0)
514 			return row;
515 		row++;
516 	}
517 
518 	return -1;
519 }
520 
prefs_display_header_clist_set_row(gboolean hidden)521 static gint prefs_display_header_clist_set_row(gboolean hidden)
522 {
523 	GtkCList *clist;
524 	DisplayHeaderProp *dp;
525 	const gchar *entry_text;
526 	gchar *dp_str[1];
527 	gint row;
528 
529 	entry_text = gtk_entry_get_text(GTK_ENTRY(dispheader.hdr_entry));
530 	if (entry_text[0] == '\0') {
531 		alertpanel_error(_("Header name is not set."));
532 		return -1;
533 	}
534 
535 	if (hidden)
536 		clist = GTK_CLIST(dispheader.hidden_headers_clist);
537 	else
538 		clist = GTK_CLIST(dispheader.headers_clist);
539 
540 	if (prefs_display_header_find_header(clist, entry_text) != -1) {
541 		alertpanel_error(_("This header is already in the list."));
542 		return -1;
543 	}
544 
545 	dp = g_new0(DisplayHeaderProp, 1);
546 
547 	dp->name = g_strdup(entry_text);
548 	dp->hidden = hidden;
549 
550 	dp_str[0] = dp->name;
551 	row = gtk_clist_append(clist, dp_str);
552 	gtk_clist_set_row_data(clist, row, dp);
553 
554 	prefs_display_header_set_list();
555 
556 	return row;
557 }
558 
prefs_display_header_register_cb(GtkButton * btn,gpointer hidden_data)559 static void prefs_display_header_register_cb(GtkButton *btn,
560 					     gpointer hidden_data)
561 {
562 	prefs_display_header_clist_set_row(GPOINTER_TO_INT(hidden_data));
563 }
564 
prefs_display_header_delete_cb(GtkButton * btn,gpointer clist_data)565 static void prefs_display_header_delete_cb(GtkButton *btn, gpointer clist_data)
566 {
567 	GtkCList *clist = GTK_CLIST(clist_data);
568 	DisplayHeaderProp *dp;
569 	gint row;
570 
571 	if (!clist->selection) return;
572 	row = GPOINTER_TO_INT(clist->selection->data);
573 
574 	dp = gtk_clist_get_row_data(clist, row);
575 	display_header_prop_free(dp);
576 	gtk_clist_remove(clist, row);
577 	prefs_common.disphdr_list =
578 		g_slist_remove(prefs_common.disphdr_list, dp);
579 }
580 
prefs_display_header_up(void)581 static void prefs_display_header_up(void)
582 {
583 	GtkCList *clist = GTK_CLIST(dispheader.headers_clist);
584 	gint row;
585 
586 	if (!clist->selection) return;
587 
588 	row = GPOINTER_TO_INT(clist->selection->data);
589 	if (row > 0)
590 		gtk_clist_row_move(clist, row, row - 1);
591 }
592 
prefs_display_header_down(void)593 static void prefs_display_header_down(void)
594 {
595 	GtkCList *clist = GTK_CLIST(dispheader.headers_clist);
596 	gint row;
597 
598 	if (!clist->selection) return;
599 
600 	row = GPOINTER_TO_INT(clist->selection->data);
601 	if (row >= 0 && row < clist->rows - 1)
602 		gtk_clist_row_move(clist, row, row + 1);
603 }
604 
prefs_display_header_row_moved(GtkCList * clist,gint source_row,gint dest_row,gpointer data)605 static void prefs_display_header_row_moved(GtkCList *clist, gint source_row,
606 					   gint dest_row, gpointer data)
607 {
608 	prefs_display_header_set_list();
609 }
610 
prefs_display_header_key_pressed(GtkWidget * widget,GdkEventKey * event,gpointer data)611 static gboolean prefs_display_header_key_pressed(GtkWidget *widget,
612 					     GdkEventKey *event,
613 					     gpointer data)
614 {
615 	if (event && event->keyval == GDK_Escape)
616 		prefs_display_header_cancel();
617 	return FALSE;
618 }
619 
prefs_display_header_ok(void)620 static void prefs_display_header_ok(void)
621 {
622 	prefs_common.show_other_header =
623 		gtk_toggle_button_get_active
624 			(GTK_TOGGLE_BUTTON(dispheader.other_headers));
625 	prefs_display_header_write_config();
626 	gtk_widget_hide(dispheader.window);
627 }
628 
prefs_display_header_cancel(void)629 static void prefs_display_header_cancel(void)
630 {
631 	prefs_display_header_read_config();
632 	gtk_widget_hide(dispheader.window);
633 }
634 
prefs_display_header_deleted(GtkWidget * widget,GdkEventAny * event,gpointer data)635 static gint prefs_display_header_deleted(GtkWidget *widget, GdkEventAny *event,
636 					 gpointer data)
637 {
638 	prefs_display_header_cancel();
639 	return TRUE;
640 }
641