progress.*: cosmetix
[k8lowj.git] / src / history_recent.c
blobe68200994f0e8e293cd10aac43a11542f88c1f54
1 /* logjam - a GTK client for LiveJournal.
2 * Copyright (C) 2000-2003 Evan Martin <evan@livejournal.com>
3 */
5 #include "gtk-all.h"
6 #include "util-gtk.h"
8 #include <stdlib.h>
10 #include "liblj/getevents.h"
12 #include "history.h"
13 #include "network.h"
14 #include "util.h"
17 /* how many entries to load each time "load more..." is clicked. */
18 #define HISTORY_LOAD_BATCH (20)
21 typedef struct {
22 GtkWidget *win;
23 GtkListStore *recentstore;
24 GtkWidget *recentview;
25 GtkWidget *lstats;
26 GtkWidget *bloadmore;
27 char *lastdate;
29 JamAccount *account;
30 const char *usejournal;
31 GdkPixbuf *pb_friends, *pb_private;
32 } HistoryUI;
35 enum {
36 COL_SECURITY,
37 COL_DATE,
38 COL_SUBJECT,
39 COL_ITEMID,
40 COL_COUNT
44 static void recalculate_stats (HistoryUI *hui) {
45 GtkTreeModel *model;
46 GtkTreeIter iter;
47 GdkPixbuf *pb;
48 char *stats;
49 int ecount = 0, pecount = 0, fecount = 0;
51 model = gtk_tree_view_get_model(GTK_TREE_VIEW(hui->recentview));
52 if (!gtk_tree_model_get_iter_first(model, &iter)) {
53 /* no history. */
54 gtk_label_set_text(GTK_LABEL(hui->lstats), "");
55 return;
58 do {
59 gtk_tree_model_get(model, &iter, COL_SECURITY, &pb, -1);
60 ++ecount;
61 /* FIXME: gross hack. */
62 if (pb == hui->pb_friends) ++fecount;
63 else if (pb == hui->pb_private) ++pecount;
64 } while (gtk_tree_model_iter_next(model, &iter));
65 stats = g_strdup_printf(_("%d entries displayed. " "%.1f%% public / %.1f%% friends-only / %.1f%% private."),
66 ecount,
67 100.0f*(ecount-pecount-fecount)/(float)ecount,
68 100.0f*fecount/(float)ecount, 100.0f *pecount/(float)ecount);
69 gtk_label_set_text(GTK_LABEL(hui->lstats), stats);
70 g_free(stats);
74 static int load_recent (HistoryUI *hui, GtkWindow *parent) {
75 LJGetEventsRecent *getevents;
76 int i, count;
77 GtkTreeIter iter;
78 GdkPixbuf *pb;
79 NetContext *ctx;
81 if (!JAM_ACCOUNT_IS_LJ(hui->account)) {
82 g_warning("XXX blogger: history for blogger\n");
83 return -1;
86 getevents = lj_getevents_recent_new(jam_account_lj_get_user(JAM_ACCOUNT_LJ(hui->account)), hui->usejournal, HISTORY_LOAD_BATCH, hui->lastdate, TRUE, 100);
87 ctx = net_ctx_gtk_new(parent, _("Loading History"));
88 if (!net_run_verb_ctx((LJVerb *)getevents, ctx, NULL)) {
89 lj_getevents_recent_free(getevents, TRUE);
90 net_ctx_gtk_free(ctx);
91 return -1;
94 count = getevents->entry_count;
95 for (i = 0; i < count; ++i) {
96 LJEntry *entry = getevents->entries[i];
97 char *date = lj_tm_to_ljdate(&entry->time);
98 switch (entry->security.type) {
99 case LJ_SECURITY_FRIENDS:
100 case LJ_SECURITY_CUSTOM:
101 pb = hui->pb_friends;
102 break;
103 case LJ_SECURITY_PRIVATE:
104 pb = hui->pb_private;
105 break;
106 default:
107 pb = NULL; /* public: no icon */
109 gtk_list_store_append(hui->recentstore, &iter);
110 gtk_list_store_set(hui->recentstore, &iter, COL_SECURITY, pb, COL_DATE, date,
111 /* because we set summary=TRUE above, the real subject is returned in event. */
112 COL_SUBJECT, entry->event, COL_ITEMID, entry->itemid, -1);
113 g_free(date);
116 if (count < HISTORY_LOAD_BATCH) {
117 /* we've reached the beginning of history. */
118 gtk_widget_set_sensitive(hui->bloadmore, FALSE);
119 } else if (count > 0) {
120 string_replace(&hui->lastdate, lj_tm_to_ljdate(&getevents->entries[count-1]->time));
123 recalculate_stats(hui);
125 lj_getevents_recent_free(getevents, TRUE);
126 net_ctx_gtk_free(ctx);
128 return count;
132 static void load_more_cb (GtkWidget *w, HistoryUI *hui) {
133 load_recent(hui, GTK_WINDOW(hui->win));
137 static void row_activated_cb (GtkTreeView *treeview, GtkTreePath *arg1, GtkTreeViewColumn *arg2, HistoryUI *hui) {
138 gtk_dialog_response(GTK_DIALOG(hui->win), GTK_RESPONSE_OK);
142 static GtkWidget *make_recentview (HistoryUI *hui) {
143 GtkCellRenderer *renderer;
144 GtkTreeViewColumn *column;
146 hui->recentview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(hui->recentstore));
147 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(hui->recentview), TRUE);
148 g_object_unref(G_OBJECT(hui->recentstore));
149 g_signal_connect(G_OBJECT(hui->recentview), "row-activated", G_CALLBACK(row_activated_cb), hui);
151 renderer = gtk_cell_renderer_pixbuf_new();
152 column = gtk_tree_view_column_new_with_attributes(_("Security"), renderer, "pixbuf", COL_SECURITY, NULL);
153 gtk_tree_view_append_column(GTK_TREE_VIEW(hui->recentview), column);
155 renderer = gtk_cell_renderer_text_new();
156 column = gtk_tree_view_column_new_with_attributes(_("Date"), renderer, "text", COL_DATE, NULL);
157 gtk_tree_view_append_column(GTK_TREE_VIEW(hui->recentview), column);
159 renderer = gtk_cell_renderer_text_new();
160 column = gtk_tree_view_column_new_with_attributes(_("Subject"), renderer, "text", COL_SUBJECT, NULL);
161 gtk_tree_view_append_column(GTK_TREE_VIEW(hui->recentview), column);
163 return scroll_wrap(hui->recentview);
167 static void hui_destroy_cb (GtkWidget *w, HistoryUI *hui) {
168 g_free(hui->lastdate);
172 void make_dialog (HistoryUI *hui, GtkWindow *parent) {
173 GtkWidget *vbox, *bbox;
175 hui->win = gtk_dialog_new_with_buttons(_("History"),
176 parent, GTK_DIALOG_MODAL,
177 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
178 g_signal_connect(G_OBJECT(hui->win), "destroy", G_CALLBACK(hui_destroy_cb), hui);
179 gtk_window_set_default_size(GTK_WINDOW(hui->win), 500, 400);
180 gtk_dialog_set_default_response(GTK_DIALOG(hui->win), GTK_RESPONSE_OK);
182 vbox = gtk_vbox_new(FALSE, 5);
183 gtk_box_pack_start(GTK_BOX(vbox), make_recentview(hui), TRUE, TRUE, 0);
184 hui->lstats = gtk_label_new("");
185 gtk_label_set_selectable(GTK_LABEL(hui->lstats), TRUE);
186 gtk_box_pack_start(GTK_BOX(vbox), hui->lstats, FALSE, FALSE, 0);
188 bbox = jam_dialog_buttonbox_new();
189 hui->bloadmore = jam_dialog_buttonbox_button_with_label(bbox, _("_Load More..."));
190 g_signal_connect(G_OBJECT(hui->bloadmore), "clicked", G_CALLBACK(load_more_cb), hui);
192 jam_dialog_set_contents_buttonbox(hui->win, vbox, bbox);
196 static LJEntry *load_selected (HistoryUI *hui) {
197 GtkTreeModel *model;
198 GtkTreeIter iter;
199 int itemid;
200 if (!gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(hui->recentview)), &model, &iter)) return NULL;
201 gtk_tree_model_get(model, &iter, COL_ITEMID, &itemid, -1);
202 return history_load_itemid(GTK_WINDOW(hui->win), hui->account, hui->usejournal, itemid);
206 LJEntry *history_recent_dialog_run (GtkWindow *parent, JamAccount *acc, const char *usejournal) {
207 HistoryUI hui_actual = { 0 }, *hui = &hui_actual;
208 LJEntry *entry = NULL;
210 hui->account = acc;
211 hui->usejournal = usejournal;
212 hui->recentstore = gtk_list_store_new(COL_COUNT, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT);
214 make_dialog(hui, parent);
216 hui->pb_friends = gtk_widget_render_icon(hui->win, "logjam-protected", GTK_ICON_SIZE_MENU, NULL);
217 hui->pb_private = gtk_widget_render_icon(hui->win, "logjam-private", GTK_ICON_SIZE_MENU, NULL);
219 if (load_recent(hui, parent) <= 0) return NULL;
221 while (gtk_dialog_run(GTK_DIALOG(hui->win)) == GTK_RESPONSE_OK) {
222 entry = load_selected(hui);
223 if (entry) break;
226 gtk_widget_destroy(hui->win);
227 return entry;