removed alot of warnings
[k8lowj.git] / src / manager.c
blob0e7a5811e31d8b7ebe10b6a53958962fa07ae519
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 "util-gtk.h"
10 #include "account.h"
12 #include "conf.h"
13 #include "tie.h"
14 #include "checkfriends.h"
15 #include "security.h"
16 #include "groupedbox.h"
17 #include "util.h"
19 /* manager:
20 * - host
21 * - account
22 * - (entries, outbox, etc?)
25 typedef struct _ManagerUI ManagerUI;
26 typedef struct _AccountUI AccountUI;
28 struct _ManagerUI {
29 GtkWidget *win;
31 GtkTreeStore *store;
32 GtkWidget *treeview;
34 GSList *pixbuf_names;
35 GSList *pixbufs;
37 GtkWidget *add;
38 GtkWidget *edit;
39 GtkWidget *del;
41 GtkWidget *filterlabel;
42 gpointer selection;
45 enum {
46 COL_ICON,
47 COL_TEXT,
48 COL_ISHOST,
49 COL_DATA,
50 COL_COUNT
53 static GdkPixbuf*
54 get_pixbuf(ManagerUI *mui, const char *stockid) {
55 int i;
56 GSList *l;
57 GdkPixbuf *pixbuf;
59 for (i = 0, l = mui->pixbuf_names; l; i++, l = l->next) {
60 if (strcmp(l->data, stockid) == 0)
61 return g_slist_nth(mui->pixbufs, i)->data;
64 pixbuf = gtk_widget_render_icon(mui->treeview, stockid,
65 GTK_ICON_SIZE_MENU, NULL);
66 mui->pixbuf_names = g_slist_append(mui->pixbuf_names, g_strdup(stockid));
67 mui->pixbufs = g_slist_append(mui->pixbufs, pixbuf);
68 return pixbuf;
71 static GtkWidget*
72 label_list(GSList *l, gboolean friendgroups /* FIXME: hack */) {
73 GtkWidget *label;
74 label = jam_form_label_new("");
75 if (l) {
76 GString *str = g_string_sized_new(1024);
78 while (l) {
79 if (str->len > 0)
80 g_string_append(str, ", ");
81 if (friendgroups) {
82 LJFriendGroup *fg = l->data;
83 g_string_append_printf(str, "<b>%s</b>", fg->name);
84 } else {
85 g_string_append_printf(str, "<b>%s</b>", (char*)l->data);
87 l = l->next;
89 gtk_label_set_markup(GTK_LABEL(label), str->str);
90 g_string_free(str, TRUE);
91 } else {
92 gtk_label_set_markup(GTK_LABEL(label), _("<i>none</i>"));
94 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
95 return label;
98 static void
99 run_cfmask_manager_dlg(GtkWidget *b, ManagerUI *mui) {
100 JamAccountLJ *acc = mui->selection;
101 guint newmask, oldmask;
103 oldmask = jam_account_lj_get_cfmask(acc);
104 newmask = custom_security_dlg_run(GTK_WINDOW(mui->win), oldmask, acc);
105 g_assert(mui->filterlabel);
106 if (newmask != oldmask) {
107 jam_account_lj_set_cfmask(acc, newmask);
108 /* XXX how do we notify the cfmgr of this new mask?
109 * cfmgr_set_mask(cfmgr_new(acc), newmask);*/
110 gtk_label_set_text(GTK_LABEL(mui->filterlabel),
111 newmask ? _("active") : _("inactive"));
115 static GtkWidget*
116 lj_user_make_ui_identity(ManagerUI *mui, LJUser *user) {
117 GtkSizeGroup *sg;
118 GtkWidget *vbox, *epassword;
120 sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
122 vbox = gtk_vbox_new(FALSE, 6);
123 gtk_container_set_border_width(GTK_CONTAINER(vbox), 12);
125 gtk_box_pack_start(GTK_BOX(vbox),
126 labelled_box_new_sg(_("_User Name:"),
127 jam_form_label_new(user->username), sg),
128 FALSE, FALSE, 0);
130 gtk_box_pack_start(GTK_BOX(vbox),
131 labelled_box_new_sg(_("_Full Name:"),
132 jam_form_label_new(user->fullname), sg),
133 FALSE, FALSE, 0);
135 epassword = gtk_entry_new();
136 gtk_entry_set_visibility(GTK_ENTRY(epassword), FALSE);
137 gtk_entry_set_text(GTK_ENTRY(epassword), user->password);
138 gtk_widget_set_usize(epassword, 100, -1);
139 gtk_box_pack_start(GTK_BOX(vbox),
140 labelled_box_new_sg(_("_Password:"), epassword, sg),
141 FALSE, FALSE, 0);
143 return vbox;
146 static void
147 account_add_ui_loginoptions(ManagerUI *mui, GtkBox *vbox, JamAccount *acc) {
148 GtkWidget *cruser, *crpassword;
149 gboolean ru, rp;
151 jam_account_get_remember(acc, &ru, &rp);
153 cruser = gtk_check_button_new_with_label(_("Remember user"));
154 tie_toggle(GTK_TOGGLE_BUTTON(cruser), &acc->remember_user);
155 gtk_box_pack_start(vbox, cruser, FALSE, FALSE, 0);
157 crpassword = gtk_check_button_new_with_label(_("Remember password"));
158 tie_toggle(GTK_TOGGLE_BUTTON(crpassword), &acc->remember_password);
159 gtk_box_pack_start(vbox, crpassword, FALSE, FALSE, 0);
162 static GtkWidget*
163 user_make_ui_pictures(ManagerUI *mui, LJUser *user) {
164 GtkWidget *box;
165 box = groupedbox_new();
166 gtk_container_set_border_width(GTK_CONTAINER(box), 12);
167 groupedbox_set_header(GROUPEDBOX(box), _("User picture keywords:"), FALSE);
168 groupedbox_pack(GROUPEDBOX(box), label_list(user->pickws, FALSE), FALSE);
169 return box;
172 static GtkWidget*
173 account_lj_make_ui_friends(ManagerUI *mui, JamAccountLJ *acc) {
174 GtkWidget *vbox, *box, *hbcff, *licff, *bcff;
175 LJUser *user = jam_account_lj_get_user(acc);
177 vbox = gtk_vbox_new(FALSE, 6);
178 gtk_container_set_border_width(GTK_CONTAINER(vbox), 12);
180 /* per-user checkfriends on/off */
181 gtk_box_pack_start(GTK_BOX(vbox),
182 tie_toggle(GTK_TOGGLE_BUTTON(gtk_check_button_new_with_mnemonic(
183 _("_Monitor this user's friends list for updates"))),
184 &user->checkfriends),
185 FALSE, FALSE, 0);
187 gtk_box_pack_start(GTK_BOX(vbox),
188 label_list(user->friendgroups, TRUE),
189 FALSE, FALSE, 0);
191 box = groupedbox_new();
192 groupedbox_set_header(GROUPEDBOX(box),
193 _("Filter for friends list monitor:"), FALSE);
195 hbcff = gtk_hbox_new(FALSE, 5);
197 licff = gtk_label_new(acc->cfmask ? _("active") : _("inactive"));
198 gtk_misc_set_alignment(GTK_MISC(licff), 0.0, 0.5);
199 gtk_box_pack_start(GTK_BOX(hbcff), licff, TRUE, TRUE, 0);
200 mui->filterlabel = licff; /* not the prettiest of hacks */
202 bcff = gtk_button_new_with_mnemonic(_("_Edit filter"));
203 /* guard against a user with no friendgroup info */
204 gtk_widget_set_sensitive(bcff, user->friendgroups != NULL);
205 gtk_box_pack_start(GTK_BOX(hbcff), bcff, FALSE, FALSE, 0);
207 groupedbox_pack(GROUPEDBOX(box), hbcff, FALSE);
209 gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0);
211 g_signal_connect(G_OBJECT(bcff), "clicked",
212 G_CALLBACK(run_cfmask_manager_dlg), mui);
214 return vbox;
217 static GtkWidget*
218 account_lj_make_ui(ManagerUI *mui, JamAccount *acc) {
219 LJUser *user;
220 GtkWidget *nb, *box;
222 nb = gtk_notebook_new();
224 user = jam_account_lj_get_user(JAM_ACCOUNT_LJ(acc));
226 box = lj_user_make_ui_identity(mui, user),
227 account_add_ui_loginoptions(mui, GTK_BOX(box), acc);
228 gtk_notebook_append_page(GTK_NOTEBOOK(nb),
229 box,
230 gtk_label_new(_("Identity")));
231 gtk_notebook_append_page(GTK_NOTEBOOK(nb),
232 user_make_ui_pictures(mui, user),
233 gtk_label_new(_("Pictures")));
234 gtk_notebook_append_page(GTK_NOTEBOOK(nb),
235 account_lj_make_ui_friends(mui, JAM_ACCOUNT_LJ(acc)),
236 gtk_label_new(_("Friends")));
237 return nb;
240 #ifdef blogger_punted_for_this_release
241 static GtkWidget*
242 account_blogger_make_ui(ManagerUI *mui, JamAccount *acc) {
243 GtkSizeGroup *sg;
244 GtkWidget *vbox, *epassword;
246 sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
248 vbox = gtk_vbox_new(FALSE, 6);
250 gtk_box_pack_start(GTK_BOX(vbox),
251 labelled_box_new_sg(_("_User Name:"),
252 jam_form_label_new(jam_account_get_username(acc)), sg),
253 FALSE, FALSE, 0);
255 epassword = gtk_entry_new();
256 gtk_entry_set_visibility(GTK_ENTRY(epassword), FALSE);
257 gtk_widget_set_usize(epassword, 100, -1);
258 gtk_entry_set_text(GTK_ENTRY(epassword), jam_account_get_password(acc));
259 gtk_box_pack_start(GTK_BOX(vbox),
260 labelled_box_new_sg(_("_Password:"), epassword, sg),
261 FALSE, FALSE, 0);
263 account_add_ui_loginoptions(mui, GTK_BOX(vbox), acc);
265 return vbox;
267 #endif /* blogger_punted_for_this_release */
269 static GtkWidget*
270 account_make_ui(ManagerUI *mui, JamAccount *acc) {
271 if (JAM_ACCOUNT_IS_LJ(acc)) {
272 return account_lj_make_ui(mui, acc);
273 #ifdef blogger_punted_for_this_release
274 } else if (JAM_ACCOUNT_IS_BLOGGER(acc)) {
275 return account_blogger_make_ui(mui, acc);
276 #endif /* blogger_punted_for_this_release */
277 } else {
278 g_error("unknown account type!");
280 return NULL;
283 typedef struct {
284 GtkTreeIter iter;
285 gpointer searchdata;
286 gboolean found;
287 } SearchData;
289 static gboolean
290 search_model_cb(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter,
291 gpointer data) {
292 SearchData *sd = data;
293 gpointer datacol;
294 gtk_tree_model_get(model, iter, COL_DATA, &datacol, -1);
295 if (datacol == sd->searchdata) {
296 sd->found = TRUE;
297 sd->iter = *iter;
298 return TRUE;
300 return FALSE;
303 static GtkTreeIter
304 search_model(ManagerUI *mui, gpointer data) {
305 SearchData sd;
306 sd.found = FALSE;
307 sd.searchdata = data;
308 gtk_tree_model_foreach(GTK_TREE_MODEL(mui->store),
309 search_model_cb, &sd);
310 return sd.iter;
313 static void
314 account_edit(ManagerUI *mui, GtkTreeIter *iter, JamAccount *acc) {
315 GtkWidget *dlg;
316 char *oldname;
317 const char *newname;
319 oldname = g_strdup(jam_account_get_username(acc));
321 dlg = gtk_dialog_new_with_buttons(_("User Properties"),
322 GTK_WINDOW(mui->win), GTK_DIALOG_DESTROY_WITH_PARENT,
323 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
324 NULL);
325 //gtk_window_set_default_size(GTK_WINDOW(dlg), 300, 200);
327 jam_dialog_set_contents(GTK_DIALOG(dlg), account_make_ui(mui, acc));
329 gtk_dialog_run(GTK_DIALOG(dlg));
331 gtk_widget_destroy(dlg);
333 newname = jam_account_get_username(acc);
334 if (strcmp(oldname, newname) != 0) {
335 gtk_tree_store_set(mui->store, iter,
336 COL_TEXT, newname,
337 -1);
339 g_free(oldname);
342 static void
343 account_del(ManagerUI *mui, GtkTreeIter *iter, JamAccount *acc) {
344 /*GtkTreeIter it;
345 LJUser *user = jam_account_get_user(acc);
346 it = search_model(mui, user);*/
347 g_warning("unimplemented\n");
351 static void
352 add_entry_cache(ManagerUI *mui, GtkTreeStore *ts, GtkTreeIter *parent, JamAccount *user) {
353 GtkTreeIter ientries;
355 gtk_tree_store_append(ts, &ientries, parent);
356 gtk_tree_store_set(ts, &ientries,
357 COL_TEXT, _("Entries"),
358 -1);
362 static void
363 add_account(ManagerUI *mui, GtkTreeIter *parent, JamAccount *account) {
364 GtkTreeIter iaccount;
366 gtk_tree_store_append(mui->store, &iaccount, parent);
367 gtk_tree_store_set(mui->store, &iaccount,
368 COL_ICON, NULL,
369 COL_TEXT, jam_account_get_username(account),
370 COL_ISHOST, FALSE,
371 COL_DATA, account,
372 -1);
375 add_entry_cache(mui, ts, &iuser, user);
377 gtk_tree_store_append(ts, &idrafts, &iuser);
378 gtk_tree_store_set(ts, &idrafts,
379 COL_TEXT, _("Drafts"),
380 -1);
382 gtk_tree_store_append(ts, &ioutbox, &iuser);
383 gtk_tree_store_set(ts, &ioutbox,
384 COL_TEXT, _("Outbox"),
385 -1);
389 static gboolean
390 entry_tie_cb(GtkEntry *entry, GdkEventFocus *e, char **data) {
391 string_replace(data, gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1));
392 return FALSE;
394 static void
395 entry_tie(GtkEntry *entry, char **data) {
396 if (*data)
397 gtk_entry_set_text(GTK_ENTRY(entry), *data);
398 g_signal_connect(G_OBJECT(entry), "focus-out-event",
399 G_CALLBACK(entry_tie_cb), data);
402 #ifdef blogger_punted_for_this_release
403 static gboolean
404 blogger_rpc_edit_cb(GtkEntry *entry, GdkEventFocus *e, JamHostBlogger *hostb) {
405 const char *url = gtk_entry_get_text(entry);
406 jam_host_blogger_set_rpcurl(hostb, url);
407 return FALSE;
409 #endif /* blogger_punted_for_this_release */
411 static gboolean
412 host_rename_cb(GtkEntry *entry, GdkEventFocus *e, JamHost *host) {
413 const char *newname;
414 GError *err = NULL;
416 newname = gtk_entry_get_text(entry);
417 if (strcmp(host->name, newname) == 0)
418 return FALSE;
419 if (!conf_rename_host(host, newname, &err)) {
420 jam_warning(GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(entry))),
421 _("Unable to rename server: %s."), err->message);
422 g_error_free(err);
423 gtk_entry_set_text(entry, host->name);
424 return FALSE;
426 return FALSE;
429 static GtkWidget*
430 host_make_ui(ManagerUI *mui, JamHost *host) {
431 GtkWidget *vbox, *name;
432 GtkSizeGroup *sg;
434 sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
436 vbox = gtk_vbox_new(FALSE, 6);
438 name = gtk_entry_new();
439 gtk_entry_set_text(GTK_ENTRY(name), host->name);
440 g_signal_connect_after(G_OBJECT(name), "focus-out-event",
441 G_CALLBACK(host_rename_cb), host);
442 gtk_widget_set_usize(name, 200, -1);
443 gtk_box_pack_start(GTK_BOX(vbox),
444 labelled_box_new_sg(_("_Name:"), name, sg),
445 FALSE, FALSE, 0);
447 if (JAM_HOST_IS_LJ(host)) {
448 JamHostLJ *hostlj = JAM_HOST_LJ(host);
449 LJServer *server = jam_host_lj_get_server(hostlj);
450 GtkWidget *eurl, *cprotocol;
452 eurl = gtk_entry_new();
453 entry_tie(GTK_ENTRY(eurl), &server->url);
454 gtk_widget_set_usize(eurl, 200, -1);
455 gtk_box_pack_start(GTK_BOX(vbox),
456 labelled_box_new_sg(_("_URL:"), eurl, sg),
457 FALSE, FALSE, 0);
459 cprotocol = gtk_check_button_new_with_mnemonic(
460 _("_Server supports protocol version 1"));
461 tie_toggle(GTK_TOGGLE_BUTTON(cprotocol), &server->protocolversion);
462 gtk_box_pack_start(GTK_BOX(vbox), cprotocol, FALSE, FALSE, 0);
463 #ifdef blogger_punted_for_this_release
464 } else if (JAM_HOST_IS_BLOGGER(host)) {
465 JamHostBlogger *hostb = JAM_HOST_BLOGGER(host);
466 GtkWidget *eurl;
467 char *url;
469 eurl = gtk_entry_new();
470 url = jam_host_blogger_get_rpcurl(hostb);
471 if (url)
472 gtk_entry_set_text(GTK_ENTRY(eurl), url);
473 g_signal_connect(G_OBJECT(eurl), "focus-out-event",
474 G_CALLBACK(blogger_rpc_edit_cb), hostb);
476 gtk_widget_set_usize(eurl, 200, -1);
477 gtk_box_pack_start(GTK_BOX(vbox),
478 labelled_box_new_sg(_("_RPC URL:"), eurl, sg),
479 FALSE, FALSE, 0);
480 #endif /* blogger_punted_for_this_release */
481 } else {
482 g_error("unknown host type!");
485 return vbox;
488 static void add_host(ManagerUI *mui, JamHost *host);
490 static void
491 host_edit(ManagerUI *mui, GtkTreeIter *iter, JamHost *host) {
492 GtkWidget *dlg;
493 char *oldname;
495 oldname = g_strdup(host->name);
497 dlg = gtk_dialog_new_with_buttons(_("Server Properties"),
498 GTK_WINDOW(mui->win), GTK_DIALOG_DESTROY_WITH_PARENT,
499 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
500 NULL);
501 //gtk_window_set_default_size(GTK_WINDOW(dlg), 300, 200);
503 jam_dialog_set_contents(GTK_DIALOG(dlg), host_make_ui(mui, host));
505 gtk_dialog_run(GTK_DIALOG(dlg));
507 gtk_widget_destroy(dlg);
509 if (strcmp(host->name, oldname) != 0) {
510 gtk_tree_store_set(mui->store, iter,
511 COL_TEXT, host->name,
512 -1);
514 g_free(oldname);
517 static void
518 host_del(ManagerUI *mui, GtkTreeIter *iter, JamHost *host) {
519 GtkTreeIter it;
521 it = search_model(mui, host);
522 gtk_tree_store_remove(mui->store, &it);
524 conf.hosts = g_slist_remove(conf.hosts, host);
525 // XXX evan g_free(server);
528 static void
529 add_host(ManagerUI *mui, JamHost *host) {
530 GtkTreeIter ihost;
531 GSList *l;
533 gtk_tree_store_append(mui->store, &ihost, NULL);
534 gtk_tree_store_set(mui->store, &ihost,
535 COL_ICON, get_pixbuf(mui, jam_host_get_stock_icon(host)),
536 COL_TEXT, host->name,
537 COL_ISHOST, TRUE,
538 COL_DATA, host,
539 -1);
541 for (l = host->accounts; l; l = l->next) {
542 add_account(mui, &ihost, l->data);
546 static void
547 populate_store(ManagerUI *mui) {
548 GSList *l;
550 gtk_tree_store_clear(mui->store);
551 for (l = conf.hosts; l; l = l->next) {
552 if (l->data)
553 add_host(mui, l->data);
557 static GtkTreeStore*
558 make_model(ManagerUI *mui) {
559 mui->store = gtk_tree_store_new(COL_COUNT,
560 /* icon */ GDK_TYPE_PIXBUF,
561 /* name */ G_TYPE_STRING,
562 /* ishost */ G_TYPE_BOOLEAN,
563 /* data */ G_TYPE_POINTER);
565 populate_store(mui);
567 return mui->store;
570 static void
571 selection_changed_cb(GtkTreeSelection *ts, ManagerUI *mui) {
572 GtkTreeModel *model;
573 GtkTreeIter iter;
575 if (!gtk_tree_selection_get_selected(ts, &model, &iter)) {
576 gtk_widget_set_sensitive(mui->edit, FALSE);
577 gtk_widget_set_sensitive(mui->del, FALSE);
578 } else {
579 /* XXX gboolean ishost;
580 gtk_tree_model_get(model, &iter, COL_ISHOST, &ishost, -1);*/
581 gtk_widget_set_sensitive(mui->edit, TRUE);
582 gtk_widget_set_sensitive(mui->del, TRUE);
586 static void
587 add_lj_cb(GtkWidget *i, ManagerUI *mui) {
588 JamHost *h;
589 LJServer *s;
590 s = lj_server_new("http://hostname:port");
591 h = JAM_HOST(jam_host_lj_new(s));
592 h->name = g_strdup("New LiveJournal Server");
593 conf.hosts = g_slist_append(conf.hosts, h);
594 gtk_tree_selection_unselect_all(
595 gtk_tree_view_get_selection(GTK_TREE_VIEW(mui->treeview)));
596 add_host(mui, h);
598 #ifdef blogger_punted_for_this_release
599 static void
600 add_blogger_cb(GtkWidget *i, ManagerUI *mui) {
601 JamHost *h;
602 h = JAM_HOST(jam_host_blogger_new());
603 h->name = g_strdup("New Blogger Server");
604 conf.hosts = g_slist_append(conf.hosts, h);
605 gtk_tree_selection_unselect_all(
606 gtk_tree_view_get_selection(GTK_TREE_VIEW(mui->treeview)));
607 add_host(mui, h);
610 static gboolean
611 add_cb(GtkWidget *b, GdkEventButton *eb, ManagerUI *mui) {
612 GtkWidget *menu, *item;
614 menu = gtk_menu_new();
615 item = gtk_menu_item_new_with_mnemonic("_LiveJournal Server...");
616 g_signal_connect(G_OBJECT(item), "activate",
617 G_CALLBACK(add_lj_cb), mui);
618 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
620 item = gtk_menu_item_new_with_mnemonic("_Blogger Server...");
621 g_signal_connect(G_OBJECT(item), "activate",
622 G_CALLBACK(add_blogger_cb), mui);
623 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
624 gtk_widget_show_all(menu);
626 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, eb->button, eb->time);
628 return TRUE;
630 #endif /* blogger_punted_for_this_release */
632 static void
633 edit_cb(GtkWidget *b, ManagerUI *mui) {
634 GtkTreeSelection *ts;
635 GtkTreeModel *model;
636 GtkTreeIter iter;
637 gboolean ishost;
638 gpointer data;
640 ts = gtk_tree_view_get_selection(GTK_TREE_VIEW(mui->treeview));
641 if (!gtk_tree_selection_get_selected(ts, &model, &iter))
642 return;
643 gtk_tree_model_get(model, &iter, COL_ISHOST, &ishost, COL_DATA, &data, -1);
644 mui->selection = data;
645 if (ishost) {
646 host_edit(mui, &iter, JAM_HOST(data));
647 } else {
648 account_edit(mui, &iter, JAM_ACCOUNT(data));
652 static void
653 del_cb(GtkWidget *b, ManagerUI *mui) {
654 GtkTreeSelection *ts;
655 GtkTreeModel *model;
656 GtkTreeIter iter;
657 gboolean ishost;
658 gpointer data;
660 ts = gtk_tree_view_get_selection(GTK_TREE_VIEW(mui->treeview));
661 if (!gtk_tree_selection_get_selected(ts, &model, &iter))
662 return;
663 gtk_tree_model_get(model, &iter, COL_ISHOST, &ishost, COL_DATA, &data, -1);
665 /* XXX evan this logic is weird; we don't want to delete the "current"
666 * stuff, but there is no real "current" anymore. maybe we should
667 * just unref it?
668 if (mui->selection == c_cur_server()
669 || mui->selection == c_cur_user()) {
670 return;
673 if (ishost) {
674 host_del(mui, &iter, JAM_HOST(data));
675 } else {
676 account_del(mui, &iter, JAM_ACCOUNT(data));
680 static GtkWidget*
681 make_tree(ManagerUI *mui) {
682 GtkCellRenderer *renderer;
683 GtkTreeViewColumn *column;
684 GtkTreeSelection *sel;
685 GtkWidget *sw;
687 mui->treeview = gtk_tree_view_new();
688 gtk_tree_view_set_model(GTK_TREE_VIEW(mui->treeview),
689 GTK_TREE_MODEL(make_model(mui)));
690 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(mui->treeview));
691 g_signal_connect(G_OBJECT(sel), "changed",
692 G_CALLBACK(selection_changed_cb), mui);
693 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(mui->treeview), FALSE);
695 column = gtk_tree_view_column_new();
696 gtk_tree_view_column_set_title(column, "Node");
698 renderer = gtk_cell_renderer_pixbuf_new();
699 gtk_tree_view_column_pack_start(column, renderer, FALSE);
700 gtk_tree_view_column_add_attribute(column, renderer,
701 "pixbuf", COL_ICON);
703 renderer = gtk_cell_renderer_text_new();
704 gtk_tree_view_column_pack_start(column, renderer, FALSE);
705 gtk_tree_view_column_add_attribute(column, renderer,
706 "text", COL_TEXT);
708 gtk_tree_view_append_column(GTK_TREE_VIEW(mui->treeview), column);
710 sw = scroll_wrap(mui->treeview);
711 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
712 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
713 return sw;
716 void
717 manager_dialog(GtkWindow *parent) {
718 STACK(ManagerUI, mui);
719 GtkWidget *mainbox, *bbox;
721 mui->win = gtk_dialog_new_with_buttons(_("Servers"),
722 parent, GTK_DIALOG_DESTROY_WITH_PARENT,
723 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
724 NULL);
725 gtk_window_set_default_size(GTK_WINDOW(mui->win), 300, 200);
726 geometry_tie(mui->win, GEOM_MANAGER);
728 mainbox = gtk_hbox_new(FALSE, 6);
730 gtk_box_pack_start(GTK_BOX(mainbox), make_tree(mui), TRUE, TRUE, 0);
732 bbox = gtk_vbox_new(FALSE, 6);
733 mui->add = gtk_button_new_from_stock(GTK_STOCK_ADD);
734 g_signal_connect(G_OBJECT(mui->add), "clicked",
735 G_CALLBACK(add_lj_cb), mui);
736 #ifdef blogger_punted_for_this_release
737 g_signal_connect(G_OBJECT(mui->add), "button-press-event",
738 G_CALLBACK(add_cb), mui);
739 #endif /* blogger_punted_for_this_release */
740 gtk_box_pack_start(GTK_BOX(bbox), mui->add, FALSE, FALSE, 0);
741 mui->edit = gtk_button_new_from_stock(GTK_STOCK_PROPERTIES);
742 g_signal_connect(G_OBJECT(mui->edit), "clicked",
743 G_CALLBACK(edit_cb), mui);
744 gtk_box_pack_start(GTK_BOX(bbox), mui->edit, FALSE, FALSE, 0);
745 mui->del = gtk_button_new_from_stock(GTK_STOCK_REMOVE);
746 g_signal_connect(G_OBJECT(mui->del), "clicked",
747 G_CALLBACK(del_cb), mui);
748 gtk_box_pack_start(GTK_BOX(bbox), mui->del, FALSE, FALSE, 0);
750 gtk_box_pack_start(GTK_BOX(mainbox), bbox, FALSE, FALSE, 0);
752 jam_dialog_set_contents(GTK_DIALOG(mui->win), mainbox);
754 gtk_dialog_run(GTK_DIALOG(mui->win));
756 conf_verify_a_host_exists();
758 gtk_widget_destroy(mui->win);
759 g_slist_foreach(mui->pixbuf_names, (GFunc)g_free, NULL);
760 g_slist_free(mui->pixbuf_names);
761 g_slist_foreach(mui->pixbufs, (GFunc)g_object_unref, NULL);
762 g_slist_free(mui->pixbufs);