about.c: cosmetix
[k8lowj.git] / src / history.c
blobce69d9c1cbed6f1915233f787375a115a9e67586
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 <time.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
13 #include "liblj/getevents.h"
15 #include "conf.h"
16 #include "network.h"
17 #include "spawn.h"
18 #include "history.h"
20 #if 0
21 typedef struct {
22 GtkWidget *win;
23 GtkWidget *daylabel;
24 GtkWidget *evlist;
25 GtkWidget *bbox;
26 guint firstyear, lastyear;
27 guint year, mon, day;
29 /* because day is never greater than 31, we can use a bitfield. */
30 guint32 *markmonths;
31 } history_calendar_dlg;
32 #define MARKMONTH(h, year, mon) (h)->markmonths[((year)-(h)->firstyear)*12+((mon)-1)]
33 #define MARKMONTH_CUR(h) MARKMONTH(h, h->year, h->mon)
35 /*typedef struct {
36 GtkWidget *win;
37 GtkWidget *esubject;
38 GtkWidget *eentry;
39 GtkWidget *eyear, *emon, *eday, *ehour, *emin;
40 GtkWidget *metamgr, *secmgr;
41 security_data security;
42 int itemid;
44 history_calendar_dlg *hcdlg;
45 } history_item_dlg;*/
47 static gboolean getdaycounts_run(history_calendar_dlg* hcdlg);
48 void popcalendar_run(GtkWidget *parent, guint date[], int markfirstyear, guint32 marks[]);
50 static void change_day(history_calendar_dlg *hcdlg);
53 static void hc_row_selected(GtkCList *list, gint row, gint col,
54 GdkEventButton *event, history_calendar_dlg *hcdlg);
55 static gint hc_list_click_cb(GtkCList *list, GdkEventButton *be,
56 history_calendar_dlg *hcdlg);
57 static void hc_edit_cb(GtkWidget *w, history_calendar_dlg *hcdlg);
58 //static void hc_web_cb(GtkWidget *w, history_calendar_dlg *hcdlg);
60 /* fixme static gint hi_dialog_run(GtkWidget *parent, int itemid);*/
62 static void
63 free_dlg_cb(GtkWidget *w, history_calendar_dlg *hcdlg) {
64 if (hcdlg->markmonths) g_free(hcdlg->markmonths);
65 g_free(hcdlg);
68 void set_date(history_calendar_dlg *hcdlg) {
69 time_t ttime;
70 struct tm tm, *ptm;
71 char buf[200];
73 memset(&tm, 0, sizeof(struct tm));
74 tm.tm_year = hcdlg->year-1900; tm.tm_mon = hcdlg->mon-1; tm.tm_mday = hcdlg->day;
76 /* convert to time_t and back, so the weekday and such get updated. */
77 ttime = mktime(&tm);
78 ptm = localtime(&ttime);
80 strftime(buf, 199, "%A, %d %B %Y", ptm);
81 gtk_label_set_text(GTK_LABEL(hcdlg->daylabel), buf);
82 change_day(hcdlg);
85 void set_current_date(history_calendar_dlg *hcdlg) {
86 time_t curtime;
87 struct tm *ptm;
89 curtime = time(NULL);
90 ptm = localtime(&curtime);
92 hcdlg->year = ptm->tm_year + 1900;
93 hcdlg->mon = ptm->tm_mon + 1;
94 hcdlg->day = ptm->tm_mday;
96 set_date(hcdlg);
99 static void
100 popup_calendar(GtkWidget *w, history_calendar_dlg *hcdlg) {
101 guint date[3];
102 date[0] = hcdlg->year;
103 date[1] = hcdlg->mon;
104 date[2] = hcdlg->day;
106 popcalendar_run(hcdlg->win, date, hcdlg->firstyear, hcdlg->markmonths);
108 if (hcdlg->year != date[0] || hcdlg->mon != date[1] || hcdlg->day != date[2]) {
109 hcdlg->year = date[0];
110 hcdlg->mon = date[1];
111 hcdlg->day = date[2];
112 set_date(hcdlg);
116 static GtkWidget*
117 make_contents(history_calendar_dlg *hcdlg) {
118 GtkWidget *vbox, *button, *scrollwin;
119 gchar *titles[] = { "Time", "Event" };
121 button = gtk_button_new();
122 hcdlg->daylabel = gtk_label_new("");
123 g_signal_connect(G_OBJECT(button), "clicked",
124 G_CALLBACK(popup_calendar), hcdlg);
125 gtk_container_add(GTK_CONTAINER(button), hcdlg->daylabel);
127 scrollwin = gtk_scrolled_window_new (NULL, NULL);
128 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW
129 (scrollwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
130 hcdlg->evlist = gtk_clist_new_with_titles(2, titles);
131 gtk_clist_set_selection_mode(GTK_CLIST(hcdlg->evlist),
132 GTK_SELECTION_BROWSE);
133 g_signal_connect(G_OBJECT(hcdlg->evlist), "select-row",
134 G_CALLBACK(hc_row_selected), hcdlg);
135 g_signal_connect(G_OBJECT(hcdlg->evlist), "unselect-row",
136 G_CALLBACK(hc_row_selected), hcdlg);
137 g_signal_connect(G_OBJECT(hcdlg->evlist), "button_press_event",
138 G_CALLBACK(hc_list_click_cb), hcdlg);
139 gtk_clist_column_titles_passive(GTK_CLIST(hcdlg->evlist));
140 /* fixme gtk2 gtk_clist_set_column_width(GTK_CLIST(hcdlg->evlist), 0,
141 gdk_string_width(hcdlg->evlist->style->font, "00:00a"));*/
142 titles[0] = NULL;
143 titles[1] = "[select a day]";
144 gtk_clist_append(GTK_CLIST(hcdlg->evlist), titles);
145 gtk_clist_set_selectable(GTK_CLIST(hcdlg->evlist), 0, FALSE);
146 gtk_container_add(GTK_CONTAINER(scrollwin), hcdlg->evlist);
148 vbox = gtk_vbox_new(FALSE, 5);
149 gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
150 gtk_box_pack_start(GTK_BOX(vbox), scrollwin, TRUE, TRUE, 0);
151 return vbox;
154 static GtkWidget*
155 make_buttonbox(history_calendar_dlg *hcdlg) {
156 GtkWidget *box, *button;
158 box = jam_dialog_buttonbox_new();
159 button = gtk_button_new_with_label(" Edit... ");
160 g_signal_connect(G_OBJECT(button), "clicked",
161 G_CALLBACK(hc_edit_cb), hcdlg);
162 jam_dialog_buttonbox_add(box, button);
164 /*button = web_button(hcdlg->win, "View...");
165 g_signal_connect(G_OBJECT(button), "clicked",
166 G_CALLBACK(hc_web_cb), hcdlg);
167 jam_dialog_buttonbox_add(box, button);*/
168 return box;
171 void history_dialog(GtkWidget *mainwin) {
172 history_calendar_dlg *hcdlg;
174 hcdlg = g_new0(history_calendar_dlg, 1);
176 hcdlg->win = jam_dialog_new(mainwin, "History Overview", 400, -1);
177 g_signal_connect(G_OBJECT(hcdlg->win), "destroy",
178 G_CALLBACK(free_dlg_cb), hcdlg);
180 hcdlg->bbox = make_buttonbox(hcdlg);
181 jam_dialog_set_contents_buttonbox(hcdlg->win,
182 make_contents(hcdlg),
183 hcdlg->bbox);
185 jam_dialog_add_close(hcdlg->win);
186 gtk_widget_set_sensitive(hcdlg->bbox, FALSE);
187 gtk_widget_show(hcdlg->win);
189 if (!getdaycounts_run(hcdlg))
190 return;
191 set_current_date(hcdlg);
194 static void
195 daycounts_hash_extents_cb(gpointer key, gpointer value, gpointer data) {
196 history_calendar_dlg *hcdlg = data;
197 int year;
198 if (sscanf((char*)key, "%4d", &year) < 1)
199 return;
201 if (hcdlg->firstyear == 0)
202 hcdlg->firstyear = year;
204 if (year < hcdlg->firstyear)
205 hcdlg->firstyear = year;
207 if (year > hcdlg->lastyear)
208 hcdlg->lastyear = year;
211 static void
212 daycounts_hash_cb(gpointer key, gpointer value, gpointer data) {
213 history_calendar_dlg *hcdlg = data;
214 char *date = key;
215 char *str = value;
216 int year, month, day;
218 if (str[0] == 0 || str[0] == '0') return; /* no entries this date? */
220 if (sscanf(date, "%4d-%2d-%2d", &year, &month, &day) < 3)
221 return;
223 if (hcdlg->firstyear == 0)
224 hcdlg->firstyear = year;
226 MARKMONTH(hcdlg, year, month) |= (1L << day);
229 static gboolean
230 getdaycounts_run(history_calendar_dlg* hcdlg) {
231 NetRequest *request;
232 NetResult *result;
234 request = XXX("getdaycounts");
236 result = net_request_run(hcdlg->win, "Loading calendar...", request);
237 net_request_free(request);
239 if (!net_result_succeeded(result)) {
240 net_result_free(result);
241 gtk_widget_destroy(hcdlg->win);
242 return FALSE;
245 /* we must iterate through the hash once to find the range of the returned years. */
246 g_hash_table_foreach(result, daycounts_hash_extents_cb, hcdlg);
248 if (hcdlg->markmonths) g_free(hcdlg->markmonths);
249 hcdlg->markmonths = g_new0(guint32,
250 12 * (hcdlg->lastyear - hcdlg->firstyear + 1));
252 /* then read all of the values from the hash. */
253 g_hash_table_foreach(result, daycounts_hash_cb, hcdlg);
255 net_result_free(result);
256 return TRUE;
259 static void
260 change_day(history_calendar_dlg *hcdlg) {
261 int count, i, itemid;
262 char key[50];
263 char *str, *event;
264 int hour, minute;
265 gint row;
266 char *append[2];
268 NetRequest *request;
269 NetResult *result;
271 if (hcdlg->firstyear == 0) return; /* this can happen if they cancelled the getdaycounts */
273 request = XXX("getevents");
275 net_request_seti(request, "truncate", 50);
276 net_request_seti(request, "prefersubject", 1);
277 net_request_seti(request, "noprops", 1);
278 net_request_copys(request, "selecttype", "day");
279 net_request_copys(request, "lineendings", "dots");
281 net_request_seti(request, "year", hcdlg->year);
282 net_request_seti(request, "month", hcdlg->mon);
283 net_request_seti(request, "day", hcdlg->day);
285 result = net_request_run(hcdlg->win, "Loading day calendar...", request);
286 net_request_free(request);
288 if (!net_result_succeeded(result)) {
289 net_result_free(result);
290 return;
293 /* it would have been better if net_result_geti used a GError */
294 str = net_result_get(result, "events_count");
295 if (str == NULL) return;
296 count = atoi(str);
298 if (count == 0) {
299 /* FIXME? no events this day; whoops. can happen if they delete. */
300 MARKMONTH_CUR(hcdlg) &= ~(1L << hcdlg->day);
301 gtk_clist_clear(GTK_CLIST(hcdlg->evlist));
302 append[0] = "";
303 append[1] = "[no events]";
304 gtk_clist_append(GTK_CLIST(hcdlg->evlist), append);
305 gtk_clist_set_selectable(GTK_CLIST(hcdlg->evlist), 0, FALSE);
306 net_result_free(result);
307 return;
310 gtk_clist_freeze(GTK_CLIST(hcdlg->evlist));
311 gtk_clist_clear(GTK_CLIST(hcdlg->evlist));
313 for (i = 1; i < count+1; i++) {
314 sprintf(key, "events_%d_event", i);
315 event = net_result_get(result, key);
317 sprintf(key, "events_%d_eventtime", i);
318 str = net_result_get(result, key);
319 sscanf(str+11, "%2d:%2d", &hour, &minute);
321 sprintf(key, "events_%d_itemid", i);
322 str = net_result_get(result, key);
323 if (str == NULL) continue;
324 itemid = atoi(str);
326 sprintf(key, "%02d:%02d", hour, minute);
327 append[0] = key;
328 append[1] = event;
329 row = gtk_clist_append(GTK_CLIST(hcdlg->evlist), append);
330 gtk_clist_set_row_data(GTK_CLIST(hcdlg->evlist), row, GINT_TO_POINTER(itemid));
332 gtk_clist_thaw(GTK_CLIST(hcdlg->evlist));
333 gtk_clist_set_column_width(GTK_CLIST(hcdlg->evlist), 0,
334 gtk_clist_optimal_column_width(GTK_CLIST(hcdlg->evlist), 0));
336 net_result_free(result);
339 static void
340 hc_row_selected(GtkCList *list,
341 gint row, gint col,
342 GdkEventButton *event,
343 history_calendar_dlg *hcdlg)
345 if (hcdlg->bbox)
346 gtk_widget_set_sensitive(hcdlg->bbox, (list->selection != NULL));
349 static int
350 hc_current_itemid(history_calendar_dlg *hcdlg) {
351 int row;
352 int itemid;
354 if (GTK_CLIST(hcdlg->evlist)->selection == NULL) return -1;
355 row = (int)GTK_CLIST(hcdlg->evlist)->selection->data;
356 itemid = (int)gtk_clist_get_row_data(GTK_CLIST(hcdlg->evlist), row);
357 return itemid;
360 static void
361 hc_show_current(history_calendar_dlg *hcdlg) {
362 int itemid = hc_current_itemid(hcdlg);
363 if (itemid < 0)
364 return;
366 /* fixme hi_dialog_run(hcdlg->win, itemid); */
369 static gint
370 hc_list_click_idle_cb(gpointer d) {
371 gdk_threads_enter();
372 hc_show_current(d);
373 gdk_threads_leave();
374 return FALSE;
377 static gint
378 hc_list_click_cb(GtkCList *list, GdkEventButton *be,
379 history_calendar_dlg *hcdlg)
381 /* if they double click, show the history item window */
382 if (be->button == 1 && be->type == GDK_2BUTTON_PRESS) {
383 gtk_idle_add(hc_list_click_idle_cb, hcdlg);
385 return 0;
388 static void
389 hc_edit_cb(GtkWidget *w, history_calendar_dlg *hcdlg) {
390 hc_show_current(hcdlg);
393 /*static void
394 history_delete_selected(history_item_dlg *hidlg) {
395 GHashTable *request, *result;
397 request = XXX("editevent");
399 g_hash_table_insert(request, g_strdup("itemid"),
400 g_strdup_printf("%d", hidlg->itemid));
402 g_hash_table_insert(request, g_strdup("event"), g_strdup(""));
404 result = net_request_run(hidlg->win, "Deleting event...", request);
406 hash_destroy(request);
408 if (net_request_succeeded(result)) {
409 gtk_widget_destroy(hidlg->win);
411 hash_destroy(result);
414 /*static void
415 hc_web_cb(GtkWidget *w, history_calendar_dlg *hcdlg) {
416 char *spawn;
418 spawn = g_strdup_printf("%s/talkread.bml?itemid=%d",
419 c_cur_server()->url,
420 hc_current_itemid(hcdlg));
421 spawn_url(spawn);
422 g_free(spawn);
425 fixme
426 static void
427 hi_load_metadata(history_item_dlg *hidlg, GHashTable *result) {
428 GHashTable *metadata;
429 int metacount, i;
430 char key[50];
432 metacount = atoi(g_hash_table_lookup(result, "prop_count"));
434 if (metacount < 1)
435 return;
437 metadata = g_hash_table_new(g_str_hash, g_str_equal);
439 for (i = 1; i < metacount + 1; i++) { /* sequence is 1-based! */
440 char *name, *value;
442 sprintf(key, "prop_%d_name", i);
443 name = g_hash_table_lookup(result, key);
444 sprintf(key, "prop_%d_value", i);
445 value = g_hash_table_lookup(result, key);
446 g_hash_table_insert(metadata,
447 g_strdup_printf("prop_%s", name),
448 g_strdup(value));
450 metamgr_load_from_request(METAMGR(hidlg->metamgr), metadata);
451 hash_destroy(metadata);
454 static void
455 hi_load_security(history_item_dlg *hidlg, GHashTable *result) {
456 char *sectext, *allowmask;
458 sectext = g_hash_table_lookup(result, "events_1_security");
459 if (sectext == NULL)
460 return;
462 allowmask = g_hash_table_lookup(result, "events_1_allowmask");
463 security_load(&hidlg->security, sectext, allowmask);
466 void
467 int_to_entry(GtkWidget *entry, int val) {
468 char buf[100];
469 sprintf(buf, "%02d", val);
470 gtk_entry_set_text(GTK_ENTRY(entry), buf);
473 static void
474 hi_load_datetime(history_item_dlg *hidlg, GHashTable *result) {
475 char *timestr;
476 int year, mon, day, hour, min, sec;
478 timestr = g_hash_table_lookup(result, "events_1_eventtime");
479 sscanf(timestr, "%4d-%2d-%2d %2d:%2d:%2d",
480 &year, &mon, &day, &hour, &min, &sec);
481 int_to_entry(hidlg->eyear, year);
482 int_to_entry(hidlg->emon, mon);
483 int_to_entry(hidlg->eday, day);
484 int_to_entry(hidlg->ehour, hour);
485 int_to_entry(hidlg->emin, min);
486 /* int_to_entry(hidlg->esec, sec); */
489 static GHashTable*
490 hi_request_run(history_item_dlg *hidlg, int itemid) {
491 GHashTable *request, *result;
493 request = XXX("getevents");
495 g_hash_table_insert(request, g_strdup("selecttype"), g_strdup("one"));
496 g_hash_table_insert(request, g_strdup("lineendings"), g_strdup("unix"));
497 g_hash_table_insert(request, g_strdup("itemid"), g_strdup_printf("%d", itemid));
499 result = net_request_run(hidlg->win, "Loading event...", request);
500 net_request_destroy(request);
502 if (!net_request_succeeded(result)) {
503 net_result_free(result);
504 return NULL;
506 return result;
509 static gboolean
510 hi_load_result(history_item_dlg *hidlg, GHashTable* result) {
511 gint insert_point;
512 char *value;
514 value = g_hash_table_lookup(result, "events_count");
515 if (value == NULL || strcmp(value, "1") != 0) {
516 jam_messagebox(hidlg->win, "Error Loading Event",
517 "Event not found.");
518 net_result_free(result);
519 return FALSE;
522 value = g_hash_table_lookup(result, "events_1_event");
523 gtk_editable_delete_text(GTK_EDITABLE(hidlg->eentry), 0, -1);
524 insert_point = 0;
525 gtk_editable_insert_text(GTK_EDITABLE(hidlg->eentry),
526 value, strlen(value), &insert_point);
527 /* fixme gtkspell gtkspell_check_all(GTK_TEXT(hidlg->eentry)); */
528 gtk_editable_set_position(GTK_EDITABLE(hidlg->eentry), 0);
530 /* subject */
531 value = g_hash_table_lookup(result, "events_1_subject");
532 if (value)
533 gtk_entry_set_text(GTK_ENTRY(hidlg->esubject), value);
535 /* we grab the "official" itemid, too, to support "latest entry". */
536 value = g_hash_table_lookup(result, "events_1_itemid");
537 if (value)
538 hidlg->itemid = atoi(value);
540 hi_load_datetime(hidlg, result);
541 hi_load_security(hidlg, result);
542 hi_load_metadata(hidlg, result);
543 net_result_free(result);
544 return TRUE;
547 static void
548 hi_save_cb(GtkWidget *w, history_item_dlg *hidlg) {
549 GHashTable *request, *result;
551 request = XXX("editevent");
553 g_hash_table_insert(request, g_strdup("itemid"),
554 g_strdup_printf("%d", hidlg->itemid));
555 g_hash_table_insert(request, g_strdup("year"),
556 gtk_editable_get_chars(GTK_EDITABLE(hidlg->eyear), 0, -1));
557 g_hash_table_insert(request, g_strdup("mon"),
558 gtk_editable_get_chars(GTK_EDITABLE(hidlg->emon), 0, -1));
559 g_hash_table_insert(request, g_strdup("day"),
560 gtk_editable_get_chars(GTK_EDITABLE(hidlg->eday), 0, -1));
561 g_hash_table_insert(request, g_strdup("hour"),
562 gtk_editable_get_chars(GTK_EDITABLE(hidlg->ehour), 0, -1));
563 g_hash_table_insert(request, g_strdup("min"),
564 gtk_editable_get_chars(GTK_EDITABLE(hidlg->emin), 0, -1));
566 g_hash_table_insert(request, g_strdup("subject"),
567 gtk_editable_get_chars(GTK_EDITABLE(hidlg->esubject), 0, -1));
568 g_hash_table_insert(request, g_strdup("event"),
569 gtk_editable_get_chars(GTK_EDITABLE(hidlg->eentry), 0, -1));
570 metamgr_append_to_request(METAMGR(hidlg->metamgr), request);
571 security_append_to_request(&hidlg->security, request);
573 result = net_request_run(hidlg->win, "Saving Item...", request);
574 net_request_free(request);
576 net_result_free(result);
579 static void
580 hi_delete_cb(GtkWidget *w, history_item_dlg *hidlg) {
581 if (conf.options.confirmdelete)
582 if (!jam_confirm(hidlg->win, "Delete?", "Delete this entry?"))
583 return;
585 history_delete_selected(hidlg);
588 static GtkWidget*
589 hi_dialog_date_hbox(history_item_dlg *hidlg) {
590 GtkWidget *hbox;
591 GtkWidget *label;
592 int twocharwidth;
594 hbox = gtk_hbox_new(FALSE, 0); {
595 /* year */
596 hidlg->eyear = gtk_entry_new_with_max_length(4);
597 /* fixme gtk2 twocharwidth = gdk_string_width(hidlg->eyear->style->font, "00");*/
598 twocharwidth = 20;
599 gtk_box_pack_start(GTK_BOX(hbox), hidlg->eyear, FALSE, FALSE, 0);
600 gtk_widget_set_usize(GTK_WIDGET(hidlg->eyear), twocharwidth*2 + 5, -1);
601 /* dash */
602 label = gtk_label_new("-"); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2);
603 /* month */
604 hidlg->emon = gtk_entry_new_with_max_length(2);
605 gtk_box_pack_start(GTK_BOX(hbox), hidlg->emon, FALSE, FALSE, 0);
606 gtk_widget_set_usize(GTK_WIDGET(hidlg->emon), twocharwidth + 5, -1);
607 /* dash */
608 label = gtk_label_new("-"); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2);
609 /* day */
610 hidlg->eday = gtk_entry_new_with_max_length(2);
611 gtk_box_pack_start(GTK_BOX(hbox), hidlg->eday, FALSE, FALSE, 0);
612 gtk_widget_set_usize(GTK_WIDGET(hidlg->eday), twocharwidth + 5, -1);
614 return hbox;
617 static GtkWidget*
618 hi_dialog_time_hbox(history_item_dlg *hidlg) {
619 GtkWidget *hbox;
620 GtkWidget *label;
621 int twocharwidth;
623 hbox = gtk_hbox_new(FALSE, 0); {
624 /* hour */
625 hidlg->ehour = gtk_entry_new_with_max_length(2);
626 twocharwidth = gdk_string_width(hidlg->ehour->style->font, "00");
627 gtk_box_pack_start(GTK_BOX(hbox), hidlg->ehour, FALSE, FALSE, 0);
628 gtk_widget_set_usize(GTK_WIDGET(hidlg->ehour), twocharwidth + 5, -1);
629 /* colon */
630 label = gtk_label_new(":"); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2);
631 /* min */
632 hidlg->emin = gtk_entry_new_with_max_length(2);
633 gtk_box_pack_start(GTK_BOX(hbox), hidlg->emin, FALSE, FALSE, 0);
634 gtk_widget_set_usize(GTK_WIDGET(hidlg->emin), twocharwidth + 5, -1);
636 return hbox;
639 static gint
640 hi_dialog_run(GtkWidget *parent, int itemid) {
641 history_item_dlg hidlg_actual = { 0 };
642 history_item_dlg *hidlg = &hidlg_actual;
643 GtkWidget *vbox, *button;
644 NetResult *result;
646 hidlg->itemid = itemid;
647 result = hi_request_run(hidlg, itemid);
648 if (result == NULL)
649 return 0;
651 hidlg->win = jam_dialog_new(parent, "History Item", 300, 300);
652 geometry_tie(hidlg->win, GEOM_HISTORY_ITEM);
653 g_signal_connect(G_OBJECT(hidlg->win), "destroy",
654 G_CALLBACK(gtk_main_quit), NULL);
656 vbox = gtk_vbox_new(FALSE, 5); {
657 GtkWidget *hbox, *scroll;
659 hbox = gtk_hbox_new(FALSE, 5); {
660 gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new("Subject:"),
661 FALSE, FALSE, 0);
662 hidlg->esubject = gtk_entry_new();
664 gtk_widget_set_usize(hidlg->esubject, 100, -1);
665 /* usize is just the minimum size... */
666 gtk_box_pack_start(GTK_BOX(hbox), hidlg->esubject, TRUE, TRUE, 0);
669 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
671 hbox = gtk_hbox_new(FALSE, 5); {
672 gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new("Date:"),
673 FALSE, FALSE, 0);
674 gtk_box_pack_start(GTK_BOX(hbox), hi_dialog_date_hbox(hidlg),
675 FALSE, FALSE, 0);
677 gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new("Time:"),
678 FALSE, FALSE, 0);
679 gtk_box_pack_start(GTK_BOX(hbox), hi_dialog_time_hbox(hidlg),
680 FALSE, FALSE, 0);
682 hidlg->security.type = conf.defaultsecurity;
683 hidlg->secmgr = secmgr_new(&hidlg->security);
684 gtk_box_pack_end(GTK_BOX(hbox), hidlg->secmgr, FALSE, FALSE, 0);
685 gtk_box_pack_end(GTK_BOX(hbox), gtk_label_new("Security:"),
686 FALSE, FALSE, 0);
688 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
690 scroll = gtk_scrolled_window_new(NULL, NULL); {
691 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
692 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
694 hidlg->eentry = gtk_text_new(NULL, NULL);
695 /* fixme gtkspell gtkspell_attach(GTK_TEXT(hidlg->eentry)); */
696 gtk_text_set_editable(GTK_TEXT(hidlg->eentry), TRUE);
697 gtk_text_set_word_wrap(GTK_TEXT(hidlg->eentry), TRUE);
698 gtk_container_add(GTK_CONTAINER(scroll), hidlg->eentry);
700 gtk_box_pack_start(GTK_BOX(vbox), scroll, TRUE, TRUE, 0);
702 hidlg->metamgr = metamgr_new(GTK_BOX(vbox));
703 gtk_box_pack_end(GTK_BOX(vbox), hidlg->metamgr, FALSE, FALSE, 0);
706 jam_dialog_set_contents(hidlg->win, vbox);
708 button = gtk_button_new_with_label(" Save Changes ");
709 g_signal_connect(G_OBJECT(button), "clicked",
710 G_CALLBACK(hi_save_cb), (gpointer) hidlg);
711 jam_dialog_add_button(hidlg->win, button);
713 button = gtk_button_new_with_label(" Delete ");
714 g_signal_connect(G_OBJECT(button), "clicked",
715 G_CALLBACK(hi_delete_cb), (gpointer) hidlg);
716 jam_dialog_add_button(hidlg->win, button);
718 jam_dialog_add_close(hidlg->win);
720 hi_load_result(hidlg, result);
722 gtk_widget_realize(hidlg->win);
723 gtk_widget_realize(hidlg->secmgr);
724 gtk_widget_show(hidlg->win);
726 gtk_main();
728 return 0;
730 #endif
732 LJEntry*
733 history_load_itemid(GtkWindow *parent, JamAccount *acc, const char *usejournal, int itemid) {
734 NetContext *ctx;
735 LJGetEventsSingle *getevents;
736 LJEntry *entry;
738 if (!JAM_ACCOUNT_IS_LJ(acc)) {
739 g_warning("XXX blogger: history for blogger\n");
740 return NULL;
743 getevents = lj_getevents_single_new(jam_account_lj_get_user(JAM_ACCOUNT_LJ(acc)), usejournal, itemid);
744 ctx = net_ctx_gtk_new(parent, _("Loading Entry"));
745 if (!net_run_verb_ctx((LJVerb*)getevents, ctx, NULL)) {
746 lj_getevents_single_free(getevents, TRUE);
747 net_ctx_gtk_free(ctx);
748 return NULL;
750 entry = getevents->entry;
751 lj_getevents_single_free(getevents, FALSE);
752 net_ctx_gtk_free(ctx);
754 return entry;
757 LJEntry*
758 history_load_latest(GtkWindow *win, JamAccount *acc, const char *usejournal) {
759 return history_load_itemid(win, acc, usejournal, -1);