1 /* logjam - a GTK client for LiveJournal.
2 * Copyright (C) 2000-2003 Evan Martin <evan@livejournal.com>
10 #include "liblj/getevents.h"
17 /* how many entries to load each time "load more..." is clicked. */
18 #define HISTORY_LOAD_BATCH (20)
23 GtkListStore
*recentstore
;
24 GtkWidget
*recentview
;
30 const char *usejournal
;
31 GdkPixbuf
*pb_friends
, *pb_private
;
44 static void recalculate_stats (HistoryUI
*hui
) {
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
)) {
54 gtk_label_set_text(GTK_LABEL(hui
->lstats
), "");
59 gtk_tree_model_get(model
, &iter
, COL_SECURITY
, &pb
, -1);
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."),
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
);
74 static int load_recent (HistoryUI
*hui
, GtkWindow
*parent
) {
75 LJGetEventsRecent
*getevents
;
81 if (!JAM_ACCOUNT_IS_LJ(hui
->account
)) {
82 g_warning("XXX blogger: history for blogger\n");
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
);
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
;
103 case LJ_SECURITY_PRIVATE
:
104 pb
= hui
->pb_private
;
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);
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
);
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
) {
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
;
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
);
226 gtk_widget_destroy(hui
->win
);