about.c: cosmetix
[k8lowj.git] / src / history_recent.c
blob404e0a8d9dc0c8012df2b62b941bc8f29ae8868f
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>
10 #include "liblj/getevents.h"
12 #include "util-gtk.h"
13 #include "history.h"
14 #include "network.h"
15 #include "util.h"
17 /* how many entries to load each time "load more..." is clicked. */
18 #define HISTORY_LOAD_BATCH 20
20 typedef struct {
21 GtkWidget *win;
22 GtkListStore *recentstore;
23 GtkWidget *recentview;
24 GtkWidget *lstats;
25 GtkWidget *bloadmore;
26 char *lastdate;
28 JamAccount *account;
29 const char *usejournal;
30 GdkPixbuf *pb_friends, *pb_private;
31 } HistoryUI;
33 enum {
34 COL_SECURITY,
35 COL_DATE,
36 COL_SUBJECT,
37 COL_ITEMID,
38 COL_COUNT
41 static void
42 recalculate_stats(HistoryUI *hui) {
43 GtkTreeModel *model;
44 GtkTreeIter iter;
45 GdkPixbuf *pb;
46 char *stats;
48 int ecount, pecount, fecount;
50 ecount = pecount = fecount = 0;
52 model = gtk_tree_view_get_model(GTK_TREE_VIEW(hui->recentview));
53 if (!gtk_tree_model_get_iter_first(model, &iter)) {
54 /* no history. */
55 gtk_label_set_text(GTK_LABEL(hui->lstats), "");
56 return;
59 do {
60 gtk_tree_model_get(model, &iter,
61 COL_SECURITY, &pb,
62 -1);
63 ecount++;
65 /* FIXME: gross hack. */
66 if (pb == hui->pb_friends)
67 fecount++;
68 else if (pb == hui->pb_private)
69 pecount++;
71 } while (gtk_tree_model_iter_next(model, &iter));
72 stats = g_strdup_printf(_("%d entries displayed. "
73 "%.1f%% public / %.1f%% friends-only / %.1f%% private."),
74 ecount,
75 100.0f * (ecount - pecount - fecount) / (float)ecount,
76 100.0f * fecount / (float)ecount,
77 100.0f * pecount / (float)ecount);
78 gtk_label_set_text(GTK_LABEL(hui->lstats), stats);
79 g_free(stats);
82 static int
83 load_recent(HistoryUI *hui, GtkWindow *parent) {
84 LJGetEventsRecent *getevents;
85 int i, count;
86 GtkTreeIter iter;
87 GdkPixbuf *pb;
88 NetContext *ctx;
90 if (!JAM_ACCOUNT_IS_LJ(hui->account)) {
91 g_warning("XXX blogger: history for blogger\n");
92 return -1;
95 getevents = lj_getevents_recent_new(
96 jam_account_lj_get_user(JAM_ACCOUNT_LJ(hui->account)),
97 hui->usejournal, HISTORY_LOAD_BATCH,
98 hui->lastdate, TRUE, 100);
99 ctx = net_ctx_gtk_new(parent, _("Loading History"));
100 if (!net_run_verb_ctx((LJVerb*)getevents, ctx, NULL)) {
101 lj_getevents_recent_free(getevents, TRUE);
102 net_ctx_gtk_free(ctx);
103 return -1;
106 count = getevents->entry_count;
107 for (i = 0; i < count; i++) {
108 LJEntry *entry = getevents->entries[i];
109 char *date = lj_tm_to_ljdate(&entry->time);
110 switch (entry->security.type) {
111 case LJ_SECURITY_FRIENDS:
112 case LJ_SECURITY_CUSTOM:
113 pb = hui->pb_friends; break;
114 case LJ_SECURITY_PRIVATE:
115 pb = hui->pb_private; break;
116 default:
117 pb = NULL; /* public: no icon */
119 gtk_list_store_append(hui->recentstore, &iter);
120 gtk_list_store_set(hui->recentstore, &iter,
121 COL_SECURITY, pb,
122 COL_DATE, date,
123 /* because we set summary=TRUE above, the real subject
124 * is returned in event. */
125 COL_SUBJECT, entry->event,
126 COL_ITEMID, entry->itemid,
127 -1);
128 g_free(date);
131 if (count < HISTORY_LOAD_BATCH) {
132 /* we've reached the beginning of history. */
133 gtk_widget_set_sensitive(hui->bloadmore, FALSE);
134 } else if (count > 0) {
135 string_replace(&hui->lastdate,
136 lj_tm_to_ljdate(&getevents->entries[count-1]->time));
139 recalculate_stats(hui);
141 lj_getevents_recent_free(getevents, TRUE);
142 net_ctx_gtk_free(ctx);
144 return count;
147 static void
148 load_more_cb(GtkWidget *w, HistoryUI *hui) {
149 load_recent(hui, GTK_WINDOW(hui->win));
152 static void
153 row_activated_cb(GtkTreeView *treeview, GtkTreePath *arg1, GtkTreeViewColumn *arg2, HistoryUI* hui) {
154 gtk_dialog_response(GTK_DIALOG(hui->win), GTK_RESPONSE_OK);
157 static GtkWidget*
158 make_recentview(HistoryUI *hui) {
159 GtkCellRenderer *renderer;
160 GtkTreeViewColumn *column;
162 hui->recentview =
163 gtk_tree_view_new_with_model(GTK_TREE_MODEL(hui->recentstore));
164 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(hui->recentview), TRUE);
165 g_object_unref(G_OBJECT(hui->recentstore));
166 g_signal_connect(G_OBJECT(hui->recentview), "row-activated",
167 G_CALLBACK(row_activated_cb), hui);
169 renderer = gtk_cell_renderer_pixbuf_new();
170 column = gtk_tree_view_column_new_with_attributes(_("Security"), renderer,
171 "pixbuf", COL_SECURITY,
172 NULL);
173 gtk_tree_view_append_column(GTK_TREE_VIEW(hui->recentview), column);
175 renderer = gtk_cell_renderer_text_new();
176 column = gtk_tree_view_column_new_with_attributes(_("Date"), renderer,
177 "text", COL_DATE,
178 NULL);
179 gtk_tree_view_append_column(GTK_TREE_VIEW(hui->recentview), column);
181 renderer = gtk_cell_renderer_text_new();
182 column = gtk_tree_view_column_new_with_attributes(_("Subject"), renderer,
183 "text", COL_SUBJECT,
184 NULL);
185 gtk_tree_view_append_column(GTK_TREE_VIEW(hui->recentview), column);
187 return scroll_wrap(hui->recentview);
190 static void
191 hui_destroy_cb(GtkWidget *w, HistoryUI *hui) {
192 g_free(hui->lastdate);
195 void
196 make_dialog(HistoryUI *hui, GtkWindow *parent) {
197 GtkWidget *vbox, *bbox;
199 hui->win = gtk_dialog_new_with_buttons(_("History"),
200 parent, GTK_DIALOG_MODAL,
201 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
202 GTK_STOCK_OK, GTK_RESPONSE_OK,
203 NULL);
204 g_signal_connect(G_OBJECT(hui->win), "destroy",
205 G_CALLBACK(hui_destroy_cb), hui);
206 gtk_window_set_default_size(GTK_WINDOW(hui->win), 500, 400);
207 gtk_dialog_set_default_response(GTK_DIALOG(hui->win), GTK_RESPONSE_OK);
209 vbox = gtk_vbox_new(FALSE, 5);
210 gtk_box_pack_start(GTK_BOX(vbox), make_recentview(hui), TRUE, TRUE, 0);
211 hui->lstats = gtk_label_new("");
212 gtk_label_set_selectable(GTK_LABEL(hui->lstats), TRUE);
213 gtk_box_pack_start(GTK_BOX(vbox), hui->lstats, FALSE, FALSE, 0);
215 bbox = jam_dialog_buttonbox_new();
216 hui->bloadmore = jam_dialog_buttonbox_button_with_label(bbox,
217 _("_Load More..."));
218 g_signal_connect(G_OBJECT(hui->bloadmore), "clicked",
219 G_CALLBACK(load_more_cb), hui);
221 jam_dialog_set_contents_buttonbox(hui->win, vbox, bbox);
224 static LJEntry*
225 load_selected(HistoryUI *hui) {
226 GtkTreeModel *model;
227 GtkTreeIter iter;
228 int itemid;
230 if (!gtk_tree_selection_get_selected(
231 gtk_tree_view_get_selection(GTK_TREE_VIEW(hui->recentview)),
232 &model, &iter))
233 return NULL;
235 gtk_tree_model_get(model, &iter,
236 COL_ITEMID, &itemid,
237 -1);
239 return history_load_itemid(GTK_WINDOW(hui->win), hui->account, hui->usejournal, itemid);
242 LJEntry*
243 history_recent_dialog_run(GtkWindow *parent, JamAccount *acc, const char *usejournal) {
244 HistoryUI hui_actual = {0}, *hui = &hui_actual;
245 LJEntry *entry = NULL;
247 hui->account = acc;
248 hui->usejournal = usejournal;
249 hui->recentstore = gtk_list_store_new(COL_COUNT,
250 GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT);
252 make_dialog(hui, parent);
254 hui->pb_friends = gtk_widget_render_icon(hui->win,
255 "logjam-protected", GTK_ICON_SIZE_MENU, NULL);
256 hui->pb_private = gtk_widget_render_icon(hui->win,
257 "logjam-private", GTK_ICON_SIZE_MENU, NULL);
259 if (load_recent(hui, parent) <= 0)
260 return NULL;
262 while (gtk_dialog_run(GTK_DIALOG(hui->win)) == GTK_RESPONSE_OK) {
263 entry = load_selected(hui);
264 if (entry)
265 break;
268 gtk_widget_destroy(hui->win);
269 return entry;