Mercurial > pidgin
changeset 3392:5a5df7968b6e
[gaim-migrate @ 3411]
Another notify.c fix from deryni.
committer: Tailor Script <tailor@pidgin.im>
author | Sean Egan <seanegan@gmail.com> |
---|---|
date | Sun, 11 Aug 2002 06:43:23 +0000 |
parents | 412d1035d666 |
children | 2a34734f6a0d |
files | plugins/notify.c |
diffstat | 1 files changed, 182 insertions(+), 55 deletions(-) [+] |
line wrap: on
line diff
--- a/plugins/notify.c Sun Aug 11 06:42:17 2002 +0000 +++ b/plugins/notify.c Sun Aug 11 06:43:23 2002 +0000 @@ -1,8 +1,15 @@ -/* Reworked by Etan Reisner +/* Rewritten by Etan Reisner <deryni@eden.rutgers.edu> * * Added config dialog * Added control over notification method * Added control over when to release notification + * + * Thanks to Carles Pina i Estany <carles@pinux.info> + * for count of new messages option + */ + +/* if my flash messages patch gets merged in can use cnv->local + * to notify on new messages also */ #define GAIM_PLUGINS @@ -12,29 +19,37 @@ #include <string.h> #include <X11/Xlib.h> #include <X11/Xutil.h> -#include <X11/Xatom.h> +#include <X11/Xatom.h> #include <gdk/gdkx.h> -guint choice; -#define REMOVE_FOCUS 0x00000001 -#define REMOVE_TYPE 0x00000002 +guint choice = 1; +#define NOTIFY_FOCUS 0x00000001 +#define NOTIFY_TYPE 0x00000002 +#define NOTIFY_IN_FOCUS 0x00000004 -guint method; -#define METHOD_STRING 0x00000001 -#define METHOD_QUOTE 0x00000002 -#define METHOD_URGENT 0x00000004 +guint method = 1; +#define METHOD_STRING 0x00000001 +#define METHOD_QUOTE 0x00000002 +#define METHOD_URGENT 0x00000004 +#define METHOD_COUNT 0x00000008 void *handle; +/* I really don't like this but I was having trouble getting any + * other way of removing the signal callbacks to work and not crash gaim + */ +GtkWidget *really_evil_hack; +/* GHashTable *hash = NULL; */ GtkWidget *Dialog = NULL; -GtkWidget *Click, *Focus, *Type; -GtkWidget *String, *Quote, *Urgent, *Entry; -gchar *title_string; +GtkWidget *Click, *Focus, *Type, *InFocus; +GtkWidget *String, *Count, *Quote, *Urgent, *Entry; +gchar *title_string = "(*) "; /* predefine some functions, less warnings */ void options(GtkWidget *widget, gpointer data); void un_star(GtkWidget *widget, gpointer data); void un_star_window(GtkWidget *widget, gpointer data); void string_remove(GtkWidget *widget); +void count_remove(GtkWidget *widget); void quote_remove(GtkWidget *widget); void urgent_remove(struct conversation *c); @@ -45,6 +60,7 @@ char *me = g_strdup(normalize(gc->username)); int revert_to_return; Window focus_return; + int c, length; if (!strcmp(me, normalize(*who))) { g_free(me); @@ -64,23 +80,36 @@ XGetInputFocus(GDK_WINDOW_XDISPLAY(cnv->window->window), &focus_return, &revert_to_return); - if (focus_return != GDK_WINDOW_XWINDOW(cnv->window->window)) { + if ((choice & NOTIFY_IN_FOCUS) || focus_return != GDK_WINDOW_XWINDOW(cnv->window->window)) { if (method & METHOD_STRING) { - g_snprintf(buf, sizeof(buf), "%s", win->title); + strncpy(buf, win->title, sizeof(buf)); if (!strstr(buf, title_string)) { - g_snprintf(buf, sizeof(buf), "%s %s", title_string, win->title); + g_snprintf(buf, sizeof(buf), "%s%s", title_string, win->title); gtk_window_set_title(win, buf); } } + if (method & METHOD_COUNT) { + strncpy(buf, win->title, sizeof(buf)); + c = counter(buf, &length); + if (!c) { + g_snprintf(buf, sizeof(buf), "[1] %s", win->title); + } + else if (!g_strncasecmp(buf, "[", 1)) { + g_snprintf(buf, sizeof(buf), "[%d] %s", c+1, &win->title[3+length]); + } + gtk_window_set_title(win, buf); + } if (method & METHOD_QUOTE) { - g_snprintf(buf, sizeof(buf), "%s", win->title); + strncpy(buf, win->title, sizeof(buf)); if (g_strncasecmp(buf, "\"", 1)) { g_snprintf(buf, sizeof(buf), "\"%s\"", win->title); gtk_window_set_title(win, buf); } } if (method & METHOD_URGENT) { - /* do it the gdk way for windows compatibility(?) if I can figure it out */ + /* do it the gdk way for windows compatibility(?) if I can figure it out */ + /* Sean says this is a bad thing, and I should try using gtk_property_get first */ + /* I'll want to pay attention to note on dev.gnome.org though */ /* gdk_property_change(win->window, WM_HINTS, WM_HINTS, 32, GDK_PROP_MODE_REPLACE, XUrgencyHint, 1); */ XWMHints *hints = XGetWMHints(GDK_WINDOW_XDISPLAY(cnv->window->window), GDK_WINDOW_XWINDOW(cnv->window->window)); hints->flags |= XUrgencyHint; @@ -96,9 +125,11 @@ struct conversation *c = find_conversation(who); if (method & METHOD_QUOTE) - string_remove(c->window); + quote_remove(c->window); + if (method & METHOD_COUNT) + count_remove(c->window); if (method & METHOD_STRING) - quote_remove(c->window); + string_remove(c->window); if (method & METHOD_URGENT) urgent_remove(c); return 0; @@ -107,34 +138,34 @@ int new_conv(char *who) { struct conversation *c = find_conversation(who); - if (choice & REMOVE_FOCUS) { - gtk_signal_connect(GTK_OBJECT(c->window), "focus-in-event", GTK_SIGNAL_FUNC(un_star), NULL); +/* g_hash_table_insert(hash, who, GINT_TO_POINTER(choice)); */ + + if (choice & NOTIFY_FOCUS) { + gtk_signal_connect_while_alive(GTK_OBJECT(c->window), "focus-in-event", GTK_SIGNAL_FUNC(un_star), NULL, GTK_OBJECT(really_evil_hack)); gtk_object_set_user_data(GTK_OBJECT(c->window), c); } else { - gtk_signal_connect(GTK_OBJECT(c->window), "button_press_event", GTK_SIGNAL_FUNC(un_star), NULL); + gtk_signal_connect_while_alive(GTK_OBJECT(c->window), "button_press_event", GTK_SIGNAL_FUNC(un_star), NULL, GTK_OBJECT(really_evil_hack)); gtk_object_set_user_data(GTK_OBJECT(c->window), c); - gtk_signal_connect(GTK_OBJECT(c->text), "button_press_event", GTK_SIGNAL_FUNC(un_star_window), NULL); + gtk_signal_connect_while_alive(GTK_OBJECT(c->text), "button_press_event", GTK_SIGNAL_FUNC(un_star_window), NULL, GTK_OBJECT(really_evil_hack)); gtk_object_set_user_data(GTK_OBJECT(c->text), c); - gtk_signal_connect(GTK_OBJECT(c->entry), "button_press_event", GTK_SIGNAL_FUNC(un_star_window), NULL); + gtk_signal_connect_while_alive(GTK_OBJECT(c->entry), "button_press_event", GTK_SIGNAL_FUNC(un_star_window), NULL, GTK_OBJECT(really_evil_hack)); gtk_object_set_user_data(GTK_OBJECT(c->entry), c); -/* gtk_signal_connect(GTK_OBJECT(c->text), "button_press_event", GTK_SIGNAL_FUNC(un_star_window), c); */ -/* gtk_signal_connect(GTK_OBJECT(c->entry), "button_press_event", GTK_SIGNAL_FUNC(un_star_window), c); */ } - if (choice & REMOVE_TYPE) { - gtk_signal_connect(GTK_OBJECT(c->entry), "key-press-event", GTK_SIGNAL_FUNC(un_star_window), NULL); + if (choice & NOTIFY_TYPE) { + gtk_signal_connect_while_alive(GTK_OBJECT(c->entry), "key-press-event", GTK_SIGNAL_FUNC(un_star_window), NULL, GTK_OBJECT(really_evil_hack)); gtk_object_set_user_data(GTK_OBJECT(c->entry), (gpointer) c); -/* gtk_signal_connect(GTK_OBJECT(c->entry), "key-press-event", GTK_SIGNAL_FUNC(un_star_window), c); */ } } void un_star(GtkWidget *widget, gpointer data) { struct conversation *c = gtk_object_get_user_data(GTK_OBJECT(widget)); -/* struct conversation *c = data; */ if (method & METHOD_QUOTE) quote_remove(widget); + if (method & METHOD_COUNT) + count_remove(widget); if (method & METHOD_STRING) string_remove(widget); if (method & METHOD_URGENT) @@ -148,11 +179,35 @@ un_star(parent, data); } +/* This function returns the number in [ ]'s or 0 */ +int counter (char *buf, int *length) { + char temp[256]; + int i = 1; + *length = 0; + +/* if (buf[0] != '[') */ +/* return (0); */ + + while (isdigit(buf[i]) && i<sizeof(buf)) { + temp[i-1] = buf[i]; + (*length)++; + i++; + } + temp[i] = '\0'; + + if (buf[i] != ']') { + *length = 0; + return (0); + } + + return (atoi(temp)); +} + void string_remove(GtkWidget *widget) { char buf[256]; GtkWindow *win = GTK_WINDOW(widget); - g_snprintf(buf, sizeof(buf), "%s", win->title); + strncpy(buf, win->title, sizeof(buf)); if (strstr(buf, title_string)) { g_snprintf(buf, sizeof(buf), "%s", &win->title[strlen(title_string)]); gtk_window_set_title(win, buf); @@ -160,11 +215,25 @@ return; } +void count_remove(GtkWidget *widget) { + char buf[256]; + GtkWindow *win = GTK_WINDOW(widget); + int length; + + strncpy(buf, win->title, sizeof(buf)); + if (!g_strncasecmp(buf, "[", 1)) { + counter(buf, &length); + g_snprintf(buf, sizeof(buf), "%s", &win->title[3+length]); + gtk_window_set_title(win, buf); + } + return; +} + void quote_remove(GtkWidget *widget) { char buf[256]; GtkWindow *win = GTK_WINDOW(widget); - g_snprintf(buf, sizeof(buf), "%s", win->title); + strncpy(buf, win->title, sizeof(buf)); if (!g_strncasecmp(buf, "\"", 1)) { g_snprintf(buf, strlen(buf) - 1, "%s", &win->title[1]); gtk_window_set_title(win, buf); @@ -183,20 +252,18 @@ } void save_notify_prefs() { - char *buf; + gchar buf[1000]; FILE *fp; - buf = malloc(1000); snprintf(buf, 1000, "%s/.gaim/.notify", getenv("HOME")); if (!(fp = fopen(buf, "w"))) { do_error_dialog(_("Unable to write to config file"), _("Notify plugin")); return; } - free(buf); - fprintf(fp, "CHOICE=%d\n", choice); - fprintf(fp, "METHOD=%d\n", method); - fprintf(fp, "STRING=%s\n", title_string); + fprintf(fp, "%d=CHOICE\n", choice); + fprintf(fp, "%d=METHOD\n", method); + fprintf(fp, "%s=STRING\n", title_string); fclose(fp); } @@ -212,13 +279,15 @@ while (fgets(buf, 1000, fp) != NULL) { parsed = g_strsplit(g_strchomp(buf), "=", 2); if (parsed[0] && parsed[1]) { - if (!strcmp(parsed[0], "CHOICE")) - choice = atoi(parsed[1]); - if (!strcmp(parsed[0], "METHOD")) - method = atoi(parsed[1]); - if (!strcmp(parsed[0], "STRING")) - title_string = parsed[1]; + if (!strcmp(parsed[1], "CHOICE")) + choice = atoi(parsed[0]); + if (!strcmp(parsed[1], "METHOD")) + method = atoi(parsed[0]); + if (!strcmp(parsed[1], "STRING")) + if (title_string != NULL) g_free(title_string); + title_string = g_strdup(parsed[0]); } + g_strfreev(parsed); } fclose(fp); return; @@ -228,9 +297,9 @@ gint option = GPOINTER_TO_INT(data); if (option == 0) - choice ^= REMOVE_FOCUS; + choice ^= NOTIFY_FOCUS; else if (option == 1) - choice ^= REMOVE_TYPE; + choice ^= NOTIFY_TYPE; else if (option == 2) { method ^= METHOD_STRING; if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) @@ -242,14 +311,18 @@ method ^= METHOD_QUOTE; else if (option == 4) method ^= METHOD_URGENT; + else if (option == 5) + choice ^= NOTIFY_IN_FOCUS; + else if (option == 6) + method ^= METHOD_COUNT; } void setup_buttons() { - if (choice & REMOVE_FOCUS) + if (choice & NOTIFY_FOCUS) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(Focus), TRUE); else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(Click), TRUE); - if (choice & REMOVE_TYPE) + if (choice & NOTIFY_TYPE) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(Type), TRUE); else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(Type), FALSE); @@ -265,6 +338,12 @@ if (method & METHOD_URGENT) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(Urgent), TRUE); + if (choice & NOTIFY_IN_FOCUS) + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(InFocus), TRUE); + + if (method & METHOD_COUNT) + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(Count), TRUE); + return; } @@ -286,6 +365,9 @@ char *gaim_plugin_init(GModule *hndl) { handle = hndl; + really_evil_hack = gtk_label_new(""); +/* hash = g_hash_table_new(g_str_hash, g_int_equal); */ + load_notify_prefs(); gaim_signal_connect(handle, event_im_recv, received_im, NULL); @@ -295,6 +377,30 @@ return NULL; } +void gaim_plugin_remove() { + GList *c = conversations; + guint options; + + gtk_widget_destroy(really_evil_hack); + + while (c) { + struct conversation *cnv = (struct conversation *)c->data; +/* if (options = GPOINTER_TO_INT(g_hash_table_lookup(hash, cnv->name))) { */ + un_star(cnv->window, NULL); +/* if (options & REMOVE_FOCUS) */ +/* gtk_signal_disconnect_by_func(GTK_OBJECT(cnv->window), GTK_SIGNAL_FUNC(un_star), NULL); */ +/* else { */ +/* gtk_signal_disconnect_by_func(GTK_OBJECT(cnv->window), GTK_SIGNAL_FUNC(un_star), NULL); */ +/* gtk_signal_disconnect_by_func(GTK_OBJECT(cnv->text), GTK_SIGNAL_FUNC(un_star_window), NULL); */ +/* gtk_signal_disconnect_by_func(GTK_OBJECT(cnv->entry), GTK_SIGNAL_FUNC(un_star_window), NULL); */ +/* } */ +/* if (options & REMOVE_TYPE) */ +/* gtk_signal_disconnect_by_func(GTK_OBJECT(cnv->entry), GTK_SIGNAL_FUNC(un_star_window), NULL); */ +/* } */ + c = c->next; + } +} + char *name() { return "Visual Notification"; } @@ -307,14 +413,13 @@ void gaim_plugin_config() { GtkWidget *dialog_vbox; GtkWidget *button, *label; - GtkWidget *box, *box2, *box3, *frame; + GtkWidget *box, *box2, *box3, *box4, *frame; if (Dialog) return; /* main config dialog */ Dialog = gtk_dialog_new(); -/* gtk_widget_set_usize(Dialog, 275, -1); */ gtk_window_set_title(GTK_WINDOW(Dialog), "Notify plugin configuration"); gtk_window_set_policy(GTK_WINDOW(Dialog), FALSE, FALSE, TRUE); gtk_signal_connect(GTK_OBJECT(Dialog), "destroy", GTK_SIGNAL_FUNC(close_dialog), GINT_TO_POINTER(-1)); @@ -335,13 +440,20 @@ gtk_widget_set_usize(button, 80, -2); gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(close_dialog), GINT_TO_POINTER(1)); + /* warning label */ + label = gtk_label_new(_("Changes in notification removal options take effect only on new conversation windows")); + gtk_box_pack_start(GTK_BOX(dialog_vbox), label, FALSE, FALSE, 1); + /* main hbox */ box = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(dialog_vbox), box, FALSE, FALSE, 0); + box4 = gtk_vbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(box), box4, FALSE, FALSE, 0); + /* un-notify choices */ frame = gtk_frame_new(_("Remove notification when:")); - gtk_box_pack_start(GTK_BOX(box), frame, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(box4), frame, FALSE, FALSE, 0); box2 = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(frame), box2); @@ -371,10 +483,7 @@ Entry = gtk_entry_new_with_max_length(7); gtk_box_pack_start(GTK_BOX(box3), Entry, FALSE, FALSE, 0); - if (!title_string) - gtk_entry_set_text(GTK_ENTRY(Entry), "(*) "); - else - gtk_entry_set_text(GTK_ENTRY(Entry), title_string); + gtk_entry_set_text(GTK_ENTRY(Entry), title_string); Quote = gtk_check_button_new_with_label(_("Quote window title.")); gtk_box_pack_start(GTK_BOX(box2), Quote, FALSE, FALSE, 0); @@ -382,6 +491,22 @@ Urgent = gtk_check_button_new_with_label(_("Send URGENT to window manager.")); gtk_box_pack_start(GTK_BOX(box2), Urgent, FALSE, FALSE, 0); + label = gtk_label_new(_("Function oddly with tabs:")); + gtk_box_pack_start(GTK_BOX(box2), label, FALSE, FALSE, 0); + + Count = gtk_check_button_new_with_label(_("Insert count of new messages into window title")); + gtk_box_pack_start(GTK_BOX(box2), Count, FALSE, FALSE, 0); + + /* general options */ + frame = gtk_frame_new(_("General Options")); + gtk_box_pack_start(GTK_BOX(box4), frame, FALSE, FALSE, 0); + + box = gtk_vbox_new(FALSE, 0); + gtk_container_add(GTK_CONTAINER(frame), box); + + InFocus = gtk_check_button_new_with_label(_("Notify even when window is in focus")); + gtk_box_pack_start(GTK_BOX(box), InFocus, FALSE, FALSE, 0); + /* setup buttons, then attach signals */ setup_buttons(); gtk_signal_connect(GTK_OBJECT(Focus), "toggled", GTK_SIGNAL_FUNC(options), GINT_TO_POINTER(0)); @@ -389,6 +514,8 @@ gtk_signal_connect(GTK_OBJECT(String), "toggled", GTK_SIGNAL_FUNC(options), GINT_TO_POINTER(2)); gtk_signal_connect(GTK_OBJECT(Quote), "toggled", GTK_SIGNAL_FUNC(options), GINT_TO_POINTER(3)); gtk_signal_connect(GTK_OBJECT(Urgent), "toggled", GTK_SIGNAL_FUNC(options), GINT_TO_POINTER(4)); + gtk_signal_connect(GTK_OBJECT(InFocus), "toggled", GTK_SIGNAL_FUNC(options), GINT_TO_POINTER(5)); + gtk_signal_connect(GTK_OBJECT(Count), "toggled", GTK_SIGNAL_FUNC(options), GINT_TO_POINTER(6)); gtk_widget_show_all(Dialog); }