2323adad1979a3e9a8c6dee3c646821316a84e6f
[claws.git] / src / prefs_summaries.c
1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 2004 Hiroyuki Yamamoto & The Sylpheed-Claws Team
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 <stdio.h>
27 #include <stdlib.h>
28
29 #include <glib.h>
30 #include <glib/gi18n.h>
31 #include <gtk/gtk.h>
32 #include <gdk/gdkkeysyms.h>
33
34 #include "prefs_common.h"
35 #include "prefs_gtk.h"
36 #include "prefs_summary_column.h"
37
38 #include "gtk/gtkutils.h"
39 #include "gtk/prefswindow.h"
40
41 #include "manage_window.h"
42
43 typedef struct _SummariesPage
44 {
45         PrefsPage page;
46
47         GtkWidget *window;
48
49         GtkWidget *chkbtn_transhdr;
50         GtkWidget *chkbtn_folder_unread;
51         GtkWidget *spinbtn_ng_abbrev_len;
52         GtkWidget *chkbtn_swapfrom;
53         GtkWidget *chkbtn_useaddrbook;
54         GtkWidget *chkbtn_threadsubj;
55         GtkWidget *button_datefmt;
56         GtkWidget *entry_datefmt;
57 } SummariesPage;
58
59 enum {
60         DATEFMT_FMT,
61         DATEFMT_TXT,
62         N_DATEFMT_COLUMNS
63 };
64
65 static void date_format_ok_btn_clicked          (GtkButton      *button,
66                                                  GtkWidget     **widget);
67 static void date_format_cancel_btn_clicked      (GtkButton      *button,
68                                                  GtkWidget     **widget);
69 static gboolean date_format_key_pressed         (GtkWidget      *keywidget,
70                                                  GdkEventKey    *event,
71                                                  GtkWidget     **widget);
72 static gboolean date_format_on_delete           (GtkWidget      *dialogwidget,
73                                                  GdkEventAny    *event,
74                                                  GtkWidget     **widget);
75 static void date_format_entry_on_change         (GtkEditable    *editable,
76                                                  GtkLabel       *example);
77 static void date_format_select_row              (GtkTreeView *list_view,
78                                                  GtkTreePath *path,
79                                                  GtkTreeViewColumn *column,
80                                                  GtkWidget *date_format);
81
82 static GtkWidget *date_format_create(GtkButton *button, void *data)
83 {
84         static GtkWidget *datefmt_win = NULL;
85
86         GtkWidget *vbox1;
87         GtkWidget *scrolledwindow1;
88         GtkWidget *datefmt_list_view;
89         GtkWidget *table;
90         GtkWidget *label1;
91         GtkWidget *label2;
92         GtkWidget *label3;
93         GtkWidget *confirm_area;
94         GtkWidget *ok_btn;
95         GtkWidget *cancel_btn;
96         GtkWidget *datefmt_entry;
97         GtkListStore *store;
98
99         struct {
100                 gchar *fmt;
101                 gchar *txt;
102         } time_format[] = {
103                 { "%a", NULL },
104                 { "%A", NULL },
105                 { "%b", NULL },
106                 { "%B", NULL },
107                 { "%c", NULL },
108                 { "%C", NULL },
109                 { "%d", NULL },
110                 { "%H", NULL },
111                 { "%I", NULL },
112                 { "%j", NULL },
113                 { "%m", NULL },
114                 { "%M", NULL },
115                 { "%p", NULL },
116                 { "%S", NULL },
117                 { "%w", NULL },
118                 { "%x", NULL },
119                 { "%y", NULL },
120                 { "%Y", NULL },
121                 { "%Z", NULL }
122         };
123
124         gchar *titles[2];
125         gint i;
126         const gint TIME_FORMAT_ELEMS =
127                 sizeof time_format / sizeof time_format[0];
128
129         GtkCellRenderer *renderer;
130         GtkTreeViewColumn *column;
131         GtkTreeSelection *selection;
132
133         time_format[0].txt  = _("the full abbreviated weekday name");
134         time_format[1].txt  = _("the full weekday name");
135         time_format[2].txt  = _("the abbreviated month name");
136         time_format[3].txt  = _("the full month name");
137         time_format[4].txt  = _("the preferred date and time for the current locale");
138         time_format[5].txt  = _("the century number (year/100)");
139         time_format[6].txt  = _("the day of the month as a decimal number");
140         time_format[7].txt  = _("the hour as a decimal number using a 24-hour clock");
141         time_format[8].txt  = _("the hour as a decimal number using a 12-hour clock");
142         time_format[9].txt  = _("the day of the year as a decimal number");
143         time_format[10].txt = _("the month as a decimal number");
144         time_format[11].txt = _("the minute as a decimal number");
145         time_format[12].txt = _("either AM or PM");
146         time_format[13].txt = _("the second as a decimal number");
147         time_format[14].txt = _("the day of the week as a decimal number");
148         time_format[15].txt = _("the preferred date for the current locale");
149         time_format[16].txt = _("the last two digits of a year");
150         time_format[17].txt = _("the year as a decimal number");
151         time_format[18].txt = _("the time zone or name or abbreviation");
152
153         if (datefmt_win) return datefmt_win;
154
155         store = gtk_list_store_new(N_DATEFMT_COLUMNS,
156                                    G_TYPE_STRING,
157                                    G_TYPE_STRING,
158                                    -1);
159
160         for (i = 0; i < TIME_FORMAT_ELEMS; i++) {
161                 GtkTreeIter iter;
162
163                 gtk_list_store_append(store, &iter);
164                 gtk_list_store_set(store, &iter,
165                                    DATEFMT_FMT, time_format[i].fmt,
166                                    DATEFMT_TXT, time_format[i].txt,
167                                    -1);
168         }
169
170         datefmt_win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
171         gtk_container_set_border_width(GTK_CONTAINER(datefmt_win), 8);
172         gtk_window_set_title(GTK_WINDOW(datefmt_win), _("Date format"));
173         gtk_window_set_position(GTK_WINDOW(datefmt_win), GTK_WIN_POS_CENTER);
174         gtk_widget_set_size_request(datefmt_win, 440, 280);
175
176         vbox1 = gtk_vbox_new(FALSE, 10);
177         gtk_widget_show(vbox1);
178         gtk_container_add(GTK_CONTAINER(datefmt_win), vbox1);
179
180         scrolledwindow1 = gtk_scrolled_window_new(NULL, NULL);
181         gtk_scrolled_window_set_policy
182                 (GTK_SCROLLED_WINDOW(scrolledwindow1),
183                  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
184         gtk_widget_show(scrolledwindow1);
185         gtk_box_pack_start(GTK_BOX(vbox1), scrolledwindow1, TRUE, TRUE, 0);
186
187         datefmt_list_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
188         g_object_unref(G_OBJECT(store));
189         gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(datefmt_list_view), TRUE);
190         gtk_widget_show(datefmt_list_view);
191         gtk_container_add(GTK_CONTAINER(scrolledwindow1), datefmt_list_view);
192
193         renderer = gtk_cell_renderer_text_new();
194         column = gtk_tree_view_column_new_with_attributes
195                         (_("Specifier"), renderer, "text", DATEFMT_FMT,
196                          NULL);
197         gtk_tree_view_append_column(GTK_TREE_VIEW(datefmt_list_view), column);
198         
199         renderer = gtk_cell_renderer_text_new();
200         column = gtk_tree_view_column_new_with_attributes
201                         (_("Description"), renderer, "text", DATEFMT_TXT,
202                          NULL);
203         gtk_tree_view_append_column(GTK_TREE_VIEW(datefmt_list_view), column);
204         
205         /* gtk_clist_set_column_width(GTK_CLIST(datefmt_clist), 0, 80); */
206         selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(datefmt_list_view));
207         gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE);
208
209         g_signal_connect(G_OBJECT(datefmt_list_view), "row_activated", 
210                          G_CALLBACK(date_format_select_row),
211                          datefmt_win);
212         
213         table = gtk_table_new(2, 2, FALSE);
214         gtk_widget_show(table);
215         gtk_box_pack_start(GTK_BOX(vbox1), table, FALSE, FALSE, 0);
216         gtk_table_set_row_spacings(GTK_TABLE(table), 4);
217         gtk_table_set_col_spacings(GTK_TABLE(table), 8);
218
219         label1 = gtk_label_new(_("Date format"));
220         gtk_widget_show(label1);
221         gtk_table_attach(GTK_TABLE(table), label1, 0, 1, 0, 1,
222                          GTK_FILL, 0, 0, 0);
223         gtk_label_set_justify(GTK_LABEL(label1), GTK_JUSTIFY_LEFT);
224         gtk_misc_set_alignment(GTK_MISC(label1), 0, 0.5);
225
226         datefmt_entry = gtk_entry_new();
227         gtk_entry_set_max_length(GTK_ENTRY(datefmt_entry), 256);
228         gtk_widget_show(datefmt_entry);
229         gtk_table_attach(GTK_TABLE(table), datefmt_entry, 1, 2, 0, 1,
230                          (GTK_EXPAND | GTK_FILL), 0, 0, 0);
231
232         /* we need the "sample" entry box; add it as data so callbacks can
233          * get the entry box */
234         g_object_set_data(G_OBJECT(datefmt_win), "datefmt_sample",
235                           datefmt_entry);
236
237         label2 = gtk_label_new(_("Example"));
238         gtk_widget_show(label2);
239         gtk_table_attach(GTK_TABLE(table), label2, 0, 1, 1, 2,
240                          GTK_FILL, 0, 0, 0);
241         gtk_label_set_justify(GTK_LABEL(label2), GTK_JUSTIFY_LEFT);
242         gtk_misc_set_alignment(GTK_MISC(label2), 0, 0.5);
243
244         label3 = gtk_label_new("");
245         gtk_widget_show(label3);
246         gtk_table_attach(GTK_TABLE(table), label3, 1, 2, 1, 2,
247                          (GTK_EXPAND | GTK_FILL), 0, 0, 0);
248         gtk_label_set_justify(GTK_LABEL(label3), GTK_JUSTIFY_LEFT);
249         gtk_misc_set_alignment(GTK_MISC(label3), 0, 0.5);
250
251         gtkut_stock_button_set_create(&confirm_area, &ok_btn, GTK_STOCK_OK,
252                                 &cancel_btn, GTK_STOCK_CANCEL, NULL, NULL);
253
254         gtk_box_pack_start(GTK_BOX(vbox1), confirm_area, FALSE, FALSE, 0);
255         gtk_widget_show(confirm_area);
256         gtk_widget_grab_default(ok_btn);
257
258         /* set the current format */
259         gtk_entry_set_text(GTK_ENTRY(datefmt_entry), prefs_common.date_format);
260         date_format_entry_on_change(GTK_EDITABLE(datefmt_entry),
261                                     GTK_LABEL(label3));
262
263         g_signal_connect(G_OBJECT(ok_btn), "clicked",
264                          G_CALLBACK(date_format_ok_btn_clicked),
265                          &datefmt_win);
266         g_signal_connect(G_OBJECT(cancel_btn), "clicked",
267                          G_CALLBACK(date_format_cancel_btn_clicked),
268                          &datefmt_win);
269         g_signal_connect(G_OBJECT(datefmt_win), "key_press_event",
270                          G_CALLBACK(date_format_key_pressed),
271                          &datefmt_win);
272         g_signal_connect(G_OBJECT(datefmt_win), "delete_event",
273                          G_CALLBACK(date_format_on_delete),
274                          &datefmt_win);
275         g_signal_connect(G_OBJECT(datefmt_entry), "changed",
276                          G_CALLBACK(date_format_entry_on_change),
277                          label3);
278
279         gtk_window_set_position(GTK_WINDOW(datefmt_win), GTK_WIN_POS_CENTER);
280         gtk_window_set_modal(GTK_WINDOW(datefmt_win), TRUE);
281
282         gtk_widget_show(datefmt_win);
283         manage_window_set_transient(GTK_WINDOW(datefmt_win));
284
285         gtk_widget_grab_focus(ok_btn);
286
287         return datefmt_win;
288 }
289
290 void prefs_summaries_create_widget(PrefsPage *_page, GtkWindow *window, 
291                                   gpointer data)
292 {
293         SummariesPage *prefs_summaries = (SummariesPage *) _page;
294         
295         GtkWidget *vbox1;
296         GtkWidget *chkbtn_transhdr;
297         GtkWidget *chkbtn_folder_unread;
298         GtkWidget *hbox1;
299         GtkWidget *label_ng_abbrev;
300         GtkWidget *spinbtn_ng_abbrev_len;
301         GtkObject *spinbtn_ng_abbrev_len_adj;
302         GtkWidget *frame_summary;
303         GtkWidget *vbox2;
304         GtkWidget *chkbtn_swapfrom;
305         GtkWidget *chkbtn_useaddrbook;
306         GtkWidget *chkbtn_threadsubj;
307         GtkWidget *vbox3;
308         GtkWidget *label_datefmt;
309         GtkWidget *button_datefmt;
310         GtkWidget *entry_datefmt;
311         GtkWidget *button_dispitem;
312
313         vbox1 = gtk_vbox_new (FALSE, VSPACING);
314         gtk_widget_show (vbox1);
315         gtk_container_set_border_width (GTK_CONTAINER (vbox1), VBOX_BORDER);
316
317         vbox2 = gtk_vbox_new (FALSE, 0);
318         gtk_widget_show (vbox2);
319         gtk_box_pack_start (GTK_BOX (vbox1), vbox2, FALSE, TRUE, 0);
320
321         PACK_CHECK_BUTTON
322                 (vbox2, chkbtn_transhdr,
323                  _("Translate header name (such as `From:', `Subject:')"));
324
325         PACK_CHECK_BUTTON (vbox2, chkbtn_folder_unread,
326                            _("Display unread number next to folder name"));
327
328         PACK_VSPACER(vbox2, vbox3, VSPACING_NARROW_2);
329
330         hbox1 = gtk_hbox_new (FALSE, 8);
331         gtk_widget_show (hbox1);
332         gtk_box_pack_start (GTK_BOX (vbox2), hbox1, FALSE, TRUE, 0);
333
334         label_ng_abbrev = gtk_label_new
335                 (_("Abbreviate newsgroup names longer than"));
336         gtk_widget_show (label_ng_abbrev);
337         gtk_box_pack_start (GTK_BOX (hbox1), label_ng_abbrev, FALSE, FALSE, 0);
338
339         spinbtn_ng_abbrev_len_adj = gtk_adjustment_new (16, 0, 999, 1, 10, 10);
340         spinbtn_ng_abbrev_len = gtk_spin_button_new
341                 (GTK_ADJUSTMENT (spinbtn_ng_abbrev_len_adj), 1, 0);
342         gtk_widget_show (spinbtn_ng_abbrev_len);
343         gtk_box_pack_start (GTK_BOX (hbox1), spinbtn_ng_abbrev_len,
344                             FALSE, FALSE, 0);
345         gtk_widget_set_size_request (spinbtn_ng_abbrev_len, 56, -1);
346         gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbtn_ng_abbrev_len),
347                                      TRUE);
348
349         label_ng_abbrev = gtk_label_new
350                 (_("letters"));
351         gtk_widget_show (label_ng_abbrev);
352         gtk_box_pack_start (GTK_BOX (hbox1), label_ng_abbrev, FALSE, FALSE, 0);
353
354         /* ---- Summary ---- */
355
356         PACK_FRAME(vbox1, frame_summary, _("Summary View"));
357
358         vbox2 = gtk_vbox_new (FALSE, 0);
359         gtk_widget_show (vbox2);
360         gtk_container_add (GTK_CONTAINER (frame_summary), vbox2);
361         gtk_container_set_border_width (GTK_CONTAINER (vbox2), 8);
362
363         PACK_CHECK_BUTTON
364                 (vbox2, chkbtn_swapfrom,
365                  _("Display recipient in `From' column if sender is yourself"));
366         PACK_CHECK_BUTTON
367                 (vbox2, chkbtn_useaddrbook,
368                  _("Display sender using address book"));
369         PACK_CHECK_BUTTON
370                 (vbox2, chkbtn_threadsubj,
371                  _("Thread using subject in addition to standard headers"));
372
373         PACK_VSPACER(vbox2, vbox3, VSPACING_NARROW_2);
374
375         hbox1 = gtk_hbox_new (FALSE, 8);
376         gtk_widget_show (hbox1);
377         gtk_box_pack_start (GTK_BOX (vbox2), hbox1, FALSE, TRUE, 0);
378
379         label_datefmt = gtk_label_new (_("Date format"));
380         gtk_widget_show (label_datefmt);
381         gtk_box_pack_start (GTK_BOX (hbox1), label_datefmt, FALSE, FALSE, 0);
382
383         entry_datefmt = gtk_entry_new ();
384         gtk_widget_show (entry_datefmt);
385         gtk_box_pack_start (GTK_BOX (hbox1), entry_datefmt, TRUE, TRUE, 0);
386
387         button_datefmt = gtk_button_new_with_label (" ... ");
388
389         gtk_widget_show (button_datefmt);
390         gtk_box_pack_start (GTK_BOX (hbox1), button_datefmt, FALSE, FALSE, 0);
391         g_signal_connect (G_OBJECT (button_datefmt), "clicked",
392                           G_CALLBACK (date_format_create), NULL);
393
394         PACK_VSPACER(vbox2, vbox3, VSPACING_NARROW);
395
396         hbox1 = gtk_hbox_new (FALSE, 8);
397         gtk_widget_show (hbox1);
398         gtk_box_pack_start (GTK_BOX (vbox2), hbox1, FALSE, TRUE, 0);
399
400         button_dispitem = gtk_button_new_with_label
401                 (_(" Set displayed items in summary... "));
402         gtk_widget_show (button_dispitem);
403         gtk_box_pack_start (GTK_BOX (hbox1), button_dispitem, FALSE, TRUE, 0);
404         g_signal_connect (G_OBJECT (button_dispitem), "clicked",
405                           G_CALLBACK (prefs_summary_column_open),
406                           NULL);
407
408         prefs_summaries->window                 = GTK_WIDGET(window);
409         
410         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chkbtn_transhdr),
411                         prefs_common.trans_hdr);
412         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chkbtn_folder_unread),
413                         prefs_common.display_folder_unread);
414         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chkbtn_swapfrom),
415                         prefs_common.swap_from);
416         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chkbtn_useaddrbook),
417                         prefs_common.use_addr_book);
418         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chkbtn_threadsubj),
419                         prefs_common.thread_by_subject);
420         gtk_spin_button_set_value(GTK_SPIN_BUTTON(spinbtn_ng_abbrev_len),
421                         prefs_common.ng_abbrev_len);
422         gtk_entry_set_text(GTK_ENTRY(entry_datefmt), 
423                         prefs_common.date_format?prefs_common.date_format:"");  
424
425         prefs_summaries->chkbtn_transhdr = chkbtn_transhdr;
426         prefs_summaries->chkbtn_folder_unread = chkbtn_folder_unread;
427         prefs_summaries->spinbtn_ng_abbrev_len = spinbtn_ng_abbrev_len;
428         prefs_summaries->chkbtn_swapfrom = chkbtn_swapfrom;
429         prefs_summaries->chkbtn_useaddrbook = chkbtn_useaddrbook;
430         prefs_summaries->chkbtn_threadsubj = chkbtn_threadsubj;
431         prefs_summaries->entry_datefmt = entry_datefmt;
432
433         prefs_summaries->page.widget = vbox1;
434 }
435
436 void prefs_summaries_save(PrefsPage *_page)
437 {
438         SummariesPage *page = (SummariesPage *) _page;
439
440         prefs_common.trans_hdr = gtk_toggle_button_get_active(
441                         GTK_TOGGLE_BUTTON(page->chkbtn_transhdr));
442         prefs_common.display_folder_unread = gtk_toggle_button_get_active(
443                         GTK_TOGGLE_BUTTON(page->chkbtn_folder_unread));
444         prefs_common.swap_from = gtk_toggle_button_get_active(
445                         GTK_TOGGLE_BUTTON(page->chkbtn_swapfrom));
446         prefs_common.use_addr_book = gtk_toggle_button_get_active(
447                         GTK_TOGGLE_BUTTON(page->chkbtn_useaddrbook));
448         prefs_common.thread_by_subject = gtk_toggle_button_get_active(
449                         GTK_TOGGLE_BUTTON(page->chkbtn_threadsubj));
450         prefs_common.ng_abbrev_len = gtk_spin_button_get_value_as_int(
451                         GTK_SPIN_BUTTON(page->spinbtn_ng_abbrev_len));
452         
453         g_free(prefs_common.date_format); 
454         prefs_common.date_format = gtk_editable_get_chars(
455                         GTK_EDITABLE(page->entry_datefmt), 0, -1);      
456 }
457
458 static void prefs_summaries_destroy_widget(PrefsPage *_page)
459 {
460 }
461
462 SummariesPage *prefs_summaries;
463
464 void prefs_summaries_init(void)
465 {
466         SummariesPage *page;
467         static gchar *path[3];
468
469         path[0] = _("Display");
470         path[1] = _("Summaries");
471         path[2] = NULL;
472
473         page = g_new0(SummariesPage, 1);
474         page->page.path = path;
475         page->page.create_widget = prefs_summaries_create_widget;
476         page->page.destroy_widget = prefs_summaries_destroy_widget;
477         page->page.save_page = prefs_summaries_save;
478         page->page.weight = 60.0;
479         prefs_gtk_register_page((PrefsPage *) page);
480         prefs_summaries = page;
481 }
482
483 void prefs_summaries_done(void)
484 {
485         prefs_gtk_unregister_page((PrefsPage *) prefs_summaries);
486         g_free(prefs_summaries);
487 }
488
489 static void date_format_ok_btn_clicked(GtkButton *button, GtkWidget **widget)
490 {
491         GtkWidget *datefmt_sample = NULL;
492         gchar *text;
493
494         g_return_if_fail(widget != NULL);
495         g_return_if_fail(*widget != NULL);
496         g_return_if_fail(prefs_summaries->entry_datefmt != NULL);
497
498         datefmt_sample = GTK_WIDGET(g_object_get_data
499                                     (G_OBJECT(*widget), "datefmt_sample"));
500         g_return_if_fail(datefmt_sample != NULL);
501
502         text = gtk_editable_get_chars(GTK_EDITABLE(datefmt_sample), 0, -1);
503         g_free(prefs_common.date_format);
504         prefs_common.date_format = text;
505         gtk_entry_set_text(GTK_ENTRY(prefs_summaries->entry_datefmt), text);
506
507         gtk_widget_destroy(*widget);
508         *widget = NULL;
509 }
510
511 static void date_format_cancel_btn_clicked(GtkButton *button,
512                                            GtkWidget **widget)
513 {
514         g_return_if_fail(widget != NULL);
515         g_return_if_fail(*widget != NULL);
516
517         gtk_widget_destroy(*widget);
518         *widget = NULL;
519 }
520
521 static gboolean date_format_key_pressed(GtkWidget *keywidget, GdkEventKey *event,
522                                         GtkWidget **widget)
523 {
524         if (event && event->keyval == GDK_Escape)
525                 date_format_cancel_btn_clicked(NULL, widget);
526         return FALSE;
527 }
528
529 static gboolean date_format_on_delete(GtkWidget *dialogwidget,
530                                       GdkEventAny *event, GtkWidget **widget)
531 {
532         g_return_val_if_fail(widget != NULL, FALSE);
533         g_return_val_if_fail(*widget != NULL, FALSE);
534
535         *widget = NULL;
536         return FALSE;
537 }
538
539 static void date_format_entry_on_change(GtkEditable *editable,
540                                         GtkLabel *example)
541 {
542         time_t cur_time;
543         struct tm *cal_time;
544         gchar buffer[100];
545         gchar *text;
546
547         cur_time = time(NULL);
548         cal_time = localtime(&cur_time);
549         buffer[0] = 0;
550         text = gtk_editable_get_chars(editable, 0, -1);
551         if (text)
552                 strftime(buffer, sizeof buffer, text, cal_time); 
553         g_free(text);
554
555         text = conv_codeset_strdup(buffer,
556                                    conv_get_locale_charset_str(),
557                                    CS_UTF_8);
558         if (!text)
559                 text = g_strdup(buffer);
560
561         gtk_label_set_text(example, text);
562
563         g_free(text);
564 }
565
566 static void date_format_select_row(GtkTreeView *list_view,
567                                    GtkTreePath *path,
568                                    GtkTreeViewColumn *column,
569                                    GtkWidget *date_format)
570 {
571         gint cur_pos;
572         gchar *format;
573         const gchar *old_format;
574         gchar *new_format;
575         GtkWidget *datefmt_sample;
576         GtkTreeIter iter;
577         GtkTreeModel *model;
578         
579         g_return_if_fail(date_format != NULL);
580
581         /* only on double click */
582         datefmt_sample = GTK_WIDGET(g_object_get_data(G_OBJECT(date_format), 
583                                                       "datefmt_sample"));
584
585         g_return_if_fail(datefmt_sample != NULL);
586
587         model = gtk_tree_view_get_model(list_view);
588
589         /* get format from list */
590         if (!gtk_tree_model_get_iter(model, &iter, path))
591                 return;
592
593         gtk_tree_model_get(model, &iter, DATEFMT_FMT, &format, -1);             
594         
595         cur_pos = gtk_editable_get_position(GTK_EDITABLE(datefmt_sample));
596         old_format = gtk_entry_get_text(GTK_ENTRY(datefmt_sample));
597
598         /* insert the format into the text entry */
599         new_format = g_malloc(strlen(old_format) + 3);
600
601         strncpy(new_format, old_format, cur_pos);
602         new_format[cur_pos] = '\0';
603         strcat(new_format, format);
604         strcat(new_format, &old_format[cur_pos]);
605
606         gtk_entry_set_text(GTK_ENTRY(datefmt_sample), new_format);
607         gtk_editable_set_position(GTK_EDITABLE(datefmt_sample), cur_pos + 2);
608
609         g_free(new_format);
610 }