summaryrefslogtreecommitdiff
path: root/src/prefs_summary_column.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/prefs_summary_column.c')
-rw-r--r--src/prefs_summary_column.c592
1 files changed, 592 insertions, 0 deletions
diff --git a/src/prefs_summary_column.c b/src/prefs_summary_column.c
new file mode 100644
index 0000000..7b223b2
--- /dev/null
+++ b/src/prefs_summary_column.c
@@ -0,0 +1,592 @@
1/*
2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2007 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 <gdk/gdkkeysyms.h>
29#include <gtk/gtk.h>
30
31#include "prefs.h"
32#include "prefs_ui.h"
33#include "prefs_common.h"
34#include "prefs_summary_column.h"
35#include "manage_window.h"
36#include "summaryview.h"
37#include "mainwindow.h"
38#include "inc.h"
39#include "gtkutils.h"
40#include "utils.h"
41
42static struct _SummaryColumnDialog
43{
44 GtkWidget *window;
45
46 GtkWidget *stock_clist;
47 GtkWidget *shown_clist;
48
49 GtkWidget *add_btn;
50 GtkWidget *remove_btn;
51 GtkWidget *up_btn;
52 GtkWidget *down_btn;
53
54 GtkWidget *default_btn;
55
56 GtkWidget *confirm_area;
57 GtkWidget *ok_btn;
58 GtkWidget *cancel_btn;
59
60 gboolean sent_folder;
61
62 gboolean finished;
63} summary_col;
64
65static const gchar *const col_name[N_SUMMARY_VISIBLE_COLS] = {
66 N_("Mark"), /* S_COL_MARK */
67 N_("Unread"), /* S_COL_UNREAD */
68 N_("Attachment"), /* S_COL_MIME */
69 N_("Subject"), /* S_COL_SUBJECT */
70 N_("From"), /* S_COL_FROM */
71 N_("Date"), /* S_COL_DATE */
72 N_("Size"), /* S_COL_SIZE */
73 N_("Number"), /* S_COL_NUMBER */
74 N_("To") /* S_COL_TO */
75};
76
77static SummaryColumnState default_state[N_SUMMARY_VISIBLE_COLS] = {
78 { S_COL_MARK , TRUE },
79 { S_COL_UNREAD , TRUE },
80 { S_COL_MIME , TRUE },
81 { S_COL_SUBJECT, TRUE },
82 { S_COL_FROM , TRUE },
83 { S_COL_DATE , TRUE },
84 { S_COL_SIZE , TRUE },
85 { S_COL_NUMBER , FALSE },
86 { S_COL_TO , FALSE }
87};
88
89static SummaryColumnState default_sent_state[N_SUMMARY_VISIBLE_COLS] = {
90 { S_COL_MARK , TRUE },
91 { S_COL_UNREAD , TRUE },
92 { S_COL_MIME , TRUE },
93 { S_COL_SUBJECT, TRUE },
94 { S_COL_TO , TRUE },
95 { S_COL_DATE , TRUE },
96 { S_COL_SIZE , TRUE },
97 { S_COL_NUMBER , FALSE },
98 { S_COL_FROM , FALSE }
99};
100
101static void prefs_summary_column_create (void);
102
103static void prefs_summary_column_set_dialog (SummaryColumnState *state);
104static void prefs_summary_column_set_view (void);
105
106/* callback functions */
107static void prefs_summary_column_add (void);
108static void prefs_summary_column_remove (void);
109
110static void prefs_summary_column_up (void);
111static void prefs_summary_column_down (void);
112
113static void prefs_summary_column_set_to_default (void);
114
115static void prefs_summary_column_ok (void);
116static void prefs_summary_column_cancel (void);
117
118static gint prefs_summary_column_delete_event (GtkWidget *widget,
119 GdkEventAny *event,
120 gpointer data);
121static gboolean prefs_summary_column_key_pressed(GtkWidget *widget,
122 GdkEventKey *event,
123 gpointer data);
124
125void prefs_summary_column_open(gboolean sent_folder)
126{
127 inc_lock();
128
129 prefs_summary_column_create();
130 summary_col.sent_folder = sent_folder;
131
132 gtkut_box_set_reverse_order(GTK_BOX(summary_col.confirm_area),
133 !prefs_common.comply_gnome_hig);
134 manage_window_set_transient(GTK_WINDOW(summary_col.window));
135 gtk_widget_grab_focus(summary_col.ok_btn);
136
137 prefs_summary_column_set_dialog(NULL);
138
139 gtk_widget_show(summary_col.window);
140
141 summary_col.finished = FALSE;
142 while (summary_col.finished == FALSE)
143 gtk_main_iteration();
144
145 gtk_widget_destroy(summary_col.window);
146 summary_col.window = NULL;
147 main_window_popup(main_window_get());
148
149 inc_unlock();
150}
151
152static void prefs_summary_column_create(void)
153{
154 GtkWidget *window;
155 GtkWidget *vbox;
156
157 GtkWidget *label_hbox;
158 GtkWidget *label;
159
160 GtkWidget *vbox1;
161
162 GtkWidget *hbox1;
163 GtkWidget *clist_hbox;
164 GtkWidget *scrolledwin;
165 GtkWidget *stock_clist;
166 GtkWidget *shown_clist;
167
168 GtkWidget *btn_vbox;
169 GtkWidget *btn_vbox1;
170 GtkWidget *add_btn;
171 GtkWidget *remove_btn;
172 GtkWidget *up_btn;
173 GtkWidget *down_btn;
174
175 GtkWidget *btn_hbox;
176 GtkWidget *default_btn;
177 GtkWidget *confirm_area;
178 GtkWidget *ok_btn;
179 GtkWidget *cancel_btn;
180
181 gchar *title[1];
182
183 debug_print(_("Creating summary column setting window...\n"));
184
185 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
186 gtk_container_set_border_width(GTK_CONTAINER(window), 8);
187 gtk_window_set_position(GTK_WINDOW(window),
188 GTK_WIN_POS_CENTER_ON_PARENT);
189 gtk_window_set_modal(GTK_WINDOW(window), TRUE);
190 gtk_window_set_policy(GTK_WINDOW(window), FALSE, FALSE, FALSE);
191 gtk_window_set_title(GTK_WINDOW(window),
192 _("Summary display item setting"));
193 g_signal_connect(G_OBJECT(window), "delete_event",
194 G_CALLBACK(prefs_summary_column_delete_event), NULL);
195 g_signal_connect(G_OBJECT(window), "key_press_event",
196 G_CALLBACK(prefs_summary_column_key_pressed), NULL);
197
198 vbox = gtk_vbox_new(FALSE, 6);
199 gtk_widget_show(vbox);
200 gtk_container_add(GTK_CONTAINER(window), vbox);
201
202 label_hbox = gtk_hbox_new(FALSE, 0);
203 gtk_widget_show(label_hbox);
204 gtk_box_pack_start(GTK_BOX(vbox), label_hbox, FALSE, FALSE, 4);
205
206 label = gtk_label_new
207 (_("Select items to be displayed on the summary view. You can modify\n"
208 "the order by using the Up / Down button."));
209 gtk_widget_show(label);
210 gtk_box_pack_start(GTK_BOX(label_hbox), label, FALSE, FALSE, 4);
211 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
212
213 vbox1 = gtk_vbox_new(FALSE, VSPACING);
214 gtk_widget_show(vbox1);
215 gtk_box_pack_start(GTK_BOX(vbox), vbox1, TRUE, TRUE, 0);
216 gtk_container_set_border_width(GTK_CONTAINER(vbox1), 2);
217
218 hbox1 = gtk_hbox_new(FALSE, 8);
219 gtk_widget_show(hbox1);
220 gtk_box_pack_start(GTK_BOX(vbox1), hbox1, FALSE, TRUE, 0);
221
222 clist_hbox = gtk_hbox_new(FALSE, 8);
223 gtk_widget_show(clist_hbox);
224 gtk_box_pack_start(GTK_BOX(hbox1), clist_hbox, TRUE, TRUE, 0);
225
226 scrolledwin = gtk_scrolled_window_new(NULL, NULL);
227 gtk_widget_set_size_request(scrolledwin, 180, 210);
228 gtk_widget_show(scrolledwin);
229 gtk_box_pack_start(GTK_BOX(clist_hbox), scrolledwin, TRUE, TRUE, 0);
230 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwin),
231 GTK_POLICY_AUTOMATIC,
232 GTK_POLICY_AUTOMATIC);
233
234 title[0] = _("Available items");
235 stock_clist = gtk_clist_new_with_titles(1, title);
236 gtk_widget_show(stock_clist);
237 gtk_container_add(GTK_CONTAINER(scrolledwin), stock_clist);
238 gtk_clist_set_selection_mode(GTK_CLIST(stock_clist),
239 GTK_SELECTION_BROWSE);
240 gtkut_clist_set_redraw(GTK_CLIST(stock_clist));
241 GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(stock_clist)->column[0].button,
242 GTK_CAN_FOCUS);
243
244 /* add/remove button */
245 btn_vbox = gtk_vbox_new(FALSE, 0);
246 gtk_widget_show(btn_vbox);
247 gtk_box_pack_start(GTK_BOX(hbox1), btn_vbox, FALSE, FALSE, 0);
248
249 btn_vbox1 = gtk_vbox_new(FALSE, 8);
250 gtk_widget_show(btn_vbox1);
251 gtk_box_pack_start(GTK_BOX(btn_vbox), btn_vbox1, TRUE, FALSE, 0);
252
253 add_btn = gtk_button_new_with_label(_(" -> "));
254 gtk_widget_show(add_btn);
255 gtk_box_pack_start(GTK_BOX(btn_vbox1), add_btn, FALSE, FALSE, 0);
256
257 remove_btn = gtk_button_new_with_label(_(" <- "));
258 gtk_widget_show(remove_btn);
259 gtk_box_pack_start(GTK_BOX(btn_vbox1), remove_btn, FALSE, FALSE, 0);
260
261 g_signal_connect(G_OBJECT(add_btn), "clicked",
262 G_CALLBACK(prefs_summary_column_add), NULL);
263 g_signal_connect(G_OBJECT(remove_btn), "clicked",
264 G_CALLBACK(prefs_summary_column_remove), NULL);
265
266 clist_hbox = gtk_hbox_new(FALSE, 8);
267 gtk_widget_show(clist_hbox);
268 gtk_box_pack_start(GTK_BOX(hbox1), clist_hbox, TRUE, TRUE, 0);
269
270 scrolledwin = gtk_scrolled_window_new(NULL, NULL);
271 gtk_widget_set_size_request(scrolledwin, 180, 210);
272 gtk_widget_show(scrolledwin);
273 gtk_box_pack_start(GTK_BOX(clist_hbox), scrolledwin, TRUE, TRUE, 0);
274 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwin),
275 GTK_POLICY_AUTOMATIC,
276 GTK_POLICY_AUTOMATIC);
277
278 title[0] = _("Displayed items");
279 shown_clist = gtk_clist_new_with_titles(1, title);
280 gtk_widget_show(shown_clist);
281 gtk_container_add(GTK_CONTAINER(scrolledwin), shown_clist);
282 gtk_clist_set_selection_mode(GTK_CLIST(shown_clist),
283 GTK_SELECTION_BROWSE);
284#if 0
285 gtk_clist_set_reorderable(GTK_CLIST(shown_clist), TRUE);
286 gtk_clist_set_use_drag_icons(GTK_CLIST(shown_clist), FALSE);
287#endif
288 gtkut_clist_set_redraw(GTK_CLIST(shown_clist));
289 GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(shown_clist)->column[0].button,
290 GTK_CAN_FOCUS);
291
292 /* up/down button */
293 btn_vbox = gtk_vbox_new(FALSE, 0);
294 gtk_widget_show(btn_vbox);
295 gtk_box_pack_start(GTK_BOX(hbox1), btn_vbox, FALSE, FALSE, 0);
296
297 btn_vbox1 = gtk_vbox_new(FALSE, 8);
298 gtk_widget_show(btn_vbox1);
299 gtk_box_pack_start(GTK_BOX(btn_vbox), btn_vbox1, TRUE, FALSE, 0);
300
301 up_btn = gtk_button_new_with_label(_("Up"));
302 gtk_widget_show(up_btn);
303 gtk_box_pack_start(GTK_BOX(btn_vbox1), up_btn, FALSE, FALSE, 0);
304
305 down_btn = gtk_button_new_with_label(_("Down"));
306 gtk_widget_show(down_btn);
307 gtk_box_pack_start(GTK_BOX(btn_vbox1), down_btn, FALSE, FALSE, 0);
308
309 g_signal_connect(G_OBJECT(up_btn), "clicked",
310 G_CALLBACK(prefs_summary_column_up), NULL);
311 g_signal_connect(G_OBJECT(down_btn), "clicked",
312 G_CALLBACK(prefs_summary_column_down), NULL);
313
314 btn_hbox = gtk_hbox_new(FALSE, 8);
315 gtk_widget_show(btn_hbox);
316 gtk_box_pack_end(GTK_BOX(vbox), btn_hbox, FALSE, FALSE, 0);
317
318 btn_vbox = gtk_vbox_new(FALSE, 0);
319 gtk_widget_show(btn_vbox);
320 gtk_box_pack_start(GTK_BOX(btn_hbox), btn_vbox, FALSE, FALSE, 0);
321
322 default_btn = gtk_button_new_with_label(_(" Revert to default "));
323 gtk_widget_show(default_btn);
324 gtk_box_pack_start(GTK_BOX(btn_vbox), default_btn, TRUE, FALSE, 0);
325 g_signal_connect(G_OBJECT(default_btn), "clicked",
326 G_CALLBACK(prefs_summary_column_set_to_default), NULL);
327
328 gtkut_stock_button_set_create(&confirm_area, &ok_btn, GTK_STOCK_OK,
329 &cancel_btn, GTK_STOCK_CANCEL,
330 NULL, NULL);
331 gtk_widget_show(confirm_area);
332 gtk_box_pack_end(GTK_BOX(btn_hbox), confirm_area, FALSE, FALSE, 0);
333 gtk_widget_grab_default(ok_btn);
334
335 g_signal_connect(G_OBJECT(ok_btn), "clicked",
336 G_CALLBACK(prefs_summary_column_ok), NULL);
337 g_signal_connect(G_OBJECT(cancel_btn), "clicked",
338 G_CALLBACK(prefs_summary_column_cancel), NULL);
339
340 summary_col.window = window;
341 summary_col.stock_clist = stock_clist;
342 summary_col.shown_clist = shown_clist;
343 summary_col.add_btn = add_btn;
344 summary_col.remove_btn = remove_btn;
345 summary_col.up_btn = up_btn;
346 summary_col.down_btn = down_btn;
347 summary_col.confirm_area = confirm_area;
348 summary_col.ok_btn = ok_btn;
349 summary_col.cancel_btn = cancel_btn;
350}
351
352SummaryColumnState *prefs_summary_column_get_config(gboolean sent_folder)
353{
354 static SummaryColumnState state[N_SUMMARY_VISIBLE_COLS];
355 SummaryColumnType type;
356 gboolean *col_visible;
357 gint *col_pos;
358 SummaryColumnState *def_state;
359 gint pos;
360
361 debug_print("prefs_summary_column_get_config(): "
362 "getting %s folder setting\n",
363 sent_folder ? "sent" : "normal");
364
365 if (sent_folder) {
366 col_visible = prefs_common.summary_sent_col_visible;
367 col_pos = prefs_common.summary_sent_col_pos;
368 def_state = default_sent_state;
369 } else {
370 col_visible = prefs_common.summary_col_visible;
371 col_pos = prefs_common.summary_col_pos;
372 def_state = default_state;
373 }
374
375 for (pos = 0; pos < N_SUMMARY_VISIBLE_COLS; pos++)
376 state[pos].type = -1;
377
378 for (type = 0; type < N_SUMMARY_VISIBLE_COLS; type++) {
379 pos = col_pos[type];
380 if (pos < 0 || pos >= N_SUMMARY_VISIBLE_COLS ||
381 state[pos].type != -1) {
382 g_warning("Wrong column position\n");
383 prefs_summary_column_set_config(def_state, sent_folder);
384 return def_state;
385 }
386
387 state[pos].type = type;
388 state[pos].visible = col_visible[type];
389 }
390
391 return state;
392}
393
394void prefs_summary_column_set_config(SummaryColumnState *state,
395 gboolean sent_folder)
396{
397 SummaryColumnType type;
398 gboolean *col_visible;
399 gint *col_pos;
400 gint pos;
401
402 if (sent_folder) {
403 col_visible = prefs_common.summary_sent_col_visible;
404 col_pos = prefs_common.summary_sent_col_pos;
405 } else {
406 col_visible = prefs_common.summary_col_visible;
407 col_pos = prefs_common.summary_col_pos;
408 }
409
410 for (pos = 0; pos < N_SUMMARY_VISIBLE_COLS; pos++) {
411 type = state[pos].type;
412 col_visible[type] = state[pos].visible;
413 col_pos[type] = pos;
414 }
415}
416
417static void prefs_summary_column_set_dialog(SummaryColumnState *state)
418{
419 GtkCList *stock_clist = GTK_CLIST(summary_col.stock_clist);
420 GtkCList *shown_clist = GTK_CLIST(summary_col.shown_clist);
421 gint pos;
422 SummaryColumnType type;
423 gchar *name;
424
425 gtk_clist_clear(stock_clist);
426 gtk_clist_clear(shown_clist);
427
428 if (!state)
429 state = prefs_summary_column_get_config
430 (summary_col.sent_folder);
431
432 for (pos = 0; pos < N_SUMMARY_VISIBLE_COLS; pos++) {
433 gint row;
434 type = state[pos].type;
435 name = gettext(col_name[type]);
436
437 if (state[pos].visible) {
438 row = gtk_clist_append(shown_clist, (gchar **)&name);
439 gtk_clist_set_row_data(shown_clist, row,
440 GINT_TO_POINTER(type));
441 } else {
442 row = gtk_clist_append(stock_clist, (gchar **)&name);
443 gtk_clist_set_row_data(stock_clist, row,
444 GINT_TO_POINTER(type));
445 }
446 }
447}
448
449static void prefs_summary_column_set_view(void)
450{
451 GtkCList *stock_clist = GTK_CLIST(summary_col.stock_clist);
452 GtkCList *shown_clist = GTK_CLIST(summary_col.shown_clist);
453 SummaryColumnState state[N_SUMMARY_VISIBLE_COLS];
454 SummaryColumnType type;
455 gint row, pos = 0;
456
457 g_return_if_fail(stock_clist->rows + shown_clist->rows ==
458 N_SUMMARY_VISIBLE_COLS);
459
460 for (row = 0; row < stock_clist->rows; row++) {
461 type = GPOINTER_TO_INT
462 (gtk_clist_get_row_data(stock_clist, row));
463 state[row].type = type;
464 state[row].visible = FALSE;
465 }
466
467 pos = row;
468 for (row = 0; row < shown_clist->rows; row++) {
469 type = GPOINTER_TO_INT
470 (gtk_clist_get_row_data(shown_clist, row));
471 state[pos + row].type = type;
472 state[pos + row].visible = TRUE;
473 }
474
475 prefs_summary_column_set_config(state, summary_col.sent_folder);
476 main_window_set_summary_column();
477}
478
479static void prefs_summary_column_add(void)
480{
481 GtkCList *stock_clist = GTK_CLIST(summary_col.stock_clist);
482 GtkCList *shown_clist = GTK_CLIST(summary_col.shown_clist);
483 gint row;
484 SummaryColumnType type;
485 gchar *name;
486
487 if (!stock_clist->selection) return;
488
489 row = GPOINTER_TO_INT(stock_clist->selection->data);
490 type = GPOINTER_TO_INT(gtk_clist_get_row_data(stock_clist, row));
491 gtk_clist_remove(stock_clist, row);
492 if (stock_clist->rows == row)
493 gtk_clist_select_row(stock_clist, row - 1, -1);
494
495 if (!shown_clist->selection)
496 row = 0;
497 else
498 row = GPOINTER_TO_INT(shown_clist->selection->data);
499
500 name = gettext(col_name[type]);
501 row = gtk_clist_insert(shown_clist, row, (gchar **)&name);
502 gtk_clist_set_row_data(shown_clist, row, GINT_TO_POINTER(type));
503}
504
505static void prefs_summary_column_remove(void)
506{
507 GtkCList *stock_clist = GTK_CLIST(summary_col.stock_clist);
508 GtkCList *shown_clist = GTK_CLIST(summary_col.shown_clist);
509 gint row;
510 SummaryColumnType type;
511 gchar *name;
512
513 if (!shown_clist->selection) return;
514
515 row = GPOINTER_TO_INT(shown_clist->selection->data);
516 type = GPOINTER_TO_INT(gtk_clist_get_row_data(shown_clist, row));
517 gtk_clist_remove(shown_clist, row);
518 if (shown_clist->rows == row)
519 gtk_clist_select_row(shown_clist, row - 1, -1);
520
521 if (!stock_clist->selection)
522 row = 0;
523 else
524 row = GPOINTER_TO_INT(stock_clist->selection->data) + 1;
525
526 name = gettext(col_name[type]);
527 row = gtk_clist_insert(stock_clist, row, (gchar **)&name);
528 gtk_clist_set_row_data(stock_clist, row, GINT_TO_POINTER(type));
529 gtk_clist_select_row(stock_clist, row, -1);
530}
531
532static void prefs_summary_column_up(void)
533{
534 GtkCList *clist = GTK_CLIST(summary_col.shown_clist);
535 gint row;
536
537 if (!clist->selection) return;
538
539 row = GPOINTER_TO_INT(clist->selection->data);
540 if (row > 0)
541 gtk_clist_row_move(clist, row, row - 1);
542}
543
544static void prefs_summary_column_down(void)
545{
546 GtkCList *clist = GTK_CLIST(summary_col.shown_clist);
547 gint row;
548
549 if (!clist->selection) return;
550
551 row = GPOINTER_TO_INT(clist->selection->data);
552 if (row >= 0 && row < clist->rows - 1)
553 gtk_clist_row_move(clist, row, row + 1);
554}
555
556static void prefs_summary_column_set_to_default(void)
557{
558 if (summary_col.sent_folder)
559 prefs_summary_column_set_dialog(default_sent_state);
560 else
561 prefs_summary_column_set_dialog(default_state);
562}
563
564static void prefs_summary_column_ok(void)
565{
566 if (!summary_col.finished) {
567 summary_col.finished = TRUE;
568 prefs_summary_column_set_view();
569 }
570}
571
572static void prefs_summary_column_cancel(void)
573{
574 summary_col.finished = TRUE;
575}
576
577static gint prefs_summary_column_delete_event(GtkWidget *widget,
578 GdkEventAny *event,
579 gpointer data)
580{
581 summary_col.finished = TRUE;
582 return TRUE;
583}
584
585static gboolean prefs_summary_column_key_pressed(GtkWidget *widget,
586 GdkEventKey *event,
587 gpointer data)
588{
589 if (event && event->keyval == GDK_Escape)
590 summary_col.finished = TRUE;
591 return FALSE;
592}