| 1 /* Rewritten by Etan Reisner <deryni@eden.rutgers.edu> |
1 /* |
| |
2 * Gaim buddy notification plugin. |
| 2 * |
3 * |
| 3 * Added config dialog |
4 * Copyright (C) 2000-2001, Eric Warmenhoven (original code) |
| 4 * Added control over notification method |
5 * Copyright (C) 2002, Etan Reisner <deryni@eden.rutgers.edu> (rewritten code) |
| 5 * Added control over when to release notification |
6 * Copyright (C) 2003, Christian Hammond (update for changed API) |
| 6 * |
7 * Copyright (C) 2003, Brian Tarricon <bjt23@cornell.edu> (mostly rewritten) |
| 7 * Added option to get notification for chats also |
8 * Copyright (C) 2003, Mark Doliner (minor cleanup) |
| 8 * Cleaned up code |
9 * |
| 9 * Added option to notify on click as it's own option |
10 * This program is free software; you can redistribute it and/or modify |
| 10 * rather then as what happens when on focus isn't clicked |
11 * it under the terms of the GNU General Public License as published by |
| 11 * Added apply button to change the denotification methods for |
12 * the Free Software Foundation; either version 2 of the License, or |
| 12 * open conversation windows |
13 * (at your option) any later version. |
| 13 * Fixed apply to conversations, count now keeps count across applies |
14 * |
| 14 * Fixed(?) memory leak, and in the process fixed some stupidities |
15 * This program is distributed in the hope that it will be useful, |
| 15 * Hit enter when done editing the title string entry box to save it |
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| |
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| |
18 * GNU General Public License for more details. |
| |
19 * |
| |
20 * You should have received a copy of the GNU General Public License |
| |
21 * along with this program; if not, write to the Free Software |
| |
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| |
23 * |
| |
24 */ |
| |
25 |
| |
26 /* |
| |
27 * From Etan, 2002: |
| |
28 * -Added config dialog |
| |
29 * -Added control over notification method |
| |
30 * -Added control over when to release notification |
| |
31 * |
| |
32 * -Added option to get notification for chats also |
| |
33 * -Cleaned up code |
| |
34 * -Added option to notify on click as it's own option |
| |
35 * rather then as what happens when on focus isn't clicked |
| |
36 * -Added apply button to change the denotification methods for |
| |
37 * open conversation windows |
| |
38 * -Fixed apply to conversations, count now keeps count across applies |
| |
39 * -Fixed(?) memory leak, and in the process fixed some stupidities |
| |
40 * -Hit enter when done editing the title string entry box to save it |
| 16 * |
41 * |
| 17 * Thanks to Carles Pina i Estany <carles@pinux.info> |
42 * Thanks to Carles Pina i Estany <carles@pinux.info> |
| 18 * for count of new messages option |
43 * for count of new messages option |
| |
44 * |
| |
45 * From Brian, 20 July 2003: |
| |
46 * -Use new xml prefs |
| |
47 * -Better handling of notification states tracking |
| |
48 * -Better pref change handling |
| |
49 * -Fixed a possible memleak and possible crash (rare) |
| |
50 * -Use gtk_window_get_title() rather than gtkwin->title |
| |
51 * -Other random fixes and cleanups |
| 19 */ |
52 */ |
| 20 |
53 |
| 21 #include "config.h" |
54 #include "internal.h" |
| 22 |
55 |
| 23 #include "gaim.h" |
56 #include "conversation.h" |
| |
57 #include "debug.h" |
| |
58 #include "notify.h" |
| |
59 #include "prefs.h" |
| |
60 |
| |
61 #include "gtkconv.h" |
| |
62 #include "gtkplugin.h" |
| |
63 #include "gtkutils.h" |
| |
64 |
| |
65 |
| |
66 #include "gtkplugin.h" |
| |
67 |
| 24 #include <string.h> |
68 #include <string.h> |
| 25 #include <ctype.h> |
69 #include <ctype.h> |
| 26 #include <stdlib.h> |
70 #include <stdlib.h> |
| 27 #include <gtk/gtk.h> |
71 #include <gtk/gtk.h> |
| 28 #include <X11/Xlib.h> |
72 #include <X11/Xlib.h> |
| 29 #include <X11/Xutil.h> |
73 #include <X11/Xutil.h> |
| 30 #include <X11/Xatom.h> |
74 #include <X11/Xatom.h> |
| 31 #include <gdk/gdkx.h> |
75 #include <gdk/gdkx.h> |
| 32 #include "gtkplugin.h" |
76 #include <glib.h> |
| 33 |
77 |
| 34 #define NOTIFY_PLUGIN_ID "gtk-notify" |
78 #define NOTIFY_PLUGIN_ID "gtk-x11-notify" |
| 35 |
79 |
| 36 guint type = 1; |
80 #define OPT_TYPE_IM ((guint)0x00000001) |
| 37 #define TYPE_IM 0x00000001 |
81 #define OPT_TYPE_CHAT ((guint)0x00000002) |
| 38 #define TYPE_CHAT 0x00000002 |
82 #define OPT_NOTIFY_FOCUS ((guint)0x00000004) |
| 39 |
83 #define OPT_NOTIFY_TYPE ((guint)0x00000008) |
| 40 guint choice = 1; |
84 #define OPT_NOTIFY_IN_FOCUS ((guint)0x00000010) |
| 41 #define NOTIFY_FOCUS 0x00000001 |
85 #define OPT_NOTIFY_CLICK ((guint)0x00000020) |
| 42 #define NOTIFY_TYPE 0x00000002 |
86 #define OPT_METHOD_STRING ((guint)0x00000040) |
| 43 #define NOTIFY_IN_FOCUS 0x00000004 |
87 #define OPT_METHOD_QUOTE ((guint)0x00000080) |
| 44 #define NOTIFY_CLICK 0x00000008 |
88 #define OPT_METHOD_URGENT ((guint)0x00000100) |
| 45 |
89 #define OPT_METHOD_COUNT ((guint)0x00000200) |
| 46 guint method = 1; |
90 #define OPT_METHOD_STRING_CHNG ((guint)0x00000400) |
| 47 #define METHOD_STRING 0x00000001 |
91 #define STATE_IS_NOTIFIED ((guint)0x80000000) |
| 48 #define METHOD_QUOTE 0x00000002 |
92 |
| 49 #define METHOD_URGENT 0x00000004 |
93 #define TITLE_STR_BUFSIZE 256 |
| 50 #define METHOD_COUNT 0x00000008 |
94 |
| |
95 #define GDATASTR "notify-plugin-opts" |
| |
96 #define GDATASTRCNT "notify-plugin-count" |
| 51 |
97 |
| 52 static GaimPlugin *my_plugin = NULL; |
98 static GaimPlugin *my_plugin = NULL; |
| 53 |
99 |
| 54 void *handle; |
100 static guint notify_opts = 0; |
| 55 GtkWidget *Entry; |
101 static gchar title_string[TITLE_STR_BUFSIZE+1]; |
| 56 gchar *title_string; |
102 |
| 57 int Number = 0; |
103 /* notification set/unset */ |
| 58 |
104 static int notify(GaimConversation *c); |
| 59 /* predefine some functions, less warnings */ |
105 static void unnotify(GaimConversation *c); |
| 60 void options(GtkWidget *widget, gpointer data); |
106 static int unnotify_cb(GtkWidget *widget, gpointer data); |
| 61 /* this returns an int so that typing events don't get stopped here */ |
107 |
| 62 int un_star(GtkWidget *widget, gpointer data); |
108 /* gtk widget callbacks for prefs panel */ |
| 63 int counter (char *buf, int *length); |
109 static void options_toggle_cb(GtkWidget *widget, gpointer data); |
| 64 /*string functions */ |
110 static gboolean options_settitle_cb(GtkWidget *w, GdkEventFocus *evt, GtkWidget *entry); |
| 65 void string_add(GtkWidget *widget); |
111 static void options_toggle_title_cb(GtkWidget *w, GtkWidget *entry); |
| 66 gboolean string_remove(GtkWidget *widget); |
112 static void apply_options(int opt_chng); |
| |
113 |
| |
114 /* string functions */ |
| |
115 static void string_add(GtkWidget *widget); |
| |
116 static void string_remove(GtkWidget *widget); |
| |
117 |
| 67 /* count functions */ |
118 /* count functions */ |
| 68 void count_add(GtkWidget *widget, int number); |
119 static void count_add(GtkWidget *widget); |
| 69 gboolean count_remove(GtkWidget *widget); |
120 static void count_remove(GtkWidget *widget); |
| |
121 |
| 70 /* quote functions */ |
122 /* quote functions */ |
| 71 void quote_add(GtkWidget *widget); |
123 static void quote_add(GtkWidget *widget); |
| 72 gboolean quote_remove(GtkWidget *widget); |
124 static void quote_remove(GtkWidget *widget); |
| |
125 |
| 73 /* urgent functions */ |
126 /* urgent functions */ |
| 74 void urgent_add(GaimConversation *c); |
127 static void urgent_add(GaimConversation *c); |
| 75 gboolean urgent_remove(GaimConversation *c); |
128 static void urgent_remove(GaimConversation *c); |
| 76 |
129 |
| 77 int notify(GaimConversation *cnv) { |
130 /****************************************/ |
| |
131 /* Begin doing stuff below this line... */ |
| |
132 /****************************************/ |
| |
133 |
| |
134 static int notify(GaimConversation *c) { |
| 78 GaimGtkWindow *gtkwin; |
135 GaimGtkWindow *gtkwin; |
| 79 Window focus_return; |
136 Window focus_return; |
| 80 int revert_to_return; |
137 int revert_to_return; |
| 81 |
138 guint opts; |
| 82 gtkwin = GAIM_GTK_WINDOW(gaim_conversation_get_window(cnv)); |
139 gint count; |
| |
140 |
| |
141 gtkwin = GAIM_GTK_WINDOW(gaim_conversation_get_window(c)); |
| |
142 |
| |
143 /* increment message counter */ |
| |
144 count = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(gtkwin->window), GDATASTRCNT)); |
| |
145 g_object_set_data(G_OBJECT(gtkwin->window), GDATASTRCNT, GINT_TO_POINTER(count+1)); |
| |
146 |
| |
147 /* if we aren't doing notifications for this type of convo, bail */ |
| |
148 if (((gaim_conversation_get_type(c) == GAIM_CONV_IM) && !(notify_opts & OPT_TYPE_IM)) || |
| |
149 ((gaim_conversation_get_type(c) == GAIM_CONV_CHAT) && !(notify_opts & OPT_TYPE_CHAT))) |
| |
150 return 0; |
| 83 |
151 |
| 84 XGetInputFocus(GDK_WINDOW_XDISPLAY(gtkwin->window->window), &focus_return, &revert_to_return); |
152 XGetInputFocus(GDK_WINDOW_XDISPLAY(gtkwin->window->window), &focus_return, &revert_to_return); |
| 85 |
153 |
| 86 if ((choice & NOTIFY_IN_FOCUS) || |
154 if ((notify_opts & OPT_NOTIFY_IN_FOCUS) || |
| 87 focus_return != GDK_WINDOW_XWINDOW(gtkwin->window->window)) { |
155 (focus_return != GDK_WINDOW_XWINDOW(gtkwin->window->window))) { |
| 88 if (method & METHOD_STRING) |
156 if (notify_opts & OPT_METHOD_STRING) |
| 89 string_add(gtkwin->window); |
157 string_add(gtkwin->window); |
| 90 if (method & METHOD_COUNT) |
158 if (notify_opts & OPT_METHOD_COUNT) |
| 91 count_add(gtkwin->window, 0); |
159 count_add(gtkwin->window); |
| 92 if (method & METHOD_QUOTE) |
160 if (notify_opts & OPT_METHOD_QUOTE) |
| 93 quote_add(gtkwin->window); |
161 quote_add(gtkwin->window); |
| 94 if (method & METHOD_URGENT) |
162 if (notify_opts & OPT_METHOD_URGENT) |
| 95 urgent_add(cnv); |
163 urgent_add(c); |
| 96 } |
164 } |
| |
165 |
| |
166 opts = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(gtkwin->window), GDATASTR)); |
| |
167 opts |= STATE_IS_NOTIFIED; |
| |
168 g_object_set_data(G_OBJECT(gtkwin->window), GDATASTR, GINT_TO_POINTER(opts)); |
| |
169 |
| 97 return 0; |
170 return 0; |
| 98 } |
171 } |
| 99 |
172 |
| 100 guint unnotify(GaimConversation *c, gboolean clean) { |
173 static void unnotify(GaimConversation *c) { |
| 101 GaimGtkWindow *gtkwin; |
174 GaimGtkWindow *gtkwin; |
| 102 guint option = 0; |
|
| 103 |
175 |
| 104 gtkwin = GAIM_GTK_WINDOW(gaim_conversation_get_window(c)); |
176 gtkwin = GAIM_GTK_WINDOW(gaim_conversation_get_window(c)); |
| 105 |
177 |
| 106 /* The top level ifs check whether we are either cleaning all methods, |
178 urgent_remove(c); |
| 107 * or whether we have that method is currently selected. |
179 quote_remove(GTK_WIDGET(gtkwin->window)); |
| 108 * If we do then they are cleaned |
180 count_remove(GTK_WIDGET(gtkwin->window)); |
| 109 * |
181 string_remove(GTK_WIDGET(gtkwin->window)); |
| 110 * The second level ifs check if we removed something, |
182 g_object_set_data(G_OBJECT(gtkwin->window), GDATASTR, GINT_TO_POINTER((guint)0)); |
| 111 * and if that method is currently selected. |
183 g_object_set_data(G_OBJECT(gtkwin->window), GDATASTRCNT, GINT_TO_POINTER((guint)0)); |
| 112 * If we did and it is then set option so that it can be re-added */ |
184 } |
| 113 if (clean || (method & METHOD_QUOTE)) |
185 |
| 114 if (quote_remove(gtkwin->window) && (method & METHOD_QUOTE)) |
186 static int unnotify_cb(GtkWidget *widget, gpointer data) { |
| 115 option ^= METHOD_QUOTE; |
187 GaimConversation *c = g_object_get_data(G_OBJECT(widget), "user_data"); |
| 116 |
188 |
| 117 if (clean || (method & METHOD_COUNT)) |
189 gaim_debug(GAIM_DEBUG_INFO, "notify.c", "in unnotify_cb()\n"); |
| 118 if (count_remove(gtkwin->window) && (method & METHOD_COUNT)) |
190 |
| 119 option ^= METHOD_COUNT; |
191 if (c) |
| 120 |
192 urgent_remove(c); |
| 121 if (clean || (method & METHOD_STRING)) |
193 quote_remove(widget); |
| 122 if (string_remove(gtkwin->window) && (method & METHOD_STRING)) |
194 count_remove(widget); |
| 123 option ^= METHOD_STRING; |
195 string_remove(widget); |
| 124 |
196 g_object_set_data(G_OBJECT(widget), GDATASTR, GINT_TO_POINTER((guint)0)); |
| 125 if (clean || (method & METHOD_URGENT)) |
197 g_object_set_data(G_OBJECT(widget), GDATASTRCNT, GINT_TO_POINTER((guint)0)); |
| 126 if (urgent_remove(c) && (method & METHOD_URGENT)) |
198 |
| 127 option ^= METHOD_URGENT; |
199 return 0; |
| 128 |
200 } |
| 129 return option; |
201 |
| 130 } |
202 static void chat_recv_im(GaimConnection *gc, int id, char **who, char **text) { |
| 131 |
|
| 132 void chat_recv_im(struct gaim_connection *gc, int id, char **who, char **text) { |
|
| 133 GaimConversation *c = gaim_find_chat(gc, id); |
203 GaimConversation *c = gaim_find_chat(gc, id); |
| 134 |
204 |
| 135 if (c && (type & TYPE_CHAT)) |
205 if (c) |
| 136 notify(c); |
206 notify(c); |
| 137 return; |
207 return; |
| 138 } |
208 } |
| 139 |
209 |
| 140 void chat_sent_im(struct gaim_connection *gc, int id, char **text) { |
210 static void chat_sent_im(GaimConnection *gc, int id, char **text) { |
| 141 GaimConversation *c = gaim_find_chat(gc, id); |
211 GaimConversation *c = gaim_find_chat(gc, id); |
| 142 |
212 |
| 143 if (c && (type & TYPE_CHAT)) |
213 if (c) |
| 144 unnotify(c, FALSE); |
214 unnotify(c); |
| 145 return; |
215 return; |
| 146 } |
216 } |
| 147 |
217 |
| 148 int im_recv_im(struct gaim_connection *gc, char **who, char **what, void *m) { |
218 static int im_recv_im(GaimConnection *gc, char **who, char **what, void *m) { |
| 149 GaimConversation *c = gaim_find_conversation(*who); |
219 GaimConversation *c = gaim_find_conversation(*who); |
| 150 |
220 |
| 151 if (c && (type & TYPE_IM)) |
221 if (c) |
| 152 notify(c); |
222 notify(c); |
| 153 return 0; |
223 return 0; |
| 154 } |
224 } |
| 155 |
225 |
| 156 int im_sent_im(struct gaim_connection *gc, char *who, char **what, void *m) { |
226 static int im_sent_im(GaimConnection *gc, char *who, char **what, void *m) { |
| 157 GaimConversation *c = gaim_find_conversation(who); |
227 GaimConversation *c = gaim_find_conversation(who); |
| 158 |
228 |
| 159 if (c && (type & TYPE_IM)) |
229 if (c) |
| 160 unnotify(c, FALSE); |
230 unnotify(c); |
| 161 return 0; |
231 return 0; |
| 162 } |
232 } |
| 163 |
233 |
| 164 int attach_signals(GaimConversation *c) { |
234 static int attach_signals(GaimConversation *c) { |
| 165 GaimGtkConversation *gtkconv; |
235 GaimGtkConversation *gtkconv; |
| 166 GaimGtkWindow *gtkwin; |
236 GaimGtkWindow *gtkwin; |
| 167 |
237 |
| 168 gtkconv = GAIM_GTK_CONVERSATION(c); |
238 gtkconv = GAIM_GTK_CONVERSATION(c); |
| 169 gtkwin = GAIM_GTK_WINDOW(gaim_conversation_get_window(c)); |
239 gtkwin = GAIM_GTK_WINDOW(gaim_conversation_get_window(c)); |
| 170 |
240 |
| 171 if (choice & NOTIFY_FOCUS) { |
241 if (notify_opts & OPT_NOTIFY_FOCUS) { |
| 172 g_signal_connect(G_OBJECT(gtkwin->window), "focus-in-event", G_CALLBACK(un_star), NULL); |
242 g_signal_connect(G_OBJECT(gtkwin->window), "focus-in-event", G_CALLBACK(unnotify_cb), NULL); |
| 173 } |
243 } |
| 174 |
244 |
| 175 if (choice & NOTIFY_CLICK) { |
245 if (notify_opts & OPT_NOTIFY_CLICK) { |
| 176 g_signal_connect(G_OBJECT(gtkwin->window), "button_press_event", G_CALLBACK(un_star), NULL); |
246 g_signal_connect(G_OBJECT(gtkwin->window), "button_press_event", G_CALLBACK(unnotify_cb), NULL); |
| 177 |
247 g_signal_connect_swapped(G_OBJECT(gtkconv->imhtml), "button_press_event", G_CALLBACK(unnotify_cb), G_OBJECT(gtkwin->window)); |
| 178 g_signal_connect_swapped(G_OBJECT(gtkconv->imhtml), "button_press_event", G_CALLBACK(un_star), G_OBJECT(gtkwin->window)); |
248 g_signal_connect_swapped(G_OBJECT(gtkconv->entry), "button_press_event", G_CALLBACK(unnotify_cb), G_OBJECT(gtkwin->window)); |
| 179 |
249 } |
| 180 g_signal_connect_swapped(G_OBJECT(gtkconv->entry), "button_press_event", G_CALLBACK(un_star), G_OBJECT(gtkwin->window)); |
250 |
| 181 } |
251 if (notify_opts & OPT_NOTIFY_TYPE) { |
| 182 |
252 g_signal_connect_swapped(G_OBJECT(gtkconv->entry), "key-press-event", G_CALLBACK(unnotify_cb), G_OBJECT(gtkwin->window)); |
| 183 if (choice & NOTIFY_TYPE) { |
253 } |
| 184 g_signal_connect_swapped(G_OBJECT(gtkconv->entry), "key-press-event", G_CALLBACK(un_star), G_OBJECT(gtkwin->window)); |
254 |
| 185 } |
|
| 186 |
|
| 187 g_object_set_data(G_OBJECT(gtkwin->window), "user_data", c); |
|
| 188 g_object_set_data(G_OBJECT(gtkwin->window), "notify_data", GUINT_TO_POINTER(choice)); |
|
| 189 return 0; |
255 return 0; |
| 190 } |
256 } |
| 191 |
257 |
| 192 void detach_signals(GaimConversation *c) { |
258 static void detach_signals(GaimConversation *c) { |
| 193 GaimGtkConversation *gtkconv; |
259 GaimGtkConversation *gtkconv; |
| 194 GaimGtkWindow *gtkwin; |
260 GaimGtkWindow *gtkwin; |
| 195 guint options; |
|
| 196 |
261 |
| 197 gtkconv = GAIM_GTK_CONVERSATION(c); |
262 gtkconv = GAIM_GTK_CONVERSATION(c); |
| 198 gtkwin = GAIM_GTK_WINDOW(gaim_conversation_get_window(c)); |
263 gtkwin = GAIM_GTK_WINDOW(gaim_conversation_get_window(c)); |
| 199 |
264 |
| 200 options = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(gtkwin->window), "notify_data")); |
265 if (notify_opts & OPT_NOTIFY_FOCUS) { |
| 201 |
266 g_signal_handlers_disconnect_by_func(G_OBJECT(gtkwin->window), unnotify_cb, NULL); |
| 202 if (options & NOTIFY_FOCUS) { |
267 } |
| 203 g_signal_handlers_disconnect_by_func(G_OBJECT(gtkwin->window), un_star, NULL); |
268 |
| 204 } |
269 if (notify_opts & OPT_NOTIFY_CLICK) { |
| 205 if (options & NOTIFY_CLICK) { |
270 g_signal_handlers_disconnect_by_func(G_OBJECT(gtkwin->window), unnotify_cb, NULL); |
| 206 g_signal_handlers_disconnect_by_func(G_OBJECT(gtkwin->window), un_star, NULL); |
271 g_signal_handlers_disconnect_by_func(G_OBJECT(gtkconv->imhtml), unnotify_cb, gtkwin->window); |
| 207 g_signal_handlers_disconnect_by_func(G_OBJECT(gtkconv->imhtml), un_star, gtkwin->window); |
272 g_signal_handlers_disconnect_by_func(G_OBJECT(gtkconv->entry), unnotify_cb, gtkwin->window); |
| 208 g_signal_handlers_disconnect_by_func(G_OBJECT(gtkconv->entry), un_star, gtkwin->window); |
273 } |
| 209 } |
274 |
| 210 |
275 if (notify_opts & OPT_NOTIFY_TYPE) { |
| 211 if (options & NOTIFY_TYPE) { |
276 g_signal_handlers_disconnect_by_func(G_OBJECT(gtkconv->entry), unnotify_cb, gtkwin->window); |
| 212 g_signal_handlers_disconnect_by_func(G_OBJECT(gtkconv->entry), un_star, gtkwin->window); |
277 } |
| 213 } |
278 } |
| 214 } |
279 |
| 215 |
280 static void new_conv(char *who) { |
| 216 void new_conv(char *who) { |
|
| 217 GaimConversation *c = gaim_find_conversation(who); |
281 GaimConversation *c = gaim_find_conversation(who); |
| 218 |
282 GaimGtkWindow *gtkwin = GAIM_GTK_WINDOW(gaim_conversation_get_window(c)); |
| 219 if (c && (type & TYPE_IM)) |
283 |
| |
284 g_object_set_data(G_OBJECT(gtkwin->window), GDATASTR, GINT_TO_POINTER((guint)0)); |
| |
285 g_object_set_data(G_OBJECT(gtkwin->window), GDATASTRCNT, GINT_TO_POINTER((guint)0)); |
| |
286 |
| |
287 if (c && (notify_opts & OPT_TYPE_IM)) |
| 220 attach_signals(c); |
288 attach_signals(c); |
| 221 } |
289 } |
| 222 |
290 |
| 223 void chat_join(struct gaim_connection *gc, int id, char *room) { |
291 static void chat_join(GaimConnection *gc, int id, char *room) { |
| 224 GaimConversation *c = gaim_find_chat(gc, id); |
292 GaimConversation *c = gaim_find_chat(gc, id); |
| 225 |
293 GaimGtkWindow *gtkwin = GAIM_GTK_WINDOW(gaim_conversation_get_window(c)); |
| 226 if (c && (type & TYPE_CHAT)) |
294 |
| |
295 g_object_set_data(G_OBJECT(gtkwin->window), GDATASTR, GINT_TO_POINTER((guint)0)); |
| |
296 g_object_set_data(G_OBJECT(gtkwin->window), GDATASTRCNT, GINT_TO_POINTER((guint)0)); |
| |
297 |
| |
298 if (c && (notify_opts & OPT_TYPE_CHAT)) |
| 227 attach_signals(c); |
299 attach_signals(c); |
| 228 } |
300 } |
| 229 |
301 |
| 230 int un_star(GtkWidget *widget, gpointer data) { |
302 static void string_add(GtkWidget *widget) { |
| 231 GaimConversation *c = g_object_get_data(G_OBJECT(widget), "user_data"); |
303 GtkWindow *win = GTK_WINDOW(widget); |
| 232 |
304 gchar newtitle[256]; |
| 233 if (method & METHOD_QUOTE) |
305 const gchar *curtitle = gtk_window_get_title(win); |
| 234 quote_remove(widget); |
306 guint opts = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), GDATASTR)); |
| 235 if (method & METHOD_COUNT) |
307 |
| |
308 gaim_debug(GAIM_DEBUG_INFO, "notify.c", "string_add(): opts=0x%04x\n", opts); |
| |
309 |
| |
310 if (opts & OPT_METHOD_STRING) |
| |
311 return; |
| |
312 |
| |
313 if (!strstr(curtitle, title_string)) { |
| |
314 if (opts & OPT_METHOD_COUNT) { |
| |
315 char *p = strchr(curtitle, ']'); |
| |
316 int len1; |
| |
317 if (!p) |
| |
318 return; |
| |
319 len1 = p-curtitle+2; |
| |
320 memcpy(newtitle, curtitle, len1); |
| |
321 strncpy(newtitle+len1, title_string, sizeof(newtitle)-len1); |
| |
322 strncpy(newtitle+len1+strlen(title_string), curtitle+len1, |
| |
323 sizeof(newtitle)-len1-strlen(title_string)); |
| |
324 } else if (opts & OPT_METHOD_QUOTE) { |
| |
325 g_snprintf(newtitle, sizeof(newtitle), "\"%s%s", title_string, curtitle+1); |
| |
326 } else { |
| |
327 g_snprintf(newtitle, sizeof(newtitle), "%s%s", title_string, curtitle); |
| |
328 } |
| |
329 gtk_window_set_title(win, newtitle); |
| |
330 gaim_debug(GAIM_DEBUG_INFO, "notify.c", "added string to window title\n"); |
| |
331 } |
| |
332 |
| |
333 opts |= OPT_METHOD_STRING; |
| |
334 g_object_set_data(G_OBJECT(widget), GDATASTR, GINT_TO_POINTER(opts)); |
| |
335 } |
| |
336 |
| |
337 static void string_remove(GtkWidget *widget) { |
| |
338 GtkWindow *win = GTK_WINDOW(widget); |
| |
339 gchar newtitle[256]; |
| |
340 const gchar *curtitle; |
| |
341 guint opts = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), GDATASTR)); |
| |
342 |
| |
343 gaim_debug(GAIM_DEBUG_INFO, "notify.c", "string_remove(): opts=0x%04x\n", opts); |
| |
344 |
| |
345 if (!(opts & OPT_METHOD_STRING)) |
| |
346 return; |
| |
347 |
| |
348 curtitle = gtk_window_get_title(win); |
| |
349 |
| |
350 if (strstr(curtitle, title_string)) { |
| |
351 if (opts & OPT_METHOD_COUNT) { |
| |
352 char *p = strchr(curtitle, ']'); |
| |
353 int len1; |
| |
354 if (!p) |
| |
355 return; |
| |
356 len1 = p-curtitle+2; |
| |
357 memcpy(newtitle, curtitle, len1); |
| |
358 strncpy(newtitle+len1, curtitle+len1+strlen(title_string), sizeof(newtitle)-len1); |
| |
359 } else if (opts & OPT_METHOD_QUOTE) { |
| |
360 g_snprintf(newtitle, sizeof(newtitle), "\"%s", curtitle+strlen(title_string)+1); |
| |
361 } else |
| |
362 strncpy(newtitle, curtitle+strlen(title_string), sizeof(newtitle)); |
| |
363 } |
| |
364 |
| |
365 gtk_window_set_title(win, newtitle); |
| |
366 gaim_debug(GAIM_DEBUG_INFO, "notify.c", "removed string from window title (title now %s)\n", newtitle); |
| |
367 } |
| |
368 |
| |
369 static void count_add(GtkWidget *widget) { |
| |
370 GtkWindow *win = GTK_WINDOW(widget); |
| |
371 char newtitle[256]; |
| |
372 const gchar *curtitle; |
| |
373 guint opts = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), GDATASTR)); |
| |
374 gint curcount = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), GDATASTRCNT)); |
| |
375 |
| |
376 gaim_debug(GAIM_DEBUG_INFO, "notify.c", "count_add(): opts=0x%04x\n", opts); |
| |
377 |
| |
378 if (curcount>0 && (opts & OPT_METHOD_COUNT)) |
| 236 count_remove(widget); |
379 count_remove(widget); |
| 237 if (method & METHOD_STRING) |
380 |
| 238 string_remove(widget); |
381 curtitle = gtk_window_get_title(win); |
| 239 if (c && method & METHOD_URGENT) |
382 if (opts & OPT_METHOD_QUOTE) |
| 240 urgent_remove(c); |
383 g_snprintf(newtitle, sizeof(newtitle), "\"[%d] %s", curcount, curtitle+1); |
| 241 return 0; |
384 else |
| 242 } |
385 g_snprintf(newtitle, sizeof(newtitle), "[%d] %s", curcount, curtitle); |
| 243 |
386 gtk_window_set_title(win, newtitle); |
| 244 /* This function returns the number in [ ]'s or 0 |
387 |
| 245 and sets *length to the number of digits in that number */ |
388 gaim_debug(GAIM_DEBUG_INFO, "notify.c", "added count of %d to window\n", curcount); |
| 246 int counter (char *buf, int *length) { |
389 |
| 247 char temp[256]; |
390 opts |= OPT_METHOD_COUNT; |
| 248 int i = 0; |
391 g_object_set_data(G_OBJECT(widget), GDATASTR, GINT_TO_POINTER(opts)); |
| 249 int j = 0; |
392 } |
| 250 *length = 0; |
393 |
| 251 |
394 static void count_remove(GtkWidget *widget) { |
| 252 /* Don't assume buf[0]=='[' */ |
|
| 253 while( buf[i++] != '[' && i<sizeof(buf)); |
|
| 254 |
|
| 255 while (isdigit(buf[i]) && i<sizeof(buf)) { |
|
| 256 temp[j++] = buf[i++]; |
|
| 257 (*length)++; |
|
| 258 } |
|
| 259 temp[j] = '\0'; |
|
| 260 |
|
| 261 if (buf[i] != ']') { |
|
| 262 *length = 0; |
|
| 263 return (0); |
|
| 264 } |
|
| 265 |
|
| 266 return (atoi(temp)); |
|
| 267 } |
|
| 268 |
|
| 269 void string_add(GtkWidget *widget) { |
|
| 270 char buf[256]; |
|
| 271 GtkWindow *win = GTK_WINDOW(widget); |
395 GtkWindow *win = GTK_WINDOW(widget); |
| 272 |
396 char newtitle[256], *p; |
| 273 strncpy(buf, win->title, sizeof(buf)); |
397 const gchar *curtitle; |
| 274 if (!strstr(buf, title_string)) { |
398 guint opts = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), GDATASTR)); |
| 275 g_snprintf(buf, sizeof(buf), "%s%s", title_string, win->title); |
399 |
| 276 gtk_window_set_title(win, buf); |
400 gaim_debug(GAIM_DEBUG_INFO, "notify.c", "count_remove(): opts=0x%04x\n", opts); |
| 277 } |
401 |
| 278 } |
402 if (!(opts & OPT_METHOD_COUNT)) |
| 279 |
403 return; |
| 280 gboolean string_remove(GtkWidget *widget) { |
404 |
| 281 char buf[256]; |
405 curtitle = gtk_window_get_title(win); |
| |
406 |
| |
407 p = strchr(curtitle, ']'); |
| |
408 |
| |
409 if (p) { |
| |
410 if (opts & OPT_METHOD_QUOTE) |
| |
411 g_snprintf(newtitle, sizeof(newtitle), "\"%s", p+2); |
| |
412 else |
| |
413 g_snprintf(newtitle, sizeof(newtitle), p+2); |
| |
414 gtk_window_set_title(win, newtitle); |
| |
415 gaim_debug(GAIM_DEBUG_INFO, "notify.c", "removed count from title (title now %s)\n", newtitle); |
| |
416 } |
| |
417 |
| |
418 opts &= ~OPT_METHOD_COUNT; |
| |
419 g_object_set_data(G_OBJECT(widget), GDATASTR, GINT_TO_POINTER(opts)); |
| |
420 } |
| |
421 |
| |
422 static void quote_add(GtkWidget *widget) { |
| 282 GtkWindow *win = GTK_WINDOW(widget); |
423 GtkWindow *win = GTK_WINDOW(widget); |
| 283 |
424 char newtitle[256]; |
| 284 strncpy(buf, win->title, sizeof(buf)); |
425 const gchar *curtitle = gtk_window_get_title(win); |
| 285 if (strstr(buf, title_string)) { |
426 guint opts = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), GDATASTR)); |
| 286 g_snprintf(buf, sizeof(buf), "%s", &win->title[strlen(title_string)]); |
427 |
| 287 gtk_window_set_title(win, buf); |
428 gaim_debug(GAIM_DEBUG_INFO, "notify.c", "quote_add(): opts=0x%04x\n", opts); |
| 288 return TRUE; |
429 |
| 289 } |
430 if (opts & OPT_METHOD_QUOTE) |
| 290 return FALSE; |
431 return; |
| 291 } |
432 |
| 292 |
433 if (*curtitle != '\"') { |
| 293 void count_add(GtkWidget *widget, int number) { |
434 g_snprintf(newtitle, sizeof(newtitle), "\"%s\"", curtitle); |
| 294 char buf[256]; |
435 gtk_window_set_title(win, newtitle); |
| 295 int c, length; |
436 gaim_debug(GAIM_DEBUG_INFO, "notify.c", "quoted title\n"); |
| |
437 } |
| |
438 |
| |
439 opts |= OPT_METHOD_QUOTE; |
| |
440 g_object_set_data(G_OBJECT(widget), GDATASTR, GINT_TO_POINTER(opts)); |
| |
441 } |
| |
442 |
| |
443 static void quote_remove(GtkWidget *widget) { |
| 296 GtkWindow *win = GTK_WINDOW(widget); |
444 GtkWindow *win = GTK_WINDOW(widget); |
| 297 |
445 char newtitle[512]; |
| 298 strncpy(buf, win->title, sizeof(buf)); |
446 const gchar *curtitle = gtk_window_get_title(win); |
| 299 c = counter(buf, &length); |
447 guint opts = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), GDATASTR)); |
| 300 |
448 |
| 301 if (number) { |
449 gaim_debug(GAIM_DEBUG_INFO, "notify.c", "quote_remove(): opts=0x%04x\n", opts); |
| 302 /* This might cause problems in the future. |
450 |
| 303 I'm pretty sure if count_add is called after quote_add |
451 if (!(opts & OPT_METHOD_QUOTE)) |
| 304 and number!=0, then this will have problems dealing with |
452 return; |
| 305 the quotation marks. */ |
453 |
| 306 g_snprintf(buf, sizeof(buf), "[%d] %s", number, win->title); |
454 if (*curtitle == '\"' && strlen(curtitle)-2<sizeof(newtitle)) { |
| 307 } else if (!c) { |
455 memcpy(newtitle, curtitle+1, strlen(curtitle)-2); |
| 308 g_snprintf(buf, sizeof(buf), "[1] %s", win->title); |
456 newtitle[strlen(curtitle)-2] = 0; |
| 309 } else if (buf[0] == '[' || buf[1] == '[' ) { |
457 gtk_window_set_title(win, newtitle); |
| 310 /* This has to be so complicated in order to account for METHOD_QUOTE */ |
458 gaim_debug(GAIM_DEBUG_INFO, "notify.c", "removed quotes from title (title now %s)\n", newtitle); |
| 311 g_snprintf(buf, sizeof(buf), "[%d] %s", c+1, &win->title[ ((method & METHOD_QUOTE) ? 4 : 3)+length ]); |
459 } |
| 312 if( buf[ strlen(buf)-1 ] == '"' ) |
460 |
| 313 buf[ strlen(buf)-1 ] = '\0'; |
461 opts &= ~OPT_METHOD_QUOTE; |
| 314 } |
462 g_object_set_data(G_OBJECT(widget), GDATASTR, GINT_TO_POINTER(opts)); |
| 315 gtk_window_set_title(win, buf); |
463 } |
| 316 } |
464 |
| 317 |
465 static void urgent_add(GaimConversation *c) { |
| 318 gboolean count_remove(GtkWidget *widget) { |
|
| 319 char buf[256]; |
|
| 320 GtkWindow *win = GTK_WINDOW(widget); |
|
| 321 int length; |
|
| 322 |
|
| 323 strncpy(buf, win->title, sizeof(buf)); |
|
| 324 if (buf[0] == '[') { |
|
| 325 Number = counter(buf, &length); |
|
| 326 g_snprintf(buf, sizeof(buf), "%s", &win->title[3+length]); |
|
| 327 gtk_window_set_title(win, buf); |
|
| 328 return TRUE; |
|
| 329 } |
|
| 330 return FALSE; |
|
| 331 } |
|
| 332 |
|
| 333 void quote_add(GtkWidget *widget) { |
|
| 334 char buf[256]; |
|
| 335 GtkWindow *win = GTK_WINDOW(widget); |
|
| 336 |
|
| 337 strncpy(buf, win->title, sizeof(buf)); |
|
| 338 if (buf[0] != '\"') { |
|
| 339 g_snprintf(buf, sizeof(buf), "\"%s\"", win->title); |
|
| 340 gtk_window_set_title(win, buf); |
|
| 341 } |
|
| 342 } |
|
| 343 |
|
| 344 gboolean quote_remove(GtkWidget *widget) { |
|
| 345 char buf[256]; |
|
| 346 GtkWindow *win = GTK_WINDOW(widget); |
|
| 347 |
|
| 348 strncpy(buf, win->title, sizeof(buf)); |
|
| 349 if (buf[0] == '\"') { |
|
| 350 g_snprintf(buf, strlen(buf) - 1, "%s", &win->title[1]); |
|
| 351 gtk_window_set_title(win, buf); |
|
| 352 return TRUE; |
|
| 353 } |
|
| 354 return FALSE; |
|
| 355 } |
|
| 356 |
|
| 357 void urgent_add(GaimConversation *c) { |
|
| 358 GaimGtkWindow *gtkwin; |
466 GaimGtkWindow *gtkwin; |
| 359 XWMHints *hints; |
467 XWMHints *hints; |
| 360 |
468 |
| 361 gtkwin = GAIM_GTK_WINDOW(gaim_conversation_get_window(c)); |
469 gtkwin = GAIM_GTK_WINDOW(gaim_conversation_get_window(c)); |
| 362 |
470 |
| 406 |
521 |
| 407 hints = XGetWMHints(GDK_WINDOW_XDISPLAY(win), GDK_WINDOW_XWINDOW(win)); |
522 hints = XGetWMHints(GDK_WINDOW_XDISPLAY(win), GDK_WINDOW_XWINDOW(win)); |
| 408 if (hints->flags & XUrgencyHint) { |
523 if (hints->flags & XUrgencyHint) { |
| 409 hints->flags &= ~XUrgencyHint; |
524 hints->flags &= ~XUrgencyHint; |
| 410 XSetWMHints(GDK_WINDOW_XDISPLAY(gtkwin->window->window), GDK_WINDOW_XWINDOW(gtkwin->window->window), hints); |
525 XSetWMHints(GDK_WINDOW_XDISPLAY(gtkwin->window->window), GDK_WINDOW_XWINDOW(gtkwin->window->window), hints); |
| 411 XFree(hints); |
|
| 412 return TRUE; |
|
| 413 } |
526 } |
| 414 XFree(hints); |
527 XFree(hints); |
| 415 return FALSE; |
|
| 416 } |
528 } |
| 417 } else { |
529 } |
| 418 GaimGtkWindow *gtkwin; |
530 } |
| 419 XWMHints *hints; |
531 |
| 420 |
532 static void save_notify_prefs() { |
| 421 gtkwin = GAIM_GTK_WINDOW(gaim_conversation_get_window(c)); |
533 gaim_prefs_set_bool("/plugins/gtk/X11/notify/notify_im", notify_opts & OPT_TYPE_IM); |
| 422 hints = XGetWMHints(GDK_WINDOW_XDISPLAY(gtkwin->window->window), GDK_WINDOW_XWINDOW(gtkwin->window->window)); |
534 gaim_prefs_set_bool("/plugins/gtk/X11/notify/notify_chat", notify_opts & OPT_TYPE_CHAT); |
| 423 |
535 gaim_prefs_set_bool("/plugins/gtk/X11/notify/notify_in_focus", notify_opts & OPT_NOTIFY_IN_FOCUS); |
| 424 if (hints->flags & XUrgencyHint) { |
536 gaim_prefs_set_bool("/plugins/gtk/X11/notify/notify_focus", notify_opts & OPT_NOTIFY_FOCUS); |
| 425 hints->flags &= ~XUrgencyHint; |
537 gaim_prefs_set_bool("/plugins/gtk/X11/notify/notify_click", notify_opts & OPT_NOTIFY_CLICK); |
| 426 XSetWMHints(GDK_WINDOW_XDISPLAY(gtkwin->window->window), GDK_WINDOW_XWINDOW(gtkwin->window->window), hints); |
538 gaim_prefs_set_bool("/plugins/gtk/X11/notify/notify_type", notify_opts & OPT_NOTIFY_TYPE); |
| 427 XFree(hints); |
539 gaim_prefs_set_bool("/plugins/gtk/X11/notify/method_string", notify_opts & OPT_METHOD_STRING); |
| 428 return TRUE; |
540 gaim_prefs_set_bool("/plugins/gtk/X11/notify/method_quote", notify_opts & OPT_METHOD_QUOTE); |
| 429 } |
541 gaim_prefs_set_bool("/plugins/gtk/X11/notify/method_urgent", notify_opts & OPT_METHOD_URGENT); |
| 430 XFree(hints); |
542 gaim_prefs_set_bool("/plugins/gtk/X11/notify/method_count", notify_opts & OPT_METHOD_COUNT); |
| 431 return FALSE; |
543 |
| 432 } |
544 gaim_prefs_set_string("/plugins/gtk/X11/notify/title_string", title_string); |
| 433 } |
545 } |
| 434 |
546 |
| 435 void save_notify_prefs() { |
547 static void load_notify_prefs() { |
| 436 gchar buf[1000]; |
548 notify_opts = 0; |
| 437 FILE *fp; |
549 |
| 438 |
550 notify_opts |= (gaim_prefs_get_bool("/plugins/gtk/X11/notify/notify_im") ? OPT_TYPE_IM : 0); |
| 439 snprintf(buf, 1000, "%s/.gaim/.notify", getenv("HOME")); |
551 notify_opts |= (gaim_prefs_get_bool("/plugins/gtk/X11/notify/notify_chat") ? OPT_TYPE_CHAT : 0); |
| 440 if (!(fp = fopen(buf, "w"))) { |
552 notify_opts |= (gaim_prefs_get_bool("/plugins/gtk/X11/notify/notify_in_focus") ? OPT_NOTIFY_IN_FOCUS : 0); |
| 441 gaim_notify_error(my_plugin, NULL, |
553 notify_opts |= (gaim_prefs_get_bool("/plugins/gtk/X11/notify/notify_focus") ? OPT_NOTIFY_FOCUS : 0); |
| 442 _("Unable to write to config file"), |
554 notify_opts |= (gaim_prefs_get_bool("/plugins/gtk/X11/notify/notify_click") ? OPT_NOTIFY_CLICK : 0); |
| 443 _("Notify plugin")); |
555 notify_opts |= (gaim_prefs_get_bool("/plugins/gtk/X11/notify/notify_type") ? OPT_NOTIFY_TYPE : 0); |
| 444 return; |
556 notify_opts |= (gaim_prefs_get_bool("/plugins/gtk/X11/notify/method_string") ? OPT_METHOD_STRING : 0); |
| 445 } |
557 notify_opts |= (gaim_prefs_get_bool("/plugins/gtk/X11/notify/method_quote") ? OPT_METHOD_QUOTE : 0); |
| 446 |
558 notify_opts |= (gaim_prefs_get_bool("/plugins/gtk/X11/notify/method_urgent") ? OPT_METHOD_URGENT : 0); |
| 447 fprintf(fp, "%d=TYPE\n", type); |
559 notify_opts |= (gaim_prefs_get_bool("/plugins/gtk/X11/notify/method_count") ? OPT_METHOD_COUNT : 0); |
| 448 fprintf(fp, "%d=CHOICE\n", choice); |
560 |
| 449 fprintf(fp, "%d=METHOD\n", method); |
561 strncpy(title_string, gaim_prefs_get_string("/plugins/gtk/X11/notify/title_string"), TITLE_STR_BUFSIZE); |
| 450 fprintf(fp, "%s=STRING\n", title_string); |
562 } |
| 451 fclose(fp); |
563 |
| 452 } |
564 static void options_toggle_cb(GtkWidget *w, gpointer data) { |
| 453 |
565 gint option = GPOINTER_TO_INT(data); |
| 454 void load_notify_prefs() { |
566 |
| 455 gchar buf[1000]; |
567 notify_opts ^= option; |
| 456 gchar **parsed; |
568 |
| 457 FILE *fp; |
569 /* save prefs and re-notify the windows */ |
| 458 |
570 save_notify_prefs(); |
| 459 g_snprintf(buf, sizeof(buf), "%s/.gaim/.notify", getenv("HOME")); |
571 apply_options(option); |
| 460 if (!(fp = fopen(buf, "r"))) |
572 } |
| 461 return; |
573 |
| 462 |
574 static gboolean options_settitle_cb(GtkWidget *w, GdkEventFocus *evt, GtkWidget *entry) { |
| 463 while (fgets(buf, 1000, fp) != NULL) { |
575 GList *cnv = gaim_get_conversations(); |
| 464 parsed = g_strsplit(g_strchomp(buf), "=", 2); |
576 |
| 465 if (parsed[0] && parsed[1]) { |
577 /* first we have to kill all the old strings */ |
| 466 if (!strcmp(parsed[1], "TYPE")) |
578 while (cnv) { |
| 467 type = atoi(parsed[0]); |
579 GaimConversation *c = (GaimConversation *)cnv->data; |
| 468 if (!strcmp(parsed[1], "CHOICE")) |
580 GaimGtkWindow *gtkwin = GAIM_GTK_WINDOW(gaim_conversation_get_window(c)); |
| 469 choice = atoi(parsed[0]); |
581 string_remove(gtkwin->window); |
| 470 if (!strcmp(parsed[1], "METHOD")) |
582 cnv = cnv->next; |
| 471 method = atoi(parsed[0]); |
583 } |
| 472 if (!strcmp(parsed[1], "STRING")) { |
584 |
| 473 if (title_string != NULL) |
585 g_snprintf(title_string, sizeof(title_string), gtk_entry_get_text(GTK_ENTRY(entry))); |
| 474 g_free(title_string); |
586 |
| 475 title_string = g_strdup(parsed[0]); |
587 /* save prefs and re-notify the windows */ |
| |
588 save_notify_prefs(); |
| |
589 apply_options(OPT_METHOD_STRING_CHNG); |
| |
590 |
| |
591 return FALSE; |
| |
592 } |
| |
593 |
| |
594 static void options_toggle_title_cb(GtkWidget *w, GtkWidget *entry) { |
| |
595 notify_opts ^= OPT_METHOD_STRING; |
| |
596 |
| |
597 if (notify_opts & OPT_METHOD_STRING) |
| |
598 gtk_widget_set_sensitive(entry, TRUE); |
| |
599 else |
| |
600 gtk_widget_set_sensitive(entry, FALSE); |
| |
601 |
| |
602 save_notify_prefs(); |
| |
603 apply_options(OPT_METHOD_STRING); |
| |
604 } |
| |
605 |
| |
606 static void apply_options(int opt_chng) { |
| |
607 GList *cnv = gaim_get_conversations(); |
| |
608 |
| |
609 /* option-setting handlers should have cleared out all window notifications */ |
| |
610 |
| |
611 while (cnv) { |
| |
612 GaimConversation *c = (GaimConversation *)cnv->data; |
| |
613 GaimGtkWindow *gtkwin = GAIM_GTK_WINDOW(gaim_conversation_get_window(c)); |
| |
614 guint opts = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(gtkwin->window), GDATASTR)); |
| |
615 |
| |
616 /* kill signals */ |
| |
617 detach_signals(c); |
| |
618 |
| |
619 /* |
| |
620 * do a full notify if the option that changed was an OPT_TYPE_* |
| |
621 * either notify if it was enabled, or unnotify if it was disabled |
| |
622 */ |
| |
623 if (opt_chng==OPT_TYPE_IM || opt_chng==OPT_TYPE_CHAT) { |
| |
624 if ((gaim_conversation_get_type(c)==GAIM_CONV_IM && (notify_opts & OPT_TYPE_IM)) || |
| |
625 (gaim_conversation_get_type(c)==GAIM_CONV_CHAT && (notify_opts & OPT_TYPE_CHAT))) { |
| |
626 Window focus_return; |
| |
627 int revert_to_return; |
| |
628 |
| |
629 XGetInputFocus(GDK_WINDOW_XDISPLAY(gtkwin->window->window), |
| |
630 &focus_return, &revert_to_return); |
| |
631 if ((notify_opts & OPT_NOTIFY_IN_FOCUS) || |
| |
632 focus_return != GDK_WINDOW_XWINDOW(gtkwin->window->window)) { |
| |
633 if (notify_opts & OPT_METHOD_STRING) |
| |
634 string_add(gtkwin->window); |
| |
635 if (notify_opts & OPT_METHOD_COUNT) |
| |
636 count_add(gtkwin->window); |
| |
637 if (notify_opts & OPT_METHOD_QUOTE) |
| |
638 quote_add(gtkwin->window); |
| |
639 if (notify_opts & OPT_METHOD_URGENT) |
| |
640 urgent_add(c); |
| |
641 } |
| |
642 } else { |
| |
643 //don't simply call unnotify(), because that will kill the msg counter |
| |
644 urgent_remove(c); |
| |
645 quote_remove(gtkwin->window); |
| |
646 count_remove(gtkwin->window); |
| |
647 string_remove(gtkwin->window); |
| |
648 } |
| |
649 } else if (opts & STATE_IS_NOTIFIED) { |
| |
650 //add/remove the status that was changed |
| |
651 switch(opt_chng) { |
| |
652 case OPT_METHOD_COUNT: |
| |
653 if (notify_opts & OPT_METHOD_COUNT) |
| |
654 count_add(gtkwin->window); |
| |
655 else |
| |
656 count_remove(gtkwin->window); |
| |
657 break; |
| |
658 case OPT_METHOD_QUOTE: |
| |
659 if (notify_opts & OPT_METHOD_QUOTE) |
| |
660 quote_add(gtkwin->window); |
| |
661 else |
| |
662 quote_remove(gtkwin->window); |
| |
663 break; |
| |
664 case OPT_METHOD_STRING: |
| |
665 if (notify_opts & OPT_METHOD_STRING) |
| |
666 string_add(gtkwin->window); |
| |
667 else |
| |
668 string_remove(gtkwin->window); |
| |
669 break; |
| |
670 case OPT_METHOD_URGENT: |
| |
671 if (notify_opts & OPT_METHOD_URGENT) |
| |
672 urgent_add(c); |
| |
673 else |
| |
674 urgent_remove(c); |
| |
675 break; |
| |
676 case OPT_METHOD_STRING_CHNG: |
| |
677 string_add(gtkwin->window); |
| |
678 break; |
| 476 } |
679 } |
| 477 } |
680 } |
| 478 g_strfreev(parsed); |
|
| 479 } |
|
| 480 fclose(fp); |
|
| 481 return; |
|
| 482 } |
|
| 483 |
|
| 484 void options(GtkWidget *widget, gpointer data) { |
|
| 485 gint option = GPOINTER_TO_INT(data); |
|
| 486 |
|
| 487 if (option == 0) |
|
| 488 choice ^= NOTIFY_FOCUS; |
|
| 489 else if (option == 1) |
|
| 490 choice ^= NOTIFY_CLICK; |
|
| 491 else if (option == 2) |
|
| 492 choice ^= NOTIFY_TYPE; |
|
| 493 else if (option == 3) { |
|
| 494 method ^= METHOD_STRING; |
|
| 495 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) |
|
| 496 gtk_widget_set_sensitive(Entry, TRUE); |
|
| 497 else |
|
| 498 gtk_widget_set_sensitive(Entry, FALSE); |
|
| 499 } |
|
| 500 else if (option == 4) |
|
| 501 method ^= METHOD_QUOTE; |
|
| 502 else if (option == 5) |
|
| 503 method ^= METHOD_URGENT; |
|
| 504 else if (option == 6) |
|
| 505 choice ^= NOTIFY_IN_FOCUS; |
|
| 506 else if (option == 7) |
|
| 507 method ^= METHOD_COUNT; |
|
| 508 else if (option == 8) |
|
| 509 type ^= TYPE_IM; |
|
| 510 else if (option == 9) |
|
| 511 type ^= TYPE_CHAT; |
|
| 512 else if (option == 10) { |
|
| 513 /* I made an option for this as at least a way to have it save correctly |
|
| 514 * I'd much rather there were better ways, and I don't want to save this |
|
| 515 * no matter which pref is changed, that's too much of a hack */ |
|
| 516 if (title_string != NULL) { |
|
| 517 g_free(title_string); |
|
| 518 title_string = g_strdup(gtk_entry_get_text(GTK_ENTRY(Entry))); |
|
| 519 } |
|
| 520 } |
|
| 521 |
|
| 522 save_notify_prefs(); |
|
| 523 } |
|
| 524 |
|
| 525 void apply_options(GtkWidget *widget, gpointer data) { |
|
| 526 GList *cnv = gaim_get_conversations(); |
|
| 527 |
|
| 528 while (cnv) { |
|
| 529 guint notification; |
|
| 530 GaimConversation *c = (GaimConversation *) cnv->data; |
|
| 531 GaimGtkConversation *gtkconv; |
|
| 532 GaimGtkWindow *gtkwin; |
|
| 533 guint options = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(c->window), "notify_data")); |
|
| 534 |
|
| 535 gtkconv = GAIM_GTK_CONVERSATION(c); |
|
| 536 gtkwin = GAIM_GTK_WINDOW(gaim_conversation_get_window(c)); |
|
| 537 |
|
| 538 if (options & NOTIFY_FOCUS) |
|
| 539 g_signal_handlers_disconnect_by_func(G_OBJECT(gtkwin->window), un_star, NULL); |
|
| 540 |
|
| 541 /* remove old notification signals */ |
|
| 542 detach_signals(c); |
|
| 543 |
|
| 544 /* clean off all notification markings */ |
|
| 545 notification = unnotify(c, TRUE); |
|
| 546 |
|
| 547 /* re-add appropriate notification methods cleaned above */ |
|
| 548 if (notification & METHOD_STRING) /* re-add string */ |
|
| 549 string_add(gtkwin->window); |
|
| 550 if (notification & METHOD_QUOTE) /* re-add quote */ |
|
| 551 quote_add(gtkwin->window); |
|
| 552 if (notification & METHOD_COUNT) /* re-add count */ |
|
| 553 count_add(gtkwin->window, Number); |
|
| 554 if (notification & METHOD_URGENT) /* re-add urgent */ |
|
| 555 urgent_add(c); |
|
| 556 |
681 |
| 557 /* attach new unnotification signals */ |
682 /* attach new unnotification signals */ |
| 558 attach_signals(c); |
683 attach_signals(c); |
| 559 |
684 |
| 560 cnv = cnv->next; |
685 cnv = cnv->next; |
| 561 } |
686 } |
| 562 } |
687 } |
| 563 |
688 |
| 564 static GtkWidget * |
689 static GtkWidget * |
| 565 get_config_frame(GaimPlugin *plugin) |
690 get_config_frame(GaimPlugin *plugin) |
| 566 { |
691 { |
| 567 GtkWidget *ret; |
692 GtkWidget *ret; |
| |
693 GtkWidget *frame; |
| 568 GtkWidget *vbox, *hbox; |
694 GtkWidget *vbox, *hbox; |
| 569 GtkWidget *toggle, *button; |
695 GtkWidget *toggle, *entry; |
| |
696 |
| 570 ret = gtk_vbox_new(FALSE, 18); |
697 ret = gtk_vbox_new(FALSE, 18); |
| 571 gtk_container_set_border_width (GTK_CONTAINER (ret), 12); |
698 gtk_container_set_border_width(GTK_CONTAINER (ret), 12); |
| 572 |
699 |
| 573 vbox = gaim_gtk_make_frame(ret, _("Notify For")); |
700 /*---------- "Notify For" ----------*/ |
| |
701 frame = gaim_gtk_make_frame(ret, _("Notify For")); |
| |
702 vbox = gtk_vbox_new(FALSE, 5); |
| |
703 gtk_container_add(GTK_CONTAINER(frame), vbox); |
| |
704 |
| 574 toggle = gtk_check_button_new_with_mnemonic(_("_IM windows")); |
705 toggle = gtk_check_button_new_with_mnemonic(_("_IM windows")); |
| 575 gtk_box_pack_start(GTK_BOX(vbox), toggle, FALSE, FALSE, 0); |
706 gtk_box_pack_start(GTK_BOX(vbox), toggle, FALSE, FALSE, 0); |
| 576 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle), type & TYPE_IM); |
707 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle), notify_opts & OPT_TYPE_IM); |
| 577 g_signal_connect(G_OBJECT(toggle), "toggled", G_CALLBACK(options), GINT_TO_POINTER(8)); |
708 g_signal_connect(G_OBJECT(toggle), "toggled", G_CALLBACK(options_toggle_cb), GINT_TO_POINTER(OPT_TYPE_IM)); |
| 578 |
709 |
| 579 toggle = gtk_check_button_new_with_mnemonic(_("_Chat windows")); |
710 toggle = gtk_check_button_new_with_mnemonic(_("_Chat windows")); |
| 580 gtk_box_pack_start(GTK_BOX(vbox), toggle, FALSE, FALSE, 0); |
711 gtk_box_pack_start(GTK_BOX(vbox), toggle, FALSE, FALSE, 0); |
| 581 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle), type & TYPE_CHAT); |
712 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle), notify_opts & OPT_TYPE_CHAT); |
| 582 g_signal_connect(G_OBJECT(toggle), "toggled", G_CALLBACK(options), GINT_TO_POINTER(9)); |
713 g_signal_connect(G_OBJECT(toggle), "toggled", G_CALLBACK(options_toggle_cb), GINT_TO_POINTER(OPT_TYPE_CHAT)); |
| 583 |
714 |
| 584 /*--------------*/ |
715 /*---------- "Notification Methods" ----------*/ |
| 585 vbox = gaim_gtk_make_frame(ret, _("Notification Methods")); |
716 frame = gaim_gtk_make_frame(ret, _("Notification Methods")); |
| |
717 vbox = gtk_vbox_new(FALSE, 5); |
| |
718 gtk_container_add(GTK_CONTAINER(frame), vbox); |
| |
719 |
| 586 hbox = gtk_hbox_new(FALSE, 18); |
720 hbox = gtk_hbox_new(FALSE, 18); |
| 587 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); |
721 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); |
| 588 toggle = gtk_check_button_new_with_mnemonic(_("Prepend _string into window title (hit enter to save):")); |
722 toggle = gtk_check_button_new_with_mnemonic(_("Prepend _string into window title:")); |
| 589 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle), method & METHOD_STRING); |
723 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle), notify_opts & OPT_METHOD_STRING); |
| 590 g_signal_connect(G_OBJECT(toggle), "toggled", G_CALLBACK(options), GINT_TO_POINTER(3)); |
|
| 591 gtk_box_pack_start(GTK_BOX(hbox), toggle, FALSE, FALSE, 0); |
724 gtk_box_pack_start(GTK_BOX(hbox), toggle, FALSE, FALSE, 0); |
| 592 Entry = gtk_entry_new(); |
725 entry = gtk_entry_new(); |
| 593 gtk_entry_set_max_length(GTK_ENTRY(Entry), 10); |
726 gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, FALSE, 0); |
| 594 gtk_widget_set_sensitive(GTK_WIDGET(Entry), method & METHOD_STRING); |
727 gtk_entry_set_max_length(GTK_ENTRY(entry), 10); |
| 595 gtk_box_pack_start(GTK_BOX(hbox), Entry, FALSE, FALSE, 0); |
728 gtk_widget_set_sensitive(GTK_WIDGET(entry), notify_opts & OPT_METHOD_STRING); |
| 596 gtk_entry_set_text(GTK_ENTRY(Entry), title_string); |
729 gtk_entry_set_text(GTK_ENTRY(entry), title_string); |
| 597 g_signal_connect(G_OBJECT(Entry), "activate", G_CALLBACK(options), GINT_TO_POINTER(10)); |
730 g_signal_connect(G_OBJECT(toggle), "toggled", G_CALLBACK(options_toggle_title_cb), entry); |
| 598 |
731 g_signal_connect(G_OBJECT(entry), "focus-out-event", G_CALLBACK(options_settitle_cb), entry); |
| 599 toggle = gtk_check_button_new_with_mnemonic(_("_Quote window title")); |
732 |
| 600 gtk_box_pack_start(GTK_BOX(vbox), toggle, FALSE, FALSE, 0); |
733 toggle = gtk_check_button_new_with_mnemonic(_("_Quote window title")); |
| 601 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle), method & METHOD_QUOTE); |
734 gtk_box_pack_start(GTK_BOX(vbox), toggle, FALSE, FALSE, 0); |
| 602 g_signal_connect(G_OBJECT(toggle), "toggled", G_CALLBACK(options), GINT_TO_POINTER(4)); |
735 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle), notify_opts & OPT_METHOD_QUOTE); |
| 603 |
736 g_signal_connect(G_OBJECT(toggle), "toggled", G_CALLBACK(options_toggle_cb), GINT_TO_POINTER(OPT_METHOD_QUOTE)); |
| 604 toggle = gtk_check_button_new_with_mnemonic(_("Set Window Manager \"_URGENT\" Hint")); |
737 |
| 605 gtk_box_pack_start(GTK_BOX(vbox), toggle, FALSE, FALSE, 0); |
738 toggle = gtk_check_button_new_with_mnemonic(_("Set Window Manager \"_URGENT\" Hint")); |
| 606 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle), method & METHOD_URGENT); |
739 gtk_box_pack_start(GTK_BOX(vbox), toggle, FALSE, FALSE, 0); |
| 607 g_signal_connect(G_OBJECT(toggle), "toggled", G_CALLBACK(options), GINT_TO_POINTER(5)); |
740 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle), notify_opts & OPT_METHOD_URGENT); |
| 608 |
741 g_signal_connect(G_OBJECT(toggle), "toggled", G_CALLBACK(options_toggle_cb), GINT_TO_POINTER(OPT_METHOD_URGENT)); |
| 609 toggle = gtk_check_button_new_with_mnemonic(_("Insert c_ount of new messages into window title")); |
742 |
| 610 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle), method & METHOD_COUNT); |
743 toggle = gtk_check_button_new_with_mnemonic(_("Insert c_ount of new messages into window title")); |
| 611 gtk_box_pack_start(GTK_BOX(vbox), toggle, FALSE, FALSE, 0); |
744 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle), notify_opts & OPT_METHOD_COUNT); |
| 612 g_signal_connect(G_OBJECT(toggle), "toggled", G_CALLBACK(options), GINT_TO_POINTER(7)); |
745 gtk_box_pack_start(GTK_BOX(vbox), toggle, FALSE, FALSE, 0); |
| 613 |
746 g_signal_connect(G_OBJECT(toggle), "toggled", G_CALLBACK(options_toggle_cb), GINT_TO_POINTER(OPT_METHOD_COUNT)); |
| 614 toggle = gtk_check_button_new_with_mnemonic(_("_Notify even if conversation is in focus")); |
747 |
| 615 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle), choice & NOTIFY_IN_FOCUS); |
748 toggle = gtk_check_button_new_with_mnemonic(_("_Notify even if conversation is in focus")); |
| 616 gtk_box_pack_start(GTK_BOX(vbox), toggle, FALSE, FALSE, 0); |
749 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle), notify_opts & OPT_NOTIFY_IN_FOCUS); |
| 617 g_signal_connect(G_OBJECT(toggle), "toggled", G_CALLBACK(options), GINT_TO_POINTER(6)); |
750 gtk_box_pack_start(GTK_BOX(vbox), toggle, FALSE, FALSE, 0); |
| 618 |
751 g_signal_connect(G_OBJECT(toggle), "toggled", G_CALLBACK(options_toggle_cb), GINT_TO_POINTER(OPT_NOTIFY_IN_FOCUS)); |
| 619 /*--------------*/ |
752 |
| 620 vbox = gaim_gtk_make_frame(ret, _("Notification Removal")); |
753 /*---------- "Notification Methods" ----------*/ |
| 621 toggle = gtk_check_button_new_with_mnemonic(_("Remove when conversation window gains _focus")); |
754 frame = gaim_gtk_make_frame(ret, _("Notification Removal")); |
| 622 gtk_box_pack_start(GTK_BOX(vbox), toggle, FALSE, FALSE, 0); |
755 vbox = gtk_vbox_new(FALSE, 5); |
| 623 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle), choice & NOTIFY_FOCUS); |
756 gtk_container_add(GTK_CONTAINER(frame), vbox); |
| 624 g_signal_connect(G_OBJECT(toggle), "toggled", G_CALLBACK(options), GINT_TO_POINTER(0)); |
757 |
| 625 |
758 toggle = gtk_check_button_new_with_mnemonic(_("Remove when conversation window gains _focus")); |
| 626 toggle = gtk_check_button_new_with_mnemonic(_("Remove when conversation window _receives click")); |
759 gtk_box_pack_start(GTK_BOX(vbox), toggle, FALSE, FALSE, 0); |
| 627 gtk_box_pack_start(GTK_BOX(vbox), toggle, FALSE, FALSE, 0); |
760 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle), notify_opts & OPT_NOTIFY_FOCUS); |
| 628 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle), choice & NOTIFY_CLICK); |
761 g_signal_connect(G_OBJECT(toggle), "toggled", G_CALLBACK(options_toggle_cb), GINT_TO_POINTER(OPT_NOTIFY_FOCUS)); |
| 629 g_signal_connect(G_OBJECT(toggle), "toggled", G_CALLBACK(options), GINT_TO_POINTER(1)); |
762 |
| 630 |
763 toggle = gtk_check_button_new_with_mnemonic(_("Remove when conversation window _receives click")); |
| 631 toggle = gtk_check_button_new_with_mnemonic(_("Remove when _typing in conversation window")); |
764 gtk_box_pack_start(GTK_BOX(vbox), toggle, FALSE, FALSE, 0); |
| 632 gtk_box_pack_start(GTK_BOX(vbox), toggle, FALSE, FALSE, 0); |
765 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle), notify_opts & OPT_NOTIFY_CLICK); |
| 633 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle), choice & NOTIFY_TYPE); |
766 g_signal_connect(G_OBJECT(toggle), "toggled", G_CALLBACK(options_toggle_cb), GINT_TO_POINTER(OPT_NOTIFY_CLICK)); |
| 634 g_signal_connect(G_OBJECT(toggle), "toggled", G_CALLBACK(options), GINT_TO_POINTER(2)); |
767 |
| 635 |
768 toggle = gtk_check_button_new_with_mnemonic(_("Remove when _typing in conversation window")); |
| 636 button = gtk_button_new_with_mnemonic(_("Appl_y")); |
769 gtk_box_pack_start(GTK_BOX(vbox), toggle, FALSE, FALSE, 0); |
| 637 gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 5); |
770 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle), notify_opts & OPT_NOTIFY_TYPE); |
| 638 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(apply_options), NULL); |
771 g_signal_connect(G_OBJECT(toggle), "toggled", G_CALLBACK(options_toggle_cb), GINT_TO_POINTER(OPT_NOTIFY_TYPE)); |
| 639 |
772 |
| 640 gtk_widget_show_all(ret); |
773 gtk_widget_show_all(ret); |
| 641 return ret; |
774 return ret; |
| 642 } |
775 } |
| 643 |
776 |
| 644 static gboolean |
777 static gboolean |
| 645 plugin_load(GaimPlugin *plugin) |
778 plugin_load(GaimPlugin *plugin) |
| 646 { |
779 { |
| 647 title_string = g_strdup("(*) "); |
780 GList *cnv = gaim_get_conversations(); |
| |
781 |
| |
782 my_plugin = plugin; |
| 648 |
783 |
| 649 load_notify_prefs(); |
784 load_notify_prefs(); |
| 650 |
785 |
| 651 gaim_signal_connect(plugin, event_im_recv, im_recv_im, NULL); |
786 gaim_signal_connect(plugin, event_im_recv, im_recv_im, NULL); |
| 652 gaim_signal_connect(plugin, event_chat_recv, chat_recv_im, NULL); |
787 gaim_signal_connect(plugin, event_chat_recv, chat_recv_im, NULL); |
| 653 gaim_signal_connect(plugin, event_im_send, im_sent_im, NULL); |
788 gaim_signal_connect(plugin, event_im_send, im_sent_im, NULL); |
| 654 gaim_signal_connect(plugin, event_chat_send, chat_sent_im, NULL); |
789 gaim_signal_connect(plugin, event_chat_send, chat_sent_im, NULL); |
| 655 gaim_signal_connect(plugin, event_new_conversation, new_conv, NULL); |
790 gaim_signal_connect(plugin, event_new_conversation, new_conv, NULL); |
| 656 gaim_signal_connect(plugin, event_chat_join, chat_join, NULL); |
791 gaim_signal_connect(plugin, event_chat_join, chat_join, NULL); |
| 657 |
792 |
| |
793 while (cnv) { |
| |
794 GaimConversation *c = (GaimConversation *)cnv->data; |
| |
795 GaimGtkWindow *gtkwin = GAIM_GTK_WINDOW(gaim_conversation_get_window(c)); |
| |
796 |
| |
797 /* attach signals */ |
| |
798 attach_signals(c); |
| |
799 /* zero out data */ |
| |
800 g_object_set_data(G_OBJECT(gtkwin->window), GDATASTR, GINT_TO_POINTER((guint)0)); |
| |
801 g_object_set_data(G_OBJECT(gtkwin->window), GDATASTRCNT, GINT_TO_POINTER((guint)0)); |
| |
802 |
| |
803 cnv = cnv->next; |
| |
804 } |
| |
805 |
| 658 return TRUE; |
806 return TRUE; |
| 659 } |
807 } |
| 660 |
808 |
| 661 static gboolean |
809 static gboolean |
| 662 plugin_unload(GaimPlugin *plugin) |
810 plugin_unload(GaimPlugin *plugin) |
| 663 { |
811 { |
| 664 GList *c = gaim_get_conversations(); |
812 GList *cnv = gaim_get_conversations(); |
| 665 |
813 |
| 666 while (c) { |
814 while (cnv) { |
| 667 GaimConversation *cnv = (GaimConversation *)c->data; |
815 GaimConversation *c = (GaimConversation *)cnv->data; |
| 668 GaimGtkWindow *gtkwin; |
816 GaimGtkWindow *gtkwin = GAIM_GTK_WINDOW(gaim_conversation_get_window(c)); |
| 669 |
817 |
| 670 gtkwin = GAIM_GTK_WINDOW(gaim_conversation_get_window(cnv)); |
818 /* kill signals */ |
| 671 |
819 detach_signals(c); |
| 672 detach_signals(cnv); |
820 /* zero out data */ |
| 673 un_star(gtkwin->window, NULL); |
821 g_object_set_data(G_OBJECT(gtkwin->window), GDATASTR, GINT_TO_POINTER((guint)0)); |
| 674 |
822 g_object_set_data(G_OBJECT(gtkwin->window), GDATASTRCNT, GINT_TO_POINTER((guint)0)); |
| 675 c = c->next; |
823 |
| 676 } |
824 cnv = cnv->next; |
| 677 |
825 } |
| 678 /* this might be a hack I'm not sure, I don't think so but... */ |
|
| 679 g_free(title_string); |
|
| 680 |
826 |
| 681 return TRUE; |
827 return TRUE; |
| 682 } |
828 } |
| 683 |
829 |
| 684 static GaimGtkPluginUiInfo ui_info = |
830 static GaimGtkPluginUiInfo ui_info = |