cosmetix
[k8lowj.git] / src / usejournal.c
blobd75e5a66085c638e433860ff16250fb82e198bef
1 /* logjam - a GTK client for LiveJournal.
2 * Copyright (C) 2000-2004 Evan Martin <evan@livejournal.com>
3 */
4 #include "gtk-all.h"
6 #include <stdint.h>
7 #include <string.h>
9 #include "jamdoc.h"
10 #include "usejournal.h"
13 /* "having a shared prefix" is a pretty vague concept.
14 * we try a few heuristics. */
15 static int sharedprefix (const char *a, const char *b) {
16 const int minmatch = 4;
17 const char *ulpos;
18 int i = 0;
19 /* does this journal have an underscore? go from there. */
20 ulpos = strchr(b, '_');
21 if (ulpos) {
22 if (strncmp(a, b, ulpos - b) == 0) return (intptr_t)(ulpos-b);
24 /* or if the shared prefix is at least minmatch chars... */
25 while (*a++ == *b++) ++i;
26 return (i > minmatch ? i : 0);
30 static void activate_cb (GtkWidget *w, JamDoc *doc) {
31 const gchar *user;
32 JamAccount *acc = jam_doc_get_account(doc);
33 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(w))) return;
34 user = gtk_label_get_text(GTK_LABEL(GTK_BIN(w)->child));
35 if (g_ascii_strcasecmp(user, jam_account_get_username(acc)) == 0) user = NULL; /* post as normal user. */
36 jam_doc_set_usejournal(doc, user);
40 GtkWidget *usejournal_build_menu (const char *defaultjournal, const char *currentjournal, GSList *journals, gpointer doc) {
41 GtkWidget *menu, *curmenu, *item, *label;
42 GSList *group = NULL;
43 GSList *l;
44 char *journal;
45 char *curmenuprefix = NULL;
46 char prefix[30];
48 curmenu = menu = gtk_menu_new();
50 item = gtk_radio_menu_item_new_with_label(group, defaultjournal);
51 group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(item));
52 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(activate_cb), doc);
54 if (currentjournal == NULL) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE);
56 gtk_widget_show(item);
57 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
59 for (l = journals; l != NULL; l = l->next) {
60 journal = (char *)l->data;
61 if (curmenuprefix) {
62 /* try to match this item to the prefix. */
63 if (sharedprefix(curmenuprefix, journal)) {
64 /* match. */
65 } else {
66 curmenu = menu;
67 curmenuprefix = NULL;
70 if (!curmenuprefix && l->next) {
71 /* try to see if this begins a new prefix. */
72 char *nextjournal = (char *)l->next->data;
73 int ofs;
74 ofs = sharedprefix(journal, nextjournal);
75 if (ofs) {
76 /* make a new submenu for these shared-prefix journals. */
77 memcpy(prefix, journal, ofs);
78 prefix[ofs] = 0;
79 item = gtk_menu_item_new();
80 label = gtk_label_new(NULL);
81 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
82 gtk_label_set_markup(GTK_LABEL(label), prefix);
83 gtk_container_add(GTK_CONTAINER(item), label);
84 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
85 curmenu = gtk_menu_new();
86 curmenuprefix = prefix;
87 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), curmenu);
88 gtk_widget_show_all(item);
91 item = gtk_radio_menu_item_new_with_label(group, journal);
92 if (currentjournal && strcmp(currentjournal, journal) == 0) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE);
93 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(activate_cb), doc);
94 gtk_widget_show(item);
95 gtk_menu_shell_append(GTK_MENU_SHELL(curmenu), item);
96 group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(item));
99 return menu;