progress.*: cosmetix
[k8lowj.git] / src / datesel.c
blobbf27f586760fb77b0b18dad5569730a81590c6d3
1 /* logjam - a GTK client for LiveJournal.
2 * Copyright (C) 2000-2003 Evan Martin <evan@livejournal.com>
4 * vim: tabstop=4 shiftwidth=4 noexpandtab :
5 */
6 #include "gtk-all.h"
7 #include "util-gtk.h"
9 #include <stdlib.h>
10 #include <string.h>
12 #include "datesel.h"
14 #include "liblj/livejournal.h"
17 struct _DateSel {
18 GtkButton parent;
19 GtkWidget *label;
21 guint timeout_id;
23 struct tm date;
24 gboolean backdated;
28 static void datesel_init (DateSel *ds);
29 static void datesel_class_init (GtkButtonClass *class);
30 static void datesel_dialog_run (DateSel *ds);
32 static void timeout_enable (DateSel *ds, gboolean usenow);
35 /* gtk stuff */
36 GObjectClass *parent_class = NULL;
39 GType datesel_get_type (void) {
40 static GType ds_type = 0;
41 if (!ds_type) {
42 static const GTypeInfo ds_info = {
43 sizeof(GtkButtonClass),
44 NULL,
45 NULL,
46 (GClassInitFunc) datesel_class_init,
47 NULL,
48 NULL,
49 sizeof(DateSel),
51 (GInstanceInitFunc) datesel_init,
53 ds_type = g_type_register_static(GTK_TYPE_BUTTON, "DateSel", &ds_info, 0);
55 return ds_type;
59 static void datesel_finalize (GObject *obj) {
60 timeout_enable(DATESEL(obj), FALSE);
61 G_OBJECT_CLASS(parent_class)->finalize(obj);
65 static void datesel_class_init (GtkButtonClass *class) {
66 GObjectClass *oclass = G_OBJECT_CLASS(class);
67 parent_class = g_type_class_peek_parent(class);
68 oclass->finalize = datesel_finalize;
72 static void update_display (DateSel *ds) {
73 char *ljdate = lj_tm_to_ljdate_noseconds(&ds->date);
74 gtk_label_set_text(GTK_LABEL(ds->label), ljdate);
75 g_free(ljdate);
79 static gboolean timeout_cb (DateSel *ds) {
80 time_t curtime_time_t = time(NULL);
81 struct tm *curtime = localtime(&curtime_time_t);
82 ds->date = *curtime;
83 update_display(ds);
84 return TRUE;
88 static void timeout_enable (DateSel *ds, gboolean usenow) {
89 if (usenow && !ds->timeout_id) {
90 timeout_cb(ds);
91 ds->timeout_id = g_timeout_add(10 * 1000, /* every 10 sec. */
92 (GSourceFunc) timeout_cb, ds);
93 } else if (!usenow && ds->timeout_id) {
94 g_source_remove(ds->timeout_id);
95 ds->timeout_id = 0;
100 static void datesel_init (DateSel *ds) {
101 ds->label = gtk_label_new("meow");
102 gtk_container_add(GTK_CONTAINER(ds), ds->label);
103 gtk_button_set_relief(GTK_BUTTON(ds), GTK_RELIEF_NONE);
104 g_signal_connect(G_OBJECT(ds), "clicked", G_CALLBACK(datesel_dialog_run), NULL);
105 ds->timeout_id = 0;
106 timeout_enable(ds, TRUE);
110 GtkWidget *datesel_new (void) {
111 DateSel *ds = DATESEL(g_object_new(datesel_get_type(), NULL));
112 return GTK_WIDGET(ds);
116 void datesel_get_tm (DateSel *ds, struct tm *ptm) {
117 if (ds->timeout_id) memset(ptm, 0, sizeof(struct tm)); else *ptm = ds->date;
121 void datesel_set_tm (DateSel *ds, struct tm *ptm) {
122 if (ptm && ptm->tm_year) {
123 ds->date = *ptm;
124 timeout_enable(ds, FALSE);
125 } else {
126 timeout_enable(ds, TRUE);
128 update_display(ds);
132 gboolean datesel_get_backdated (DateSel *ds) {
133 return ds->backdated;
137 void datesel_set_backdated (DateSel *ds, gboolean backdated) {
138 ds->backdated = backdated;
142 static void usenow_cb (GtkToggleButton *cb, GtkWidget *box) {
143 if (gtk_toggle_button_get_active(cb)) gtk_widget_hide(box); else gtk_widget_show(box);
147 static void backdated_cb (GtkToggleButton *cb, DateSel *ds) {
148 ds->backdated = gtk_toggle_button_get_active(cb);
152 static gboolean minute_output_cb(GtkSpinButton *s) {
153 char buf[5];
154 g_snprintf(buf, 5, "%02d", (int)gtk_spin_button_get_value(s));
155 if (strcmp(buf, gtk_entry_get_text(GTK_ENTRY(s))) != 0) gtk_entry_set_text(GTK_ENTRY(s), buf);
156 return TRUE;
160 static void datesel_dialog_run (DateSel *ds) {
161 GtkWidget *dlg, *vbox;
162 GtkWidget *datebox, *cal;
163 GtkAdjustment *houradj, *minadj;
164 GtkWidget *hbox, *label, *hourspin, *minspin;
165 GtkWidget *check, *backdated;
166 guint year, month, day;
168 dlg = gtk_dialog_new_with_buttons(_("Select Date"),
169 GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(ds))),
170 GTK_DIALOG_MODAL, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL);
171 gtk_window_set_resizable(GTK_WINDOW(dlg), FALSE);
173 datebox = gtk_vbox_new(FALSE, 5);
174 cal = gtk_calendar_new();
175 gtk_calendar_select_month(GTK_CALENDAR(cal), ds->date.tm_mon, ds->date.tm_year + 1900);
176 gtk_calendar_select_day(GTK_CALENDAR(cal), ds->date.tm_mday);
177 gtk_box_pack_start(GTK_BOX(datebox), cal, TRUE, TRUE, 0);
179 hbox = gtk_hbox_new(FALSE, 5);
180 label = gtk_label_new_with_mnemonic(_("_Time:"));
181 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
182 houradj = (GtkAdjustment *)gtk_adjustment_new(ds->date.tm_hour, 0, 23, 1, 4, 4);
183 hourspin = gtk_spin_button_new(houradj, 1.0, 0);
184 gtk_label_set_mnemonic_widget(GTK_LABEL(label), hourspin);
186 minadj = (GtkAdjustment *)gtk_adjustment_new(ds->date.tm_min, 0, 59, 1, 10, 10);
187 minspin = gtk_spin_button_new(minadj, 1.0, 0);
188 gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(minspin), TRUE);
189 g_signal_connect(G_OBJECT(minspin), "output", G_CALLBACK(minute_output_cb), NULL);
191 if (gtk_widget_get_direction(hbox) == GTK_TEXT_DIR_RTL) {
192 /* even though we're right-to-left, hours still should
193 * be on the left of minutes. */
194 gtk_box_pack_start(GTK_BOX(hbox), minspin, FALSE, FALSE, 0);
195 gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(":"), FALSE, FALSE, 0);
196 gtk_box_pack_start(GTK_BOX(hbox), hourspin, FALSE, FALSE, 0);
197 } else {
198 gtk_box_pack_start(GTK_BOX(hbox), hourspin, FALSE, FALSE, 0);
199 gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(":"), FALSE, FALSE, 0);
200 gtk_box_pack_start(GTK_BOX(hbox), minspin, FALSE, FALSE, 0);
203 gtk_box_pack_start(GTK_BOX(datebox), hbox, FALSE, FALSE, 0);
205 check = gtk_check_button_new_with_mnemonic(_("Use _current date/time"));
206 g_signal_connect(G_OBJECT(check), "toggled", G_CALLBACK(usenow_cb), datebox);
208 backdated = gtk_check_button_new_with_mnemonic(_("Entry is _backdated"));
209 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(backdated), ds->backdated);
210 g_signal_connect(G_OBJECT(backdated), "toggled", G_CALLBACK(backdated_cb), ds);
212 vbox = gtk_vbox_new(FALSE, 10);
213 gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
214 gtk_box_pack_start(GTK_BOX(vbox), datebox, TRUE, TRUE, 0);
215 gtk_box_pack_start(GTK_BOX(vbox), backdated, FALSE, FALSE, 0);
217 jam_dialog_set_contents(GTK_DIALOG(dlg), vbox);
219 /* set it active here so it can hide the contents if necessary. */
220 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), ds->timeout_id != 0);
222 gtk_dialog_run(GTK_DIALOG(dlg));
224 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check))) {
225 timeout_enable(ds, TRUE);
226 } else {
227 timeout_enable(ds, FALSE);
228 gtk_calendar_get_date(GTK_CALENDAR(cal), &year, &month, &day);
229 ds->date.tm_year = year-1900;
230 ds->date.tm_mon = month;
231 ds->date.tm_mday = day;
232 ds->date.tm_hour = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(hourspin));
233 ds->date.tm_min = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(minspin));
235 update_display(ds);
236 gtk_widget_destroy(dlg);