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.
27 #include <gtk/gtkmain.h>
28 #include <gtk/gtkwindow.h>
29 #include <gtk/gtkvbox.h>
30 #include <gtk/gtkhbox.h>
31 #include <gtk/gtkclist.h>
32 #include <gtk/gtkbutton.h>
33 #include <gdk/gdkkeysyms.h>
36 #include "prefs_gtk.h"
37 #include "prefs_common.h"
38 #include "prefs_summary_column.h"
39 #include "manage_window.h"
40 #include "summaryview.h"
41 #include "mainwindow.h"
46 static struct _SummaryColumnDialog
50 GtkWidget *stock_clist;
51 GtkWidget *shown_clist;
54 GtkWidget *remove_btn;
58 GtkWidget *default_btn;
61 GtkWidget *cancel_btn;
66 static const gchar *const col_name[N_SUMMARY_COLS] = {
67 N_("Mark"), /* S_COL_MARK */
68 N_("Status"), /* S_COL_STATUS */
69 N_("Attachment"), /* S_COL_MIME */
70 N_("Subject"), /* S_COL_SUBJECT */
71 N_("From"), /* S_COL_FROM */
72 N_("Date"), /* S_COL_DATE */
73 N_("Size"), /* S_COL_SIZE */
74 N_("Number"), /* S_COL_NUMBER */
75 N_("Score"), /* S_COL_SCORE */
76 N_("Locked"), /* S_COL_LOCKED */
79 static SummaryColumnState default_state[N_SUMMARY_COLS] = {
80 { S_COL_MARK , TRUE },
81 { S_COL_STATUS , TRUE },
82 { S_COL_MIME , TRUE },
83 { S_COL_SUBJECT, TRUE },
84 { S_COL_FROM , TRUE },
85 { S_COL_DATE , TRUE },
86 { S_COL_SIZE , TRUE },
87 { S_COL_NUMBER , FALSE },
88 { S_COL_SCORE , FALSE },
89 { S_COL_LOCKED , FALSE },
92 static void prefs_summary_column_create (void);
94 static void prefs_summary_column_set_dialog (SummaryColumnState *state);
95 static void prefs_summary_column_set_view (void);
97 /* callback functions */
98 static void prefs_summary_column_add (void);
99 static void prefs_summary_column_remove (void);
101 static void prefs_summary_column_up (void);
102 static void prefs_summary_column_down (void);
104 static void prefs_summary_column_set_to_default (void);
106 static void prefs_summary_column_ok (void);
107 static void prefs_summary_column_cancel (void);
109 static gint prefs_summary_column_delete_event (GtkWidget *widget,
112 static void prefs_summary_column_key_pressed (GtkWidget *widget,
116 void prefs_summary_column_open(void)
120 if (!summary_col.window)
121 prefs_summary_column_create();
123 manage_window_set_transient(GTK_WINDOW(summary_col.window));
124 gtk_widget_grab_focus(summary_col.ok_btn);
126 prefs_summary_column_set_dialog(NULL);
128 gtk_widget_show(summary_col.window);
130 summary_col.finished = FALSE;
131 while (summary_col.finished == FALSE)
132 gtk_main_iteration();
134 gtk_widget_hide(summary_col.window);
139 static void prefs_summary_column_create(void)
144 GtkWidget *label_hbox;
150 GtkWidget *clist_hbox;
151 GtkWidget *scrolledwin;
152 GtkWidget *stock_clist;
153 GtkWidget *shown_clist;
156 GtkWidget *btn_vbox1;
158 GtkWidget *remove_btn;
163 GtkWidget *default_btn;
164 GtkWidget *confirm_area;
166 GtkWidget *cancel_btn;
170 debug_print("Creating summary column setting window...\n");
172 window = gtk_window_new(GTK_WINDOW_DIALOG);
173 gtk_container_set_border_width(GTK_CONTAINER(window), 8);
174 gtk_window_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
175 gtk_window_set_modal(GTK_WINDOW(window), TRUE);
176 gtk_window_set_policy(GTK_WINDOW(window), FALSE, FALSE, FALSE);
177 gtk_window_set_title(GTK_WINDOW(window),
178 _("Displayed items configuration"));
179 gtk_signal_connect(GTK_OBJECT(window), "delete_event",
180 GTK_SIGNAL_FUNC(prefs_summary_column_delete_event),
182 gtk_signal_connect(GTK_OBJECT(window), "key_press_event",
183 GTK_SIGNAL_FUNC(prefs_summary_column_key_pressed),
186 vbox = gtk_vbox_new(FALSE, 6);
187 gtk_widget_show(vbox);
188 gtk_container_add(GTK_CONTAINER(window), vbox);
190 label_hbox = gtk_hbox_new(FALSE, 0);
191 gtk_widget_show(label_hbox);
192 gtk_box_pack_start(GTK_BOX(vbox), label_hbox, FALSE, FALSE, 4);
194 label = gtk_label_new
195 (_("Select items to be displayed in the summary view. You can modify\n"
196 "the order by using the Up / Down buttons or by dragging the items."));
197 gtk_widget_show(label);
198 gtk_box_pack_start(GTK_BOX(label_hbox), label, FALSE, FALSE, 4);
199 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
201 vbox1 = gtk_vbox_new(FALSE, VSPACING);
202 gtk_widget_show(vbox1);
203 gtk_box_pack_start(GTK_BOX(vbox), vbox1, TRUE, TRUE, 0);
204 gtk_container_set_border_width(GTK_CONTAINER(vbox1), 2);
206 hbox1 = gtk_hbox_new(FALSE, 8);
207 gtk_widget_show(hbox1);
208 gtk_box_pack_start(GTK_BOX(vbox1), hbox1, FALSE, TRUE, 0);
210 clist_hbox = gtk_hbox_new(FALSE, 8);
211 gtk_widget_show(clist_hbox);
212 gtk_box_pack_start(GTK_BOX(hbox1), clist_hbox, TRUE, TRUE, 0);
214 scrolledwin = gtk_scrolled_window_new(NULL, NULL);
215 gtk_widget_set_usize(scrolledwin, 180, 210);
216 gtk_widget_show(scrolledwin);
217 gtk_box_pack_start(GTK_BOX(clist_hbox), scrolledwin, TRUE, TRUE, 0);
218 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwin),
219 GTK_POLICY_AUTOMATIC,
220 GTK_POLICY_AUTOMATIC);
222 title[0] = _("Available items");
223 stock_clist = gtk_clist_new_with_titles(1, title);
224 gtk_widget_show(stock_clist);
225 gtk_container_add(GTK_CONTAINER(scrolledwin), stock_clist);
226 gtk_clist_set_selection_mode(GTK_CLIST(stock_clist),
227 GTK_SELECTION_BROWSE);
228 GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(stock_clist)->column[0].button,
231 /* add/remove button */
232 btn_vbox = gtk_vbox_new(FALSE, 0);
233 gtk_widget_show(btn_vbox);
234 gtk_box_pack_start(GTK_BOX(hbox1), btn_vbox, FALSE, FALSE, 0);
236 btn_vbox1 = gtk_vbox_new(FALSE, 8);
237 gtk_widget_show(btn_vbox1);
238 gtk_box_pack_start(GTK_BOX(btn_vbox), btn_vbox1, TRUE, FALSE, 0);
240 add_btn = gtk_button_new_with_label(_(" -> "));
241 gtk_widget_show(add_btn);
242 gtk_box_pack_start(GTK_BOX(btn_vbox1), add_btn, FALSE, FALSE, 0);
244 remove_btn = gtk_button_new_with_label(_(" <- "));
245 gtk_widget_show(remove_btn);
246 gtk_box_pack_start(GTK_BOX(btn_vbox1), remove_btn, FALSE, FALSE, 0);
248 gtk_signal_connect(GTK_OBJECT(add_btn), "clicked",
249 GTK_SIGNAL_FUNC(prefs_summary_column_add), NULL);
250 gtk_signal_connect(GTK_OBJECT(remove_btn), "clicked",
251 GTK_SIGNAL_FUNC(prefs_summary_column_remove), NULL);
253 clist_hbox = gtk_hbox_new(FALSE, 8);
254 gtk_widget_show(clist_hbox);
255 gtk_box_pack_start(GTK_BOX(hbox1), clist_hbox, TRUE, TRUE, 0);
257 scrolledwin = gtk_scrolled_window_new(NULL, NULL);
258 gtk_widget_set_usize(scrolledwin, 180, 210);
259 gtk_widget_show(scrolledwin);
260 gtk_box_pack_start(GTK_BOX(clist_hbox), scrolledwin, TRUE, TRUE, 0);
261 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwin),
262 GTK_POLICY_AUTOMATIC,
263 GTK_POLICY_AUTOMATIC);
265 title[0] = _("Displayed items");
266 shown_clist = gtk_clist_new_with_titles(1, title);
267 gtk_widget_show(shown_clist);
268 gtk_container_add(GTK_CONTAINER(scrolledwin), shown_clist);
269 gtk_clist_set_selection_mode(GTK_CLIST(shown_clist),
270 GTK_SELECTION_BROWSE);
271 gtk_clist_set_reorderable(GTK_CLIST(shown_clist), TRUE);
272 gtk_clist_set_use_drag_icons(GTK_CLIST(shown_clist), FALSE);
273 GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(shown_clist)->column[0].button,
277 btn_vbox = gtk_vbox_new(FALSE, 0);
278 gtk_widget_show(btn_vbox);
279 gtk_box_pack_start(GTK_BOX(hbox1), btn_vbox, FALSE, FALSE, 0);
281 btn_vbox1 = gtk_vbox_new(FALSE, 8);
282 gtk_widget_show(btn_vbox1);
283 gtk_box_pack_start(GTK_BOX(btn_vbox), btn_vbox1, TRUE, FALSE, 0);
285 up_btn = gtk_button_new_with_label(_("Up"));
286 gtk_widget_show(up_btn);
287 gtk_box_pack_start(GTK_BOX(btn_vbox1), up_btn, FALSE, FALSE, 0);
289 down_btn = gtk_button_new_with_label(_("Down"));
290 gtk_widget_show(down_btn);
291 gtk_box_pack_start(GTK_BOX(btn_vbox1), down_btn, FALSE, FALSE, 0);
293 gtk_signal_connect(GTK_OBJECT(up_btn), "clicked",
294 GTK_SIGNAL_FUNC(prefs_summary_column_up), NULL);
295 gtk_signal_connect(GTK_OBJECT(down_btn), "clicked",
296 GTK_SIGNAL_FUNC(prefs_summary_column_down), NULL);
298 btn_hbox = gtk_hbox_new(FALSE, 8);
299 gtk_widget_show(btn_hbox);
300 gtk_box_pack_end(GTK_BOX(vbox), btn_hbox, FALSE, FALSE, 0);
302 btn_vbox = gtk_vbox_new(FALSE, 0);
303 gtk_widget_show(btn_vbox);
304 gtk_box_pack_start(GTK_BOX(btn_hbox), btn_vbox, FALSE, FALSE, 0);
306 default_btn = gtk_button_new_with_label(_(" Use default "));
307 gtk_widget_show(default_btn);
308 gtk_box_pack_start(GTK_BOX(btn_vbox), default_btn, TRUE, FALSE, 0);
309 gtk_signal_connect(GTK_OBJECT(default_btn), "clicked",
310 GTK_SIGNAL_FUNC(prefs_summary_column_set_to_default),
313 gtkut_button_set_create(&confirm_area, &ok_btn, _("OK"),
314 &cancel_btn, _("Cancel"), NULL, NULL);
315 gtk_widget_show(confirm_area);
316 gtk_box_pack_end(GTK_BOX(btn_hbox), confirm_area, FALSE, FALSE, 0);
317 gtk_widget_grab_default(ok_btn);
319 gtk_signal_connect(GTK_OBJECT(ok_btn), "clicked",
320 GTK_SIGNAL_FUNC(prefs_summary_column_ok), NULL);
321 gtk_signal_connect(GTK_OBJECT(cancel_btn), "clicked",
322 GTK_SIGNAL_FUNC(prefs_summary_column_cancel), NULL);
324 summary_col.window = window;
325 summary_col.stock_clist = stock_clist;
326 summary_col.shown_clist = shown_clist;
327 summary_col.add_btn = add_btn;
328 summary_col.remove_btn = remove_btn;
329 summary_col.up_btn = up_btn;
330 summary_col.down_btn = down_btn;
331 summary_col.ok_btn = ok_btn;
332 summary_col.cancel_btn = cancel_btn;
335 SummaryColumnState *prefs_summary_column_get_config(void)
337 static SummaryColumnState state[N_SUMMARY_COLS];
338 SummaryColumnType type;
341 for (pos = 0; pos < N_SUMMARY_COLS; pos++)
342 state[pos].type = -1;
344 for (type = 0; type < N_SUMMARY_COLS; type++) {
345 pos = prefs_common.summary_col_pos[type];
346 if (pos < 0 || pos >= N_SUMMARY_COLS ||
347 state[pos].type != -1) {
348 g_warning("Wrong column position\n");
349 prefs_summary_column_set_config(default_state);
350 return default_state;
353 state[pos].type = type;
354 state[pos].visible = prefs_common.summary_col_visible[type];
360 void prefs_summary_column_set_config(SummaryColumnState *state)
362 SummaryColumnType type;
365 for (pos = 0; pos < N_SUMMARY_COLS; pos++) {
366 type = state[pos].type;
367 prefs_common.summary_col_visible[type] = state[pos].visible;
368 prefs_common.summary_col_pos[type] = pos;
372 static void prefs_summary_column_set_dialog(SummaryColumnState *state)
374 GtkCList *stock_clist = GTK_CLIST(summary_col.stock_clist);
375 GtkCList *shown_clist = GTK_CLIST(summary_col.shown_clist);
377 SummaryColumnType type;
380 gtk_clist_clear(stock_clist);
381 gtk_clist_clear(shown_clist);
384 state = prefs_summary_column_get_config();
386 for (pos = 0; pos < N_SUMMARY_COLS; pos++) {
388 type = state[pos].type;
389 name = gettext(col_name[type]);
391 if (state[pos].visible) {
392 row = gtk_clist_append(shown_clist, (gchar **)&name);
393 gtk_clist_set_row_data(shown_clist, row,
394 GINT_TO_POINTER(type));
396 row = gtk_clist_append(stock_clist, (gchar **)&name);
397 gtk_clist_set_row_data(stock_clist, row,
398 GINT_TO_POINTER(type));
403 static void prefs_summary_column_set_view(void)
405 GtkCList *stock_clist = GTK_CLIST(summary_col.stock_clist);
406 GtkCList *shown_clist = GTK_CLIST(summary_col.shown_clist);
407 SummaryColumnState state[N_SUMMARY_COLS];
408 SummaryColumnType type;
412 (stock_clist->rows + shown_clist->rows == N_SUMMARY_COLS);
414 for (row = 0; row < stock_clist->rows; row++) {
415 type = GPOINTER_TO_INT
416 (gtk_clist_get_row_data(stock_clist, row));
417 state[row].type = type;
418 state[row].visible = FALSE;
422 for (row = 0; row < shown_clist->rows; row++) {
423 type = GPOINTER_TO_INT
424 (gtk_clist_get_row_data(shown_clist, row));
425 state[pos + row].type = type;
426 state[pos + row].visible = TRUE;
429 prefs_summary_column_set_config(state);
430 main_window_set_summary_column();
433 static void prefs_summary_column_add(void)
435 GtkCList *stock_clist = GTK_CLIST(summary_col.stock_clist);
436 GtkCList *shown_clist = GTK_CLIST(summary_col.shown_clist);
438 SummaryColumnType type;
441 if (!stock_clist->selection) return;
443 row = GPOINTER_TO_INT(stock_clist->selection->data);
444 type = GPOINTER_TO_INT(gtk_clist_get_row_data(stock_clist, row));
445 gtk_clist_remove(stock_clist, row);
446 if (stock_clist->rows == row)
447 gtk_clist_select_row(stock_clist, row - 1, -1);
449 if (!shown_clist->selection)
452 row = GPOINTER_TO_INT(shown_clist->selection->data) + 1;
454 name = gettext(col_name[type]);
455 row = gtk_clist_insert(shown_clist, row, (gchar **)&name);
456 gtk_clist_set_row_data(shown_clist, row, GINT_TO_POINTER(type));
457 gtk_clist_select_row(shown_clist, row, -1);
460 static void prefs_summary_column_remove(void)
462 GtkCList *stock_clist = GTK_CLIST(summary_col.stock_clist);
463 GtkCList *shown_clist = GTK_CLIST(summary_col.shown_clist);
465 SummaryColumnType type;
468 if (!shown_clist->selection) return;
470 row = GPOINTER_TO_INT(shown_clist->selection->data);
471 type = GPOINTER_TO_INT(gtk_clist_get_row_data(shown_clist, row));
472 gtk_clist_remove(shown_clist, row);
473 if (shown_clist->rows == row)
474 gtk_clist_select_row(shown_clist, row - 1, -1);
476 if (!stock_clist->selection)
479 row = GPOINTER_TO_INT(stock_clist->selection->data) + 1;
481 name = gettext(col_name[type]);
482 row = gtk_clist_insert(stock_clist, row, (gchar **)&name);
483 gtk_clist_set_row_data(stock_clist, row, GINT_TO_POINTER(type));
484 gtk_clist_select_row(stock_clist, row, -1);
487 static void prefs_summary_column_up(void)
489 GtkCList *clist = GTK_CLIST(summary_col.shown_clist);
492 if (!clist->selection) return;
494 row = GPOINTER_TO_INT(clist->selection->data);
496 gtk_clist_row_move(clist, row, row - 1);
499 static void prefs_summary_column_down(void)
501 GtkCList *clist = GTK_CLIST(summary_col.shown_clist);
504 if (!clist->selection) return;
506 row = GPOINTER_TO_INT(clist->selection->data);
507 if (row >= 0 && row < clist->rows - 1)
508 gtk_clist_row_move(clist, row, row + 1);
511 static void prefs_summary_column_set_to_default(void)
513 prefs_summary_column_set_dialog(default_state);
516 static void prefs_summary_column_ok(void)
518 if (!summary_col.finished) {
519 summary_col.finished = TRUE;
520 prefs_summary_column_set_view();
524 static void prefs_summary_column_cancel(void)
526 summary_col.finished = TRUE;
529 static gint prefs_summary_column_delete_event(GtkWidget *widget,
533 summary_col.finished = TRUE;
537 static void prefs_summary_column_key_pressed(GtkWidget *widget,
541 if (event && event->keyval == GDK_Escape)
542 summary_col.finished = TRUE;