2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2011 Hiroyuki Yamamoto and the Claws Mail team
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 3 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, see <http://www.gnu.org/licenses/>.
27 #include <glib/gi18n.h>
29 #include <gdk/gdkkeysyms.h>
35 #include "prefs_gtk.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"
50 static struct DisplayHeader {
54 GtkWidget *cancel_btn;
58 GtkWidget *headers_list_view;
59 GtkWidget *hidden_headers_list_view;
61 GtkWidget *other_headers;
64 /* widget creating functions */
65 static void prefs_display_header_create (void);
67 static void prefs_display_header_set_dialog (void);
68 static void prefs_display_header_set_list (void);
69 static void prefs_display_header_list_view_set_row (gboolean hidden);
71 /* callback functions */
72 static void prefs_display_header_register_cb (GtkButton *btn,
73 gpointer hidden_data);
74 static void prefs_display_header_delete_cb (GtkButton *btn,
75 gpointer list_view_data);
76 static void prefs_display_header_up (void);
77 static void prefs_display_header_down (void);
79 static gboolean prefs_display_header_key_pressed (GtkWidget *widget,
82 static void prefs_display_header_ok (void);
83 static void prefs_display_header_cancel (void);
84 static gint prefs_display_header_deleted (GtkWidget *widget,
89 static GtkListStore *prefs_display_header_create_store (void);
90 static void prefs_display_header_insert_header (GtkListStore *store,
92 DisplayHeaderProp *dp);
93 static GtkWidget *prefs_display_header_list_view_create (const gchar *name);
94 static void prefs_filtering_create_list_view_columns (GtkWidget *list_view,
96 static void headers_list_model_rows_reordered (GtkTreeModel *model,
100 GtkTreeView *list_view);
102 static void drag_end (GtkTreeView *list_view,
103 GdkDragContext *context,
107 static gchar *defaults[] =
128 "-Content-Transfer-Encoding",
136 static gchar *defaults[] =
157 "-Content-Transfer-Encoding",
165 static void prefs_display_header_set_default(void)
168 DisplayHeaderProp *dp;
170 for(i = 0; i < sizeof(defaults) / sizeof(defaults[0]); i++) {
171 dp = display_header_prop_read_str(defaults[i]);
172 prefs_common.disphdr_list =
173 g_slist_append(prefs_common.disphdr_list, dp);
177 void prefs_display_header_open(void)
179 if (prefs_rc_is_readonly(DISPLAY_HEADER_RC))
182 if (!dispheader.window) {
183 prefs_display_header_create();
186 manage_window_set_transient(GTK_WINDOW(dispheader.window));
187 gtk_widget_grab_focus(dispheader.ok_btn);
189 prefs_display_header_set_dialog();
191 gtk_widget_show(dispheader.window);
192 gtk_window_set_modal(GTK_WINDOW(dispheader.window), TRUE);
195 static void prefs_display_header_create(void)
201 GtkWidget *cancel_btn;
202 GtkWidget *confirm_area;
207 GtkWidget *hdr_label;
208 GtkWidget *hdr_combo;
216 GtkWidget *list_view_hbox;
217 GtkWidget *list_view_hbox1;
218 GtkWidget *list_view_hbox2;
219 GtkWidget *list_view_scrolledwin;
220 GtkWidget *headers_list_view;
221 GtkWidget *hidden_headers_list_view;
223 GtkWidget *checkbtn_other_headers;
226 debug_print("Creating display header setting window...\n");
228 window = gtkut_window_new(GTK_WINDOW_TOPLEVEL, "prefs_display_header");
229 gtk_container_set_border_width (GTK_CONTAINER (window), 8);
230 gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
231 gtk_window_set_resizable(GTK_WINDOW (window), TRUE);
233 vbox = gtk_vbox_new (FALSE, 6);
234 gtk_widget_show (vbox);
235 gtk_container_add (GTK_CONTAINER (window), vbox);
237 btn_hbox = gtk_hbox_new (FALSE, 8);
238 gtk_widget_show (btn_hbox);
239 gtk_box_pack_end (GTK_BOX (vbox), btn_hbox, FALSE, FALSE, 0);
241 gtkut_stock_button_set_create(&confirm_area, &cancel_btn, GTK_STOCK_CANCEL,
242 &ok_btn, GTK_STOCK_OK,
244 gtk_widget_show (confirm_area);
245 gtk_box_pack_end (GTK_BOX(btn_hbox), confirm_area, FALSE, FALSE, 0);
246 gtk_widget_grab_default (ok_btn);
248 gtk_window_set_title (GTK_WINDOW(window),
249 _("Displayed header configuration"));
250 MANAGE_WINDOW_SIGNALS_CONNECT(window);
251 g_signal_connect (G_OBJECT(window), "delete_event",
252 G_CALLBACK(prefs_display_header_deleted),
254 g_signal_connect (G_OBJECT(window), "key_press_event",
255 G_CALLBACK(prefs_display_header_key_pressed),
257 g_signal_connect (G_OBJECT(ok_btn), "clicked",
258 G_CALLBACK(prefs_display_header_ok),
260 g_signal_connect (G_OBJECT(cancel_btn), "clicked",
261 G_CALLBACK(prefs_display_header_cancel),
264 vbox1 = gtk_vbox_new (FALSE, VSPACING);
265 gtk_widget_show (vbox1);
266 gtk_box_pack_start (GTK_BOX (vbox), vbox1, TRUE, TRUE, 0);
267 gtk_container_set_border_width (GTK_CONTAINER (vbox1), 2);
269 hbox1 = gtk_hbox_new (FALSE, 8);
270 gtk_widget_show (hbox1);
271 gtk_box_pack_start (GTK_BOX (vbox1), hbox1, FALSE, TRUE, 0);
273 hdr_label = gtk_label_new (_("Header name"));
274 gtk_widget_show (hdr_label);
275 gtk_box_pack_start (GTK_BOX (hbox1), hdr_label, FALSE, FALSE, 0);
277 hdr_combo = gtk_combo_box_entry_new_text();
278 for(i=0; i < 9 ; i++)
279 gtk_combo_box_append_text(GTK_COMBO_BOX (hdr_combo),
280 (*defaults[i] == '-') ? defaults[i]+1 : defaults[i]);
281 gtk_combo_box_set_active(GTK_COMBO_BOX(hdr_combo), 0);
282 gtk_widget_show (hdr_combo);
283 gtk_box_pack_start (GTK_BOX (hbox1), hdr_combo, TRUE, TRUE, 0);
284 gtk_widget_set_size_request (hdr_combo, 150, -1);
286 list_view_hbox = gtk_hbox_new (FALSE, 10);
287 gtk_widget_show (list_view_hbox);
288 gtk_box_pack_start (GTK_BOX (vbox1), list_view_hbox, TRUE, TRUE, 0);
290 /* display headers list */
292 list_view_hbox1 = gtk_hbox_new (FALSE, 8);
293 gtk_widget_show (list_view_hbox1);
294 gtk_box_pack_start (GTK_BOX (list_view_hbox), list_view_hbox1, TRUE, TRUE, 0);
296 list_view_scrolledwin = gtk_scrolled_window_new (NULL, NULL);
297 gtk_widget_set_size_request (list_view_scrolledwin, 200, 210);
298 gtk_widget_show (list_view_scrolledwin);
299 gtk_box_pack_start (GTK_BOX (list_view_hbox1), list_view_scrolledwin,
301 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (list_view_scrolledwin),
302 GTK_POLICY_AUTOMATIC,
303 GTK_POLICY_AUTOMATIC);
304 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(list_view_scrolledwin),
307 headers_list_view = prefs_display_header_list_view_create
308 (_("Displayed Headers"));
309 gtk_widget_show (headers_list_view);
310 gtk_container_add(GTK_CONTAINER(list_view_scrolledwin), headers_list_view);
311 gtk_tree_view_set_reorderable(GTK_TREE_VIEW(headers_list_view), TRUE);
313 g_signal_connect(G_OBJECT(headers_list_view), "drag_end",
314 G_CALLBACK(drag_end),
317 /* connect rows change for this list view's model */
318 g_signal_connect(G_OBJECT(gtk_tree_view_get_model(GTK_TREE_VIEW(headers_list_view))),
320 G_CALLBACK(headers_list_model_rows_reordered),
323 btn_vbox = gtk_vbox_new (FALSE, 8);
324 gtk_widget_show (btn_vbox);
325 gtk_box_pack_start (GTK_BOX (list_view_hbox1), btn_vbox, FALSE, FALSE, 0);
327 reg_btn = gtk_button_new_from_stock (GTK_STOCK_ADD);
328 gtk_widget_show (reg_btn);
329 gtk_box_pack_start (GTK_BOX (btn_vbox), reg_btn, FALSE, TRUE, 0);
330 g_signal_connect (G_OBJECT (reg_btn), "clicked",
331 G_CALLBACK (prefs_display_header_register_cb),
332 GINT_TO_POINTER(FALSE));
333 del_btn = gtk_button_new_from_stock (GTK_STOCK_REMOVE);
334 gtk_widget_show (del_btn);
335 gtk_box_pack_start (GTK_BOX (btn_vbox), del_btn, FALSE, TRUE, 0);
336 g_signal_connect (G_OBJECT (del_btn), "clicked",
337 G_CALLBACK (prefs_display_header_delete_cb),
340 up_btn = gtk_button_new_from_stock (GTK_STOCK_GO_UP);
341 gtk_widget_show (up_btn);
342 gtk_box_pack_start (GTK_BOX (btn_vbox), up_btn, FALSE, FALSE, 0);
343 g_signal_connect (G_OBJECT (up_btn), "clicked",
344 G_CALLBACK (prefs_display_header_up), NULL);
346 down_btn = gtk_button_new_from_stock (GTK_STOCK_GO_DOWN);
347 gtk_widget_show (down_btn);
348 gtk_box_pack_start (GTK_BOX (btn_vbox), down_btn, FALSE, FALSE, 0);
349 g_signal_connect (G_OBJECT (down_btn), "clicked",
350 G_CALLBACK (prefs_display_header_down), NULL);
352 /* hidden headers list */
354 list_view_hbox2 = gtk_hbox_new (FALSE, 8);
355 gtk_widget_show (list_view_hbox2);
356 gtk_box_pack_start (GTK_BOX (list_view_hbox), list_view_hbox2, TRUE, TRUE, 0);
358 list_view_scrolledwin = gtk_scrolled_window_new (NULL, NULL);
359 gtk_widget_set_size_request (list_view_scrolledwin, 200, 210);
360 gtk_widget_show (list_view_scrolledwin);
361 gtk_box_pack_start (GTK_BOX (list_view_hbox2), list_view_scrolledwin,
363 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (list_view_scrolledwin),
364 GTK_POLICY_AUTOMATIC,
365 GTK_POLICY_AUTOMATIC);
366 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(list_view_scrolledwin),
369 hidden_headers_list_view = prefs_display_header_list_view_create
370 (_("Hidden headers"));
371 gtk_widget_show (hidden_headers_list_view);
372 gtk_container_add (GTK_CONTAINER (list_view_scrolledwin),
373 hidden_headers_list_view);
375 btn_vbox = gtk_vbox_new (FALSE, 8);
376 gtk_widget_show (btn_vbox);
377 gtk_box_pack_start (GTK_BOX (list_view_hbox2), btn_vbox, FALSE, FALSE, 0);
379 reg_btn = gtk_button_new_from_stock (GTK_STOCK_ADD);
380 gtk_widget_show (reg_btn);
381 gtk_box_pack_start (GTK_BOX (btn_vbox), reg_btn, FALSE, TRUE, 0);
382 g_signal_connect (G_OBJECT (reg_btn), "clicked",
384 (prefs_display_header_register_cb),
385 GINT_TO_POINTER(TRUE));
386 del_btn = gtk_button_new_from_stock (GTK_STOCK_DELETE);
387 gtk_widget_show (del_btn);
388 gtk_box_pack_start (GTK_BOX (btn_vbox), del_btn, FALSE, TRUE, 0);
389 g_signal_connect (G_OBJECT (del_btn), "clicked",
390 G_CALLBACK (prefs_display_header_delete_cb),
391 hidden_headers_list_view);
395 PACK_CHECK_BUTTON (vbox, checkbtn_other_headers,
396 _("Show all unspecified headers"));
397 SET_TOGGLE_SENSITIVITY (checkbtn_other_headers, list_view_hbox2);
399 gtk_widget_show_all(window);
401 dispheader.window = window;
402 dispheader.ok_btn = ok_btn;
403 dispheader.cancel_btn = cancel_btn;
405 dispheader.hdr_combo = hdr_combo;
407 dispheader.headers_list_view = headers_list_view;
408 dispheader.hidden_headers_list_view = hidden_headers_list_view;
410 dispheader.other_headers = checkbtn_other_headers;
413 void prefs_display_header_read_config(void)
417 gchar buf[PREFSBUFSIZE];
418 DisplayHeaderProp *dp;
420 debug_print("Reading configuration for displaying headers...\n");
422 rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
423 DISPLAY_HEADER_RC, NULL);
424 if ((fp = g_fopen(rcpath, "rb")) == NULL) {
425 if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
427 prefs_common.disphdr_list = NULL;
428 prefs_display_header_set_default();
433 /* remove all previous headers list */
434 while (prefs_common.disphdr_list != NULL) {
435 dp = (DisplayHeaderProp *)prefs_common.disphdr_list->data;
436 display_header_prop_free(dp);
437 prefs_common.disphdr_list =
438 g_slist_remove(prefs_common.disphdr_list, dp);
441 while (fgets(buf, sizeof(buf), fp) != NULL) {
442 g_strdelimit(buf, "\r\n", '\0');
443 dp = display_header_prop_read_str(buf);
445 prefs_common.disphdr_list =
446 g_slist_append(prefs_common.disphdr_list, dp);
452 static void prefs_display_header_write_config(void)
458 debug_print("Writing configuration for displaying headers...\n");
460 rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
461 DISPLAY_HEADER_RC, NULL);
463 if ((pfile = prefs_write_open(rcpath)) == NULL) {
464 g_warning("failed to write configuration to file\n");
469 for (cur = prefs_common.disphdr_list; cur != NULL;
471 DisplayHeaderProp *dp = (DisplayHeaderProp *)cur->data;
474 dpstr = display_header_prop_get_str(dp);
475 if (fputs(dpstr, pfile->fp) == EOF ||
476 fputc('\n', pfile->fp) == EOF) {
477 FILE_OP_ERROR(rcpath, "fputs || fputc");
478 prefs_file_close_revert(pfile);
488 if (prefs_file_close(pfile) < 0) {
489 g_warning("failed to write configuration to file\n");
494 static void prefs_display_header_set_dialog(void)
496 GtkTreeView *list_view = GTK_TREE_VIEW(dispheader.headers_list_view);
497 GtkTreeView *hidden_list_view = GTK_TREE_VIEW(dispheader.hidden_headers_list_view);
499 GtkTreeModel *model_list, *model_hidden;
501 model_list = gtk_tree_view_get_model(list_view);
502 model_hidden = gtk_tree_view_get_model(hidden_list_view);
504 gtk_list_store_clear(GTK_LIST_STORE(model_list));
505 gtk_list_store_clear(GTK_LIST_STORE(model_hidden));
507 for (cur = prefs_common.disphdr_list; cur != NULL;
509 DisplayHeaderProp *dp = (DisplayHeaderProp *)cur->data;
512 prefs_display_header_insert_header(GTK_LIST_STORE
513 (model_hidden), dp->name, dp);
515 prefs_display_header_insert_header(GTK_LIST_STORE
516 (model_list), dp->name, dp);
519 gtk_toggle_button_set_active
520 (GTK_TOGGLE_BUTTON(dispheader.other_headers),
521 prefs_common.show_other_header);
524 static void prefs_display_header_set_list(void)
527 DisplayHeaderProp *dp;
531 g_slist_free(prefs_common.disphdr_list);
532 prefs_common.disphdr_list = NULL;
534 model = gtk_tree_view_get_model(GTK_TREE_VIEW(dispheader.headers_list_view));
535 while (gtk_tree_model_iter_nth_child(model, &iter, NULL, row)) {
536 gtk_tree_model_get(model, &iter, PREFS_HDR_DATA, &dp, -1);
538 prefs_common.disphdr_list =
539 g_slist_append(prefs_common.disphdr_list, dp);
543 model = gtk_tree_view_get_model
544 (GTK_TREE_VIEW(dispheader.hidden_headers_list_view));
546 while (gtk_tree_model_iter_nth_child(model, &iter, NULL, row)) {
547 gtk_tree_model_get(model, &iter, PREFS_HDR_DATA, &dp, -1);
549 prefs_common.disphdr_list =
550 g_slist_append(prefs_common.disphdr_list, dp);
555 static gint prefs_display_header_find_header(GtkTreeView *list_view,
559 DisplayHeaderProp *dp;
563 model = gtk_tree_view_get_model(list_view);
564 while (gtk_tree_model_iter_nth_child(model, &iter, NULL, row)) {
565 gtk_tree_model_get(model, &iter, PREFS_HDR_DATA, &dp, -1);
566 if (dp && g_ascii_strcasecmp(dp->name, header) == 0)
574 static void prefs_display_header_list_view_set_row(gboolean hidden)
576 GtkTreeView *list_view;
577 DisplayHeaderProp *dp;
581 entry_text = gtk_combo_box_get_active_text(GTK_COMBO_BOX(dispheader.hdr_combo));
583 entry_text = gtk_editable_get_chars(
584 GTK_EDITABLE(gtk_bin_get_child(GTK_BIN(dispheader.hdr_combo))),0,-1);
585 if (!entry_text || entry_text[0] == '\0') {
586 alertpanel_error(_("Header name is not set."));
591 list_view = GTK_TREE_VIEW(dispheader.hidden_headers_list_view);
593 list_view = GTK_TREE_VIEW(dispheader.headers_list_view);
595 if (prefs_display_header_find_header(list_view, entry_text) != -1) {
596 alertpanel_error(_("This header is already in the list."));
600 dp = g_new0(DisplayHeaderProp, 1);
602 dp->name = g_strdup(entry_text);
605 model = gtk_tree_view_get_model(list_view);
606 prefs_display_header_insert_header(GTK_LIST_STORE(model),
609 prefs_display_header_set_list();
614 static void prefs_display_header_register_cb(GtkButton *btn,
615 gpointer hidden_data)
617 prefs_display_header_list_view_set_row(GPOINTER_TO_INT(hidden_data));
620 static void prefs_display_header_delete_cb(GtkButton *btn, gpointer list_view_data)
622 GtkTreeView *list_view = GTK_TREE_VIEW(list_view_data);
623 DisplayHeaderProp *dp;
624 GtkListStore *store = GTK_LIST_STORE(gtk_tree_view_get_model(list_view));
625 GtkTreeSelection *selection = gtk_tree_view_get_selection(list_view);
628 if (!gtk_tree_selection_get_selected(selection, NULL, &iter))
631 gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, PREFS_HDR_DATA, &dp, -1);
635 prefs_common.disphdr_list =
636 g_slist_remove(prefs_common.disphdr_list, dp);
637 display_header_prop_free(dp);
638 gtk_list_store_remove(store, &iter);
641 static void prefs_display_header_up(void)
643 GtkTreePath *prev, *sel, *try;
645 GtkListStore *store = NULL;
646 GtkTreeModel *model = NULL;
649 if (!gtk_tree_selection_get_selected
650 (gtk_tree_view_get_selection
651 (GTK_TREE_VIEW(dispheader.headers_list_view)),
655 store = (GtkListStore *)model;
656 sel = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &isel);
660 /* no move if we're at row 0... */
661 try = gtk_tree_path_copy(sel);
662 if (!gtk_tree_path_prev(try)) {
663 gtk_tree_path_free(try);
664 gtk_tree_path_free(sel);
669 gtk_tree_model_get_iter(GTK_TREE_MODEL(store),
671 gtk_list_store_swap(store, &iprev, &isel);
673 gtk_tree_path_free(sel);
674 gtk_tree_path_free(prev);
677 static void prefs_display_header_down(void)
679 GtkListStore *store = NULL;
680 GtkTreeModel *model = NULL;
681 GtkTreeIter next, sel;
684 if (!gtk_tree_selection_get_selected
685 (gtk_tree_view_get_selection
686 (GTK_TREE_VIEW(dispheader.headers_list_view)),
690 store = (GtkListStore *)model;
691 try = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &sel);
696 if (gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &next))
697 gtk_list_store_swap(store, &next, &sel);
699 gtk_tree_path_free(try);
702 static gboolean prefs_display_header_key_pressed(GtkWidget *widget,
706 if (event && event->keyval == GDK_Escape)
707 prefs_display_header_cancel();
711 static void prefs_display_header_ok(void)
713 prefs_common.show_other_header =
714 gtk_toggle_button_get_active
715 (GTK_TOGGLE_BUTTON(dispheader.other_headers));
716 prefs_display_header_write_config();
717 gtk_widget_hide(dispheader.window);
718 gtk_window_set_modal(GTK_WINDOW(dispheader.window), FALSE);
721 static void prefs_display_header_cancel(void)
723 prefs_display_header_read_config();
724 gtk_widget_hide(dispheader.window);
725 gtk_window_set_modal(GTK_WINDOW(dispheader.window), FALSE);
728 static gint prefs_display_header_deleted(GtkWidget *widget, GdkEventAny *event,
731 prefs_display_header_cancel();
735 static GtkListStore *prefs_display_header_create_store(void)
737 return gtk_list_store_new(N_PREFS_HDR_COLUMNS,
743 static void prefs_display_header_insert_header(GtkListStore *store,
745 DisplayHeaderProp *dp)
750 gtk_list_store_append(store, &iter);
751 gtk_list_store_set(store, &iter,
758 static GtkWidget *prefs_display_header_list_view_create(const gchar *name)
760 GtkWidget *list_view;
761 GtkTreeSelection *selector;
764 model = GTK_TREE_MODEL(prefs_display_header_create_store());
765 list_view = gtk_tree_view_new_with_model(model);
766 g_object_unref(G_OBJECT(model));
768 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(list_view),
769 prefs_common.use_stripes_everywhere);
771 selector = gtk_tree_view_get_selection(GTK_TREE_VIEW(list_view));
772 gtk_tree_selection_set_mode(selector, GTK_SELECTION_BROWSE);
774 prefs_filtering_create_list_view_columns(GTK_WIDGET(list_view), name);
779 static void prefs_filtering_create_list_view_columns(GtkWidget *list_view,
782 GtkTreeViewColumn *column;
783 GtkCellRenderer *renderer;
785 renderer = gtk_cell_renderer_text_new();
786 column = gtk_tree_view_column_new_with_attributes
787 (name, renderer, "text", PREFS_HDR_HEADER, NULL);
788 gtk_tree_view_append_column(GTK_TREE_VIEW(list_view), column);
792 *\brief Called as a result of a gtk_list_store_swap()
794 static void headers_list_model_rows_reordered(GtkTreeModel *model,
798 GtkTreeView *list_view)
800 prefs_display_header_set_list();
804 *\brief Called as a result of a drag & drop
806 static void drag_end(GtkTreeView *list_view,
807 GdkDragContext *context,
810 prefs_display_header_set_list();