it builds! (note that some autogenerated files are hardcoded now, and you can't build...
[k8lowj.git] / src / datesel.c
blobe099be133504be5ad56d469221caa671e8f59e63
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 */
7 #include "gtk-all.h"
8 #include <stdlib.h>
9 #include <string.h>
10 #include "liblj/livejournal.h"
12 #include "datesel.h"
14 struct _DateSel {
15 GtkButton parent;
16 GtkWidget *label;
18 guint timeout_id;
20 struct tm date;
21 gboolean backdated;
24 static void datesel_init(DateSel *ds);
25 static void datesel_class_init(GtkButtonClass *class);
26 static void datesel_dialog_run(DateSel *ds);
28 static void timeout_enable(DateSel *ds, gboolean usenow);
30 /* gtk stuff */
31 GObjectClass *parent_class = NULL;
33 GType
34 datesel_get_type(void) {
35 static GType ds_type = 0;
36 if (!ds_type) {
37 static const GTypeInfo ds_info = {
38 sizeof(GtkButtonClass),
39 NULL,
40 NULL,
41 (GClassInitFunc)datesel_class_init,
42 NULL,
43 NULL,
44 sizeof(DateSel),
46 (GInstanceInitFunc) datesel_init,
48 ds_type = g_type_register_static(GTK_TYPE_BUTTON, "DateSel",
49 &ds_info, 0);
51 return ds_type;
54 static void
55 datesel_finalize(GObject *obj) {
56 timeout_enable(DATESEL(obj), FALSE);
57 G_OBJECT_CLASS(parent_class)->finalize(obj);
60 static void
61 datesel_class_init(GtkButtonClass *class) {
62 GObjectClass *oclass = G_OBJECT_CLASS(class);
63 parent_class = g_type_class_peek_parent(class);
64 oclass->finalize = datesel_finalize;
67 static void
68 update_display(DateSel *ds) {
69 char *ljdate = lj_tm_to_ljdate_noseconds(&ds->date);
70 gtk_label_set_text(GTK_LABEL(ds->label), ljdate);
71 g_free(ljdate);
74 static gboolean
75 timeout_cb(DateSel *ds) {
76 time_t curtime_time_t = time(NULL);
77 struct tm *curtime = localtime(&curtime_time_t);
78 ds->date = *curtime;
79 update_display(ds);
80 return TRUE;
83 static void
84 timeout_enable(DateSel *ds, gboolean usenow) {
85 if (usenow && !ds->timeout_id) {
86 timeout_cb(ds);
87 ds->timeout_id = g_timeout_add(10*1000, /* every 10 sec. */
88 (GSourceFunc)timeout_cb, ds);
89 } else if (!usenow && ds->timeout_id) {
90 g_source_remove(ds->timeout_id);
91 ds->timeout_id = 0;
95 static void
96 datesel_init(DateSel *ds) {
97 ds->label = gtk_label_new("meow");
98 gtk_container_add(GTK_CONTAINER(ds), ds->label);
99 gtk_button_set_relief(GTK_BUTTON(ds), GTK_RELIEF_NONE);
100 g_signal_connect(G_OBJECT(ds), "clicked",
101 G_CALLBACK(datesel_dialog_run), NULL);
103 ds->timeout_id = 0;
104 timeout_enable(ds, TRUE);
107 GtkWidget*
108 datesel_new(void) {
109 DateSel *ds = DATESEL(g_object_new(datesel_get_type(), NULL));
111 return GTK_WIDGET(ds);
114 void
115 datesel_get_tm(DateSel *ds, struct tm *ptm) {
116 if (ds->timeout_id)
117 memset(ptm, 0, sizeof(struct tm));
118 else
119 *ptm = ds->date;
122 void
123 datesel_set_tm(DateSel *ds, struct tm *ptm) {
124 if (ptm && ptm->tm_year) {
125 ds->date = *ptm;
126 timeout_enable(ds, FALSE);
127 } else {
128 timeout_enable(ds, TRUE);
130 update_display(ds);
133 gboolean
134 datesel_get_backdated(DateSel *ds) {
135 return ds->backdated;
138 void
139 datesel_set_backdated(DateSel *ds, gboolean backdated) {
140 ds->backdated = backdated;
143 static void
144 usenow_cb(GtkToggleButton *cb, GtkWidget *box) {
145 if (gtk_toggle_button_get_active(cb))
146 gtk_widget_hide(box);
147 else
148 gtk_widget_show(box);
151 static void
152 backdated_cb(GtkToggleButton *cb, DateSel *ds) {
153 ds->backdated = gtk_toggle_button_get_active(cb);
156 static gboolean
157 minute_output_cb(GtkSpinButton *s) {
158 char buf[5];
159 g_snprintf(buf, 5, "%02d", (int)gtk_spin_button_get_value(s));
160 if (strcmp(buf, gtk_entry_get_text(GTK_ENTRY(s))) != 0)
161 gtk_entry_set_text(GTK_ENTRY(s), buf);
162 return TRUE;
165 static void
166 datesel_dialog_run(DateSel *ds) {
167 GtkWidget *dlg, *vbox;
168 GtkWidget *datebox, *cal;
169 GtkAdjustment *houradj, *minadj;
170 GtkWidget *hbox, *label, *hourspin, *minspin;
171 GtkWidget *check, *backdated;
172 guint year, month, day;
174 dlg = gtk_dialog_new_with_buttons(_("Select Date"),
175 GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(ds))),
176 GTK_DIALOG_MODAL,
177 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
178 NULL);
179 gtk_window_set_resizable(GTK_WINDOW(dlg), FALSE);
181 datebox = gtk_vbox_new(FALSE, 5);
182 cal = gtk_calendar_new();
183 gtk_calendar_select_month(GTK_CALENDAR(cal), ds->date.tm_mon, ds->date.tm_year+1900);
184 gtk_calendar_select_day(GTK_CALENDAR(cal), ds->date.tm_mday);
185 gtk_box_pack_start(GTK_BOX(datebox), cal, TRUE, TRUE, 0);
187 hbox = gtk_hbox_new(FALSE, 5);
188 label = gtk_label_new_with_mnemonic(_("_Time:"));
189 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
190 houradj = (GtkAdjustment*)gtk_adjustment_new(ds->date.tm_hour, 0, 23, 1, 4, 4);
191 hourspin = gtk_spin_button_new(houradj, 1.0, 0);
192 gtk_label_set_mnemonic_widget(GTK_LABEL(label), hourspin);
194 minadj = (GtkAdjustment*)gtk_adjustment_new(ds->date.tm_min, 0, 59, 1, 10, 10);
195 minspin = gtk_spin_button_new(minadj, 1.0, 0);
196 gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(minspin), TRUE);
197 g_signal_connect(G_OBJECT(minspin), "output",
198 G_CALLBACK(minute_output_cb), NULL);
200 if (gtk_widget_get_direction(hbox) == GTK_TEXT_DIR_RTL) {
201 /* even though we're right-to-left, hours still should
202 * be on the left of minutes. */
203 gtk_box_pack_start(GTK_BOX(hbox), minspin, FALSE, FALSE, 0);
204 gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(":"),
205 FALSE, FALSE, 0);
206 gtk_box_pack_start(GTK_BOX(hbox), hourspin, FALSE, FALSE, 0);
207 } else {
208 gtk_box_pack_start(GTK_BOX(hbox), hourspin, FALSE, FALSE, 0);
209 gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(":"),
210 FALSE, FALSE, 0);
211 gtk_box_pack_start(GTK_BOX(hbox), minspin, FALSE, FALSE, 0);
214 gtk_box_pack_start(GTK_BOX(datebox), hbox, FALSE, FALSE, 0);
216 check = gtk_check_button_new_with_mnemonic(_("Use _current date/time"));
217 g_signal_connect(G_OBJECT(check), "toggled",
218 G_CALLBACK(usenow_cb), datebox);
220 backdated = gtk_check_button_new_with_mnemonic(_("Entry is _backdated"));
221 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(backdated), ds->backdated);
222 g_signal_connect(G_OBJECT(backdated), "toggled",
223 G_CALLBACK(backdated_cb), ds);
225 vbox = gtk_vbox_new(FALSE, 10);
226 gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
227 gtk_box_pack_start(GTK_BOX(vbox), datebox, TRUE, TRUE, 0);
228 gtk_box_pack_start(GTK_BOX(vbox), backdated, FALSE, FALSE, 0);
230 jam_dialog_set_contents(GTK_DIALOG(dlg), vbox);
232 /* set it active here so it can hide the contents if necessary. */
233 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), ds->timeout_id != 0);
235 gtk_dialog_run(GTK_DIALOG(dlg));
237 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check))) {
238 timeout_enable(ds, TRUE);
239 } else {
240 timeout_enable(ds, FALSE);
241 gtk_calendar_get_date(GTK_CALENDAR(cal), &year, &month, &day);
242 ds->date.tm_year = year-1900;
243 ds->date.tm_mon = month;
244 ds->date.tm_mday = day;
245 ds->date.tm_hour = gtk_spin_button_get_value_as_int(
246 GTK_SPIN_BUTTON(hourspin));
247 ds->date.tm_min = gtk_spin_button_get_value_as_int(
248 GTK_SPIN_BUTTON(minspin));
250 update_display(ds);
251 gtk_widget_destroy(dlg);