Mercurial > pidgin.yaz
annotate src/gtkconv.c @ 4681:efa194b5caaf
[gaim-migrate @ 4992]
Set the title of the conversation window to be the same as the tab label,
because that's the cool thing to do.
For the moment, this will suffer from the same problem as the tabs that are
red when they shouldn't be. I hope to get all of that fixed this weekend.
I define "this weekend" as "before I go to class on Monday", just like Sean
defines "tonight" as "before he goes to bed" ;-)
committer: Tailor Script <tailor@pidgin.im>
author | Nathan Walp <nwalp@pidgin.im> |
---|---|
date | Sun, 09 Mar 2003 08:20:51 +0000 |
parents | 7ffe2b64de2d |
children | 794cc8ec1166 |
rev | line source |
---|---|
4359 | 1 /* |
2 * gaim | |
3 * | |
4 * Copyright (C) 2002-2003, Christian Hammond <chipx86@gnupdate.org> | |
5 * | |
6 * This program is free software; you can redistribute it and/or modify | |
7 * it under the terms of the GNU General Public License as published by | |
8 * the Free Software Foundation; either version 2 of the License, or | |
9 * (at your option) any later version. | |
10 * | |
11 * This program is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 * GNU General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License | |
17 * along with this program; if not, write to the Free Software | |
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 * | |
20 */ | |
21 #ifdef HAVE_CONFIG_H | |
22 #include <config.h> | |
23 #endif | |
24 #include <string.h> | |
25 #ifndef _WIN32 | |
26 #include <sys/time.h> | |
27 #include <unistd.h> | |
28 #include <gdk/gdkx.h> | |
29 #include <X11/Xlib.h> | |
30 #endif /*_WIN32*/ | |
31 #include <sys/types.h> | |
32 #include <sys/stat.h> | |
33 #include <stdio.h> | |
34 #include <stdlib.h> | |
35 #include <errno.h> | |
36 #include <ctype.h> | |
37 #include <gtk/gtk.h> | |
38 #ifdef USE_GTKSPELL | |
39 #include <gtkspell/gtkspell.h> | |
40 #endif | |
41 #include "gtkimhtml.h" | |
42 #include <gdk/gdkkeysyms.h> | |
43 #include "prpl.h" | |
44 #include "gtkimhtml.h" | |
45 #include "dnd-hints.h" | |
4561 | 46 #include "sound.h" |
4359 | 47 |
4373
dcc6c130c6d9
[gaim-migrate @ 4639]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
4370
diff
changeset
|
48 #ifdef _WIN32 |
dcc6c130c6d9
[gaim-migrate @ 4639]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
4370
diff
changeset
|
49 #include "win32dep.h" |
dcc6c130c6d9
[gaim-migrate @ 4639]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
4370
diff
changeset
|
50 #endif |
dcc6c130c6d9
[gaim-migrate @ 4639]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
4370
diff
changeset
|
51 |
4359 | 52 static char nick_colors[][8] = { |
53 "#ba55d3", /* Medium Orchid */ | |
54 "#ee82ee", /* Violet */ | |
55 "#c715b4", /* Medium Violet Red */ | |
56 "#ff69b4", /* Hot Pink */ | |
57 "#ff6347", /* Tomato */ | |
58 "#fa8c00", /* Dark Orange */ | |
59 "#fa8072", /* Salmon */ | |
60 "#b22222", /* Fire Brick */ | |
61 "#f4a460", /* Sandy Brown */ | |
62 "#cd5c5c", /* Indian Red */ | |
63 "#bc8f8f", /* Rosy Brown */ | |
64 "#f0e68c", /* Khaki */ | |
65 "#bdb76b", /* Dark Khaki */ | |
66 "#228b22", /* Forest Green */ | |
67 "#9acd32", /* Yellow Green */ | |
68 "#32cd32", /* Lime Green */ | |
69 "#3cb371", /* Medium Sea Green */ | |
70 "#2e8b57", /* Sea Green */ | |
71 "#8fbc8f", /* Dark Sea Green */ | |
72 "#66cdaa", /* Medium Aquamarine */ | |
73 "#5f9ea0", /* Cadet Blue */ | |
74 "#48d1cc", /* Medium Turquoise */ | |
75 "#00ced1", /* Dark Turquoise */ | |
76 "#4682b4", /* Stell Blue */ | |
77 "#00bfff", /* Deep Sky Blue */ | |
78 "#1690ff", /* Dodger Blue */ | |
79 "#4169ff", /* Royal Blue */ | |
80 "#6a5acd", /* Slate Blue */ | |
81 "#6495ed", /* Cornflower Blue */ | |
82 "#708090", /* Slate gray */ | |
83 "#ffdead", /* Navajo White */ | |
84 }; | |
85 #define NUM_NICK_COLORS (sizeof(nick_colors) / sizeof(*nick_colors)) | |
86 | |
87 #define SCALE(x) \ | |
88 ((gdk_pixbuf_animation_get_width(x) <= 48 && \ | |
89 gdk_pixbuf_animation_get_height(x) <= 48) ? 48 : 50) | |
90 | |
91 struct InviteBuddyInfo | |
92 { | |
93 GtkWidget *window; | |
94 | |
95 GtkWidget *entry; | |
96 GtkWidget *message; | |
97 | |
98 struct gaim_conversation *conv; | |
99 }; | |
100 | |
101 char fontface[128] = { 0 }; | |
102 int fontsize = 3; | |
103 | |
104 static GtkWidget *invite_dialog = NULL; | |
105 | |
106 static volatile gboolean state_lock = FALSE; | |
107 | |
108 /* Prototypes. <-- because Paco-Paco hates this comment. */ | |
109 static void check_everything(GtkTextBuffer *buffer); | |
110 static void quiet_set(GtkWidget *tb, gboolean active); | |
111 static void move_next_tab(struct gaim_conversation *conv); | |
112 static void do_bold(GtkWidget *bold, struct gaim_gtk_conversation *gtkconv); | |
113 static void do_italic(GtkWidget *italic, struct gaim_gtk_conversation *gtkconv); | |
114 static void do_underline(GtkWidget *underline, struct gaim_gtk_conversation *gtkconv); | |
115 static void do_small(GtkWidget *small, struct gaim_gtk_conversation *gtkconv); | |
116 static void do_normal(GtkWidget *small, struct gaim_gtk_conversation *gtkconv); | |
117 static void do_big(GtkWidget *small, struct gaim_gtk_conversation *gtkconv); | |
118 static void toggle_font(GtkWidget *font, struct gaim_conversation *conv); | |
119 static void toggle_fg_color(GtkWidget *color, struct gaim_conversation *conv); | |
120 static void toggle_bg_color(GtkWidget *color, struct gaim_conversation *conv); | |
121 static void got_typing_keypress(struct gaim_conversation *conv, gboolean first); | |
122 static GList *generate_invite_user_names(struct gaim_connection *gc); | |
123 static void add_chat_buddy_common(struct gaim_conversation *conv, | |
124 const char *name, int pos); | |
125 static void tab_complete(struct gaim_conversation *conv); | |
126 static void update_send_as_selection(struct gaim_window *win); | |
4602
4128761bacb8
[gaim-migrate @ 4889]
Christian Hammond <chipx86@chipx86.com>
parents:
4598
diff
changeset
|
127 static char *item_factory_translate_func (const char *path, gpointer func_data); |
4359 | 128 |
129 /************************************************************************** | |
130 * Callbacks | |
131 **************************************************************************/ | |
132 static void | |
133 do_insert_image_cb(GObject *obj, GtkWidget *wid) | |
134 { | |
135 struct gaim_conversation *conv; | |
136 struct gaim_gtk_conversation *gtkconv; | |
137 struct gaim_im *im; | |
138 const char *name; | |
139 const char *filename; | |
140 char *buf; | |
141 struct stat st; | |
142 int id; | |
143 | |
144 conv = g_object_get_data(obj, "user_data"); | |
145 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
146 im = GAIM_IM(conv); | |
147 name = gtk_file_selection_get_filename(GTK_FILE_SELECTION(wid)); | |
148 id = g_slist_length(im->images) + 1; | |
149 | |
150 if (file_is_dir(name, wid)) | |
151 return; | |
152 | |
153 gtk_widget_destroy(wid); | |
154 | |
155 if (!name) | |
156 return; | |
157 | |
158 if (stat(name, &st) != 0) { | |
159 debug_printf("Could not stat %s\n", name); | |
160 return; | |
161 } | |
162 | |
163 filename = name; | |
164 while (strchr(filename, '/')) | |
165 filename = strchr(filename, '/') + 1; | |
166 | |
167 buf = g_strdup_printf("<IMG SRC=\"file://%s\" ID=\"%d\" DATASIZE=\"%d\">", | |
168 filename, id, (int)st.st_size); | |
169 im->images = g_slist_append(im->images, g_strdup(name)); | |
170 gtk_text_buffer_insert_at_cursor(GTK_TEXT_BUFFER(gtkconv->entry_buffer), | |
171 buf, -1); | |
172 g_free(buf); | |
173 } | |
174 | |
175 static gint | |
176 close_win_cb(GtkWidget *w, GdkEventAny *e, gpointer d) | |
177 { | |
178 struct gaim_window *win = (struct gaim_window *)d; | |
179 | |
180 gaim_window_destroy(win); | |
4361
25d5b2a7545f
[gaim-migrate @ 4627]
Christian Hammond <chipx86@chipx86.com>
parents:
4360
diff
changeset
|
181 |
25d5b2a7545f
[gaim-migrate @ 4627]
Christian Hammond <chipx86@chipx86.com>
parents:
4360
diff
changeset
|
182 return TRUE; |
4359 | 183 } |
184 | |
185 static gint | |
186 close_conv_cb(GtkWidget *w, gpointer d) | |
187 { | |
188 struct gaim_conversation *conv = (struct gaim_conversation *)d; | |
189 | |
190 gaim_conversation_destroy(conv); | |
4361
25d5b2a7545f
[gaim-migrate @ 4627]
Christian Hammond <chipx86@chipx86.com>
parents:
4360
diff
changeset
|
191 |
25d5b2a7545f
[gaim-migrate @ 4627]
Christian Hammond <chipx86@chipx86.com>
parents:
4360
diff
changeset
|
192 return TRUE; |
4359 | 193 } |
194 | |
195 static void | |
196 insert_image_cb(GtkWidget *save, struct gaim_conversation *conv) | |
197 { | |
198 struct gaim_gtk_conversation *gtkconv; | |
199 char buf[BUF_LONG]; | |
200 GtkWidget *window; | |
201 | |
202 if (gaim_gtk_is_state_locked()) | |
203 return; | |
204 | |
205 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
206 | |
207 window = gtk_file_selection_new(_("Gaim - Insert Image")); | |
208 g_snprintf(buf, sizeof(buf), "%s" G_DIR_SEPARATOR_S, gaim_home_dir()); | |
209 gtk_file_selection_set_filename(GTK_FILE_SELECTION(window), buf); | |
210 | |
211 g_object_set_data(G_OBJECT(GTK_FILE_SELECTION(window)->ok_button), | |
212 "user_data", conv); | |
213 g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(window)->ok_button), | |
214 "clicked", G_CALLBACK(do_insert_image_cb), window); | |
215 g_signal_connect_swapped( | |
216 G_OBJECT(GTK_FILE_SELECTION(window)->cancel_button), | |
217 "clicked", G_CALLBACK(gtk_widget_destroy), window); | |
218 | |
219 gtk_widget_show(window); | |
220 | |
221 gaim_gtk_set_state_lock(TRUE); | |
4635 | 222 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtkconv->toolbar.image), |
4359 | 223 FALSE); |
224 gaim_gtk_set_state_lock(FALSE); | |
225 } | |
226 | |
227 static void | |
228 insert_link_cb(GtkWidget *w, struct gaim_conversation *conv) | |
229 { | |
230 struct gaim_gtk_conversation *gtkconv; | |
231 | |
232 if (gaim_gtk_is_state_locked()) | |
233 return; | |
234 | |
235 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
236 | |
237 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gtkconv->toolbar.link))) | |
238 show_insert_link(gtkconv->toolbar.link, conv); | |
239 else if (gtkconv->dialogs.link) | |
240 cancel_link(gtkconv->toolbar.link, conv); | |
241 else | |
242 gaim_gtk_advance_past(gtkconv, "<A HREF>", "</A>"); | |
243 | |
244 gtk_widget_grab_focus(gtkconv->entry); | |
245 } | |
246 | |
247 static void | |
248 insert_smiley_cb(GtkWidget *smiley, struct gaim_conversation *conv) | |
249 { | |
250 struct gaim_gtk_conversation *gtkconv; | |
251 | |
252 if (gaim_gtk_is_state_locked()) | |
253 return; | |
254 | |
255 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
256 | |
257 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(smiley))) | |
258 show_smiley_dialog(conv, smiley); | |
259 else if (gtkconv->dialogs.smiley) | |
260 close_smiley_dialog(smiley, conv); | |
261 | |
262 gtk_widget_grab_focus(gtkconv->entry); | |
263 } | |
264 | |
265 static void | |
266 menu_save_as_cb(gpointer data, guint action, GtkWidget *widget) | |
267 { | |
268 struct gaim_window *win = (struct gaim_window *)data; | |
269 | |
270 save_convo(NULL, gaim_window_get_active_conversation(win)); | |
271 } | |
272 | |
273 static void | |
274 menu_view_history_cb(gpointer data, guint action, GtkWidget *widget) | |
275 { | |
276 struct gaim_window *win = (struct gaim_window *)data; | |
4387
a3fd5fe57a0b
[gaim-migrate @ 4653]
Christian Hammond <chipx86@chipx86.com>
parents:
4383
diff
changeset
|
277 struct gaim_conversation *conv; |
a3fd5fe57a0b
[gaim-migrate @ 4653]
Christian Hammond <chipx86@chipx86.com>
parents:
4383
diff
changeset
|
278 |
a3fd5fe57a0b
[gaim-migrate @ 4653]
Christian Hammond <chipx86@chipx86.com>
parents:
4383
diff
changeset
|
279 conv = gaim_window_get_active_conversation(win); |
a3fd5fe57a0b
[gaim-migrate @ 4653]
Christian Hammond <chipx86@chipx86.com>
parents:
4383
diff
changeset
|
280 |
a3fd5fe57a0b
[gaim-migrate @ 4653]
Christian Hammond <chipx86@chipx86.com>
parents:
4383
diff
changeset
|
281 conv_show_log(NULL, (char *)gaim_conversation_get_name(conv)); |
4359 | 282 } |
283 static void | |
284 menu_insert_link_cb(gpointer data, guint action, GtkWidget *widget) | |
285 { | |
286 struct gaim_window *win = (struct gaim_window *)data; | |
287 struct gaim_conversation *conv; | |
288 struct gaim_gtk_conversation *gtkconv; | |
289 | |
290 conv = gaim_window_get_active_conversation(win); | |
291 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
292 | |
293 show_insert_link(gtkconv->toolbar.link, conv); | |
294 } | |
295 | |
296 static void | |
297 menu_insert_image_cb(gpointer data, guint action, GtkWidget *widget) | |
298 { | |
299 struct gaim_window *win = (struct gaim_window *)data; | |
300 | |
301 insert_image_cb(NULL, gaim_window_get_active_conversation(win)); | |
302 } | |
303 | |
304 static void | |
305 menu_close_conv_cb(gpointer data, guint action, GtkWidget *widget) | |
306 { | |
307 struct gaim_window *win = (struct gaim_window *)data; | |
308 | |
309 close_conv_cb(NULL, gaim_window_get_active_conversation(win)); | |
310 } | |
311 | |
312 static void | |
313 menu_logging_cb(gpointer data, guint action, GtkWidget *widget) | |
314 { | |
315 struct gaim_window *win = (struct gaim_window *)data; | |
316 struct gaim_conversation *conv; | |
317 | |
318 if (gaim_gtk_is_state_locked()) | |
319 return; | |
320 | |
321 conv = gaim_window_get_active_conversation(win); | |
322 | |
323 gaim_conversation_set_logging(conv, !gaim_conversation_is_logging(conv)); | |
324 } | |
325 | |
326 static void | |
327 menu_sounds_cb(gpointer data, guint action, GtkWidget *widget) | |
328 { | |
329 struct gaim_window *win = (struct gaim_window *)data; | |
330 struct gaim_conversation *conv; | |
331 struct gaim_gtk_conversation *gtkconv; | |
332 | |
333 if (gaim_gtk_is_state_locked()) | |
334 return; | |
335 | |
336 conv = gaim_window_get_active_conversation(win); | |
337 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
338 | |
339 gtkconv->make_sound = !gtkconv->make_sound; | |
340 } | |
341 | |
342 static gboolean | |
343 entry_key_pressed_cb_1(GtkTextBuffer *buffer) | |
344 { | |
345 check_everything(buffer); | |
346 | |
347 return FALSE; | |
348 } | |
349 | |
350 static void | |
351 send_cb(GtkWidget *widget, struct gaim_conversation *conv) | |
352 { | |
353 struct gaim_gtk_conversation *gtkconv; | |
354 char *buf, *buf2; | |
355 GtkTextIter start_iter, end_iter; | |
356 int limit; | |
4505 | 357 struct gaim_connection *gc = gaim_conversation_get_gc(conv); |
4359 | 358 |
359 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
360 | |
361 gtk_text_buffer_get_start_iter(gtkconv->entry_buffer, &start_iter); | |
362 gtk_text_buffer_get_end_iter(gtkconv->entry_buffer, &end_iter); | |
363 buf2 = gtk_text_buffer_get_text(gtkconv->entry_buffer, | |
364 &start_iter, &end_iter, FALSE); | |
365 | |
366 quiet_set(gtkconv->toolbar.bold, FALSE); | |
367 quiet_set(gtkconv->toolbar.italic, FALSE); | |
368 quiet_set(gtkconv->toolbar.underline, FALSE); | |
369 quiet_set(gtkconv->toolbar.normal_size, FALSE); | |
370 quiet_set(gtkconv->toolbar.fgcolor, FALSE); | |
371 quiet_set(gtkconv->toolbar.bgcolor, FALSE); | |
372 quiet_set(gtkconv->toolbar.link, FALSE); | |
373 | |
374 gtk_widget_grab_focus(gtkconv->entry); | |
375 | |
376 limit = 32 * 1024; /* This will be done again in gaim_im_send. *shrug* */ | |
377 | |
378 buf = g_malloc(limit); | |
379 strncpy(buf, buf2, limit); | |
380 | |
381 g_free(buf2); | |
382 | |
383 if (strlen(buf) == 0) { | |
384 g_free(buf); | |
385 | |
386 return; | |
387 } | |
388 | |
389 buf2 = g_malloc(limit); | |
390 | |
4505 | 391 if (gc && gc->flags & OPT_CONN_HTML) { |
4359 | 392 if (font_options & OPT_FONT_BOLD) { |
393 g_snprintf(buf2, limit, "<B>%s</B>", buf); | |
394 strcpy(buf, buf2); | |
395 } | |
396 | |
397 if (font_options & OPT_FONT_ITALIC) { | |
398 g_snprintf(buf2, limit, "<I>%s</I>", buf); | |
399 strcpy(buf, buf2); | |
400 } | |
401 | |
402 if (font_options & OPT_FONT_UNDERLINE) { | |
403 g_snprintf(buf2, limit, "<U>%s</U>", buf); | |
404 strcpy(buf, buf2); | |
405 } | |
406 | |
407 if (font_options & OPT_FONT_STRIKE) { | |
408 g_snprintf(buf2, limit, "<STRIKE>%s</STRIKE>", buf); | |
409 strcpy(buf, buf2); | |
410 } | |
411 | |
412 if ((font_options & OPT_FONT_FACE) || gtkconv->has_font) { | |
413 g_snprintf(buf2, limit, | |
414 "<FONT FACE=\"%s\">%s</FONT>", gtkconv->fontface, buf); | |
415 strcpy(buf, buf2); | |
416 } | |
417 | |
418 if (font_options & OPT_FONT_SIZE) { | |
419 g_snprintf(buf2, limit, | |
420 "<FONT SIZE=\"%d\">%s</FONT>", fontsize, buf); | |
421 strcpy(buf, buf2); | |
422 } | |
423 | |
4421 | 424 if (font_options & OPT_FONT_FGCOL) { |
4359 | 425 g_snprintf(buf2, limit, |
426 "<FONT COLOR=\"#%02X%02X%02X\">%s</FONT>", | |
427 gtkconv->fg_color.red / 256, | |
428 gtkconv->fg_color.green / 256, | |
429 gtkconv->fg_color.blue / 256, buf); | |
430 strcpy(buf, buf2); | |
431 } | |
432 | |
4421 | 433 if (font_options & OPT_FONT_BGCOL) { |
4359 | 434 g_snprintf(buf2, limit, |
435 "<BODY BGCOLOR=\"#%02X%02X%02X\">%s</BODY>", | |
4421 | 436 gtkconv->bg_color.red / 256, |
437 gtkconv->bg_color.green / 256, | |
438 gtkconv->bg_color.blue / 256, buf); | |
4359 | 439 strcpy(buf, buf2); |
440 } | |
441 } | |
442 | |
443 g_free(buf2); | |
444 | |
445 if (gaim_conversation_get_type(conv) == GAIM_CONV_IM) | |
446 gaim_im_send(GAIM_IM(conv), buf); | |
447 else | |
448 gaim_chat_send(GAIM_CHAT(conv), buf); | |
449 | |
450 g_free(buf); | |
451 | |
452 gtk_text_buffer_set_text(gtkconv->entry_buffer, "", -1); | |
453 } | |
454 | |
455 static void | |
456 add_cb(GtkWidget *widget, struct gaim_conversation *conv) | |
457 { | |
458 struct gaim_connection *gc; | |
459 struct buddy *b; | |
460 const char *name; | |
461 | |
462 gc = gaim_conversation_get_gc(conv); | |
463 name = gaim_conversation_get_name(conv); | |
4491 | 464 b = find_buddy(gc->account, name); |
4359 | 465 |
466 if (b != NULL) | |
467 show_confirm_del(gc, (char *)name); | |
468 else if (gc != NULL) | |
469 show_add_buddy(gc, (char *)name, NULL, NULL); | |
470 | |
471 gtk_widget_grab_focus(GAIM_GTK_CONVERSATION(conv)->entry); | |
472 } | |
473 | |
474 static void | |
475 info_cb(GtkWidget *widget, struct gaim_conversation *conv) | |
476 { | |
477 struct gaim_gtk_conversation *gtkconv; | |
478 | |
479 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
480 | |
481 if (gaim_conversation_get_type(conv) == GAIM_CONV_CHAT) { | |
482 struct gaim_gtk_chat_pane *gtkchat; | |
483 GtkTreeIter iter; | |
484 GtkTreeModel *model; | |
485 GtkTreeSelection *sel; | |
486 const char *name; | |
487 | |
488 gtkchat = gtkconv->u.chat; | |
489 | |
490 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); | |
491 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkchat->list)); | |
492 | |
493 if (gtk_tree_selection_get_selected(sel, NULL, &iter)) | |
494 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 1, &name, -1); | |
495 else | |
496 return; | |
497 | |
498 serv_get_info(gaim_conversation_get_gc(conv), (char *)name); | |
499 } | |
500 else { | |
501 serv_get_info(gaim_conversation_get_gc(conv), | |
502 (char *)gaim_conversation_get_name(conv)); | |
503 | |
504 gtk_widget_grab_focus(gtkconv->entry); | |
505 } | |
506 } | |
507 | |
508 static void | |
509 warn_cb(GtkWidget *widget, struct gaim_conversation *conv) | |
510 { | |
511 show_warn_dialog(gaim_conversation_get_gc(conv), | |
512 (char *)gaim_conversation_get_name(conv)); | |
513 | |
514 gtk_widget_grab_focus(GAIM_GTK_CONVERSATION(conv)->entry); | |
515 } | |
516 | |
517 static void | |
518 block_cb(GtkWidget *widget, struct gaim_conversation *conv) | |
519 { | |
520 struct gaim_connection *gc; | |
521 | |
522 gc = gaim_conversation_get_gc(conv); | |
523 | |
524 if (gc != NULL) | |
525 show_add_perm(gc, (char *)gaim_conversation_get_name(conv), FALSE); | |
526 | |
527 gtk_widget_grab_focus(GAIM_GTK_CONVERSATION(conv)->entry); | |
528 } | |
529 | |
530 void | |
531 im_cb(GtkWidget *widget, struct gaim_conversation *conv) | |
532 { | |
533 struct gaim_conversation *conv2; | |
534 struct gaim_gtk_conversation *gtkconv; | |
535 struct gaim_gtk_chat_pane *gtkchat; | |
4491 | 536 struct gaim_account *account; |
4359 | 537 GtkTreeIter iter; |
538 GtkTreeModel *model; | |
539 GtkTreeSelection *sel; | |
540 const char *name; | |
541 | |
542 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
543 gtkchat = gtkconv->u.chat; | |
544 | |
545 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); | |
546 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkchat->list)); | |
547 | |
548 if (gtk_tree_selection_get_selected(sel, NULL, &iter)) | |
549 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 1, &name, -1); | |
550 else | |
551 return; | |
552 | |
553 if (*name == '@') name++; | |
4621
69f028a6f357
[gaim-migrate @ 4912]
Christian Hammond <chipx86@chipx86.com>
parents:
4608
diff
changeset
|
554 if (*name == '%') name++; |
4359 | 555 if (*name == '+') name++; |
556 | |
4491 | 557 account = gaim_conversation_get_account(conv); |
4476
62c1e5e656d0
[gaim-migrate @ 4751]
Christian Hammond <chipx86@chipx86.com>
parents:
4466
diff
changeset
|
558 |
4359 | 559 conv2 = gaim_find_conversation(name); |
560 | |
4476
62c1e5e656d0
[gaim-migrate @ 4751]
Christian Hammond <chipx86@chipx86.com>
parents:
4466
diff
changeset
|
561 if (conv2 != NULL) { |
4359 | 562 gaim_window_raise(gaim_conversation_get_window(conv2)); |
4491 | 563 gaim_conversation_set_account(conv2, account); |
4476
62c1e5e656d0
[gaim-migrate @ 4751]
Christian Hammond <chipx86@chipx86.com>
parents:
4466
diff
changeset
|
564 } |
4359 | 565 else |
4491 | 566 conv2 = gaim_conversation_new(GAIM_CONV_IM, account, name); |
4359 | 567 } |
568 | |
569 static void | |
570 ignore_cb(GtkWidget *w, struct gaim_conversation *conv) | |
571 { | |
572 struct gaim_gtk_conversation *gtkconv; | |
573 struct gaim_gtk_chat_pane *gtkchat; | |
574 struct gaim_chat *chat; | |
575 GtkTreeIter iter; | |
576 GtkTreeModel *model; | |
577 GtkTreeSelection *sel; | |
578 const char *name; | |
579 int pos; | |
580 | |
581 chat = GAIM_CHAT(conv); | |
582 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
583 gtkchat = gtkconv->u.chat; | |
584 | |
585 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); | |
586 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkchat->list)); | |
587 | |
588 if (gtk_tree_selection_get_selected(sel, NULL, &iter)) { | |
589 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 1, &name, -1); | |
590 gtk_list_store_remove(GTK_LIST_STORE(model), &iter); | |
591 } | |
592 else | |
593 return; | |
594 | |
595 pos = g_list_index(gaim_chat_get_users(chat), name); | |
596 | |
597 if (gaim_chat_is_user_ignored(chat, name)) | |
598 gaim_chat_unignore(chat, name); | |
599 else | |
600 gaim_chat_ignore(chat, name); | |
601 | |
602 add_chat_buddy_common(conv, name, pos); | |
603 } | |
604 | |
605 static void | |
606 menu_im_cb(GtkWidget *w, struct gaim_conversation *conv) | |
607 { | |
608 const char *who; | |
609 struct gaim_conversation *conv2; | |
4491 | 610 struct gaim_account *account; |
4359 | 611 |
612 who = g_object_get_data(G_OBJECT(w), "user_data"); | |
613 | |
4491 | 614 account = gaim_conversation_get_account(conv); |
4476
62c1e5e656d0
[gaim-migrate @ 4751]
Christian Hammond <chipx86@chipx86.com>
parents:
4466
diff
changeset
|
615 |
4359 | 616 conv2 = gaim_find_conversation(who); |
617 | |
618 if (conv2 != NULL) | |
619 gaim_window_show(gaim_conversation_get_window(conv2)); | |
4476
62c1e5e656d0
[gaim-migrate @ 4751]
Christian Hammond <chipx86@chipx86.com>
parents:
4466
diff
changeset
|
620 else |
4491 | 621 conv2 = gaim_conversation_new(GAIM_CONV_IM, account, who); |
4359 | 622 } |
623 | |
624 static void | |
625 menu_info_cb(GtkWidget *w, struct gaim_conversation *conv) | |
626 { | |
627 struct gaim_connection *gc; | |
628 char *who; | |
629 | |
630 gc = gaim_conversation_get_gc(conv); | |
631 who = g_object_get_data(G_OBJECT(w), "user_data"); | |
632 | |
633 if (gc != NULL) { | |
634 /* | |
635 * If there are special needs for getting info on users in | |
636 * buddy chat "rooms"... | |
637 */ | |
638 if (gc->prpl->get_cb_info != NULL) | |
639 gc->prpl->get_cb_info(gc, gaim_chat_get_id(GAIM_CHAT(conv)), who); | |
640 else | |
641 gc->prpl->get_info(gc, who); | |
642 } | |
643 } | |
644 | |
645 static void | |
646 menu_away_cb(GtkWidget *w, struct gaim_conversation *conv) | |
647 { | |
648 struct gaim_connection *gc; | |
649 char *who; | |
650 | |
651 gc = gaim_conversation_get_gc(conv); | |
652 who = g_object_get_data(G_OBJECT(w), "user_data"); | |
653 | |
654 if (gc != NULL) { | |
655 /* | |
656 * May want to expand this to work similarly to menu_info_cb? | |
657 */ | |
658 | |
659 if (gc->prpl->get_cb_away != NULL) | |
660 gc->prpl->get_cb_away(gc, gaim_chat_get_id(GAIM_CHAT(conv)), who); | |
661 } | |
662 } | |
663 | |
664 static void | |
665 menu_add_cb(GtkWidget *w, struct gaim_conversation *conv) | |
666 { | |
667 struct gaim_connection *gc; | |
668 struct buddy *b; | |
669 char *name; | |
670 | |
671 gc = gaim_conversation_get_gc(conv); | |
672 name = g_object_get_data(G_OBJECT(w), "user_data"); | |
4491 | 673 b = find_buddy(gc->account, name); |
4359 | 674 |
675 if (b != NULL) | |
676 show_confirm_del(gc, name); | |
677 else if (gc != NULL) | |
678 show_add_buddy(gc, name, NULL, NULL); | |
679 | |
680 gtk_widget_grab_focus(GAIM_GTK_CONVERSATION(conv)->entry); | |
681 } | |
682 | |
683 static gint | |
684 right_click_chat_cb(GtkWidget *widget, GdkEventButton *event, | |
685 struct gaim_conversation *conv) | |
686 { | |
687 struct gaim_gtk_conversation *gtkconv; | |
688 struct gaim_gtk_chat_pane *gtkchat; | |
689 struct gaim_connection *gc; | |
4491 | 690 struct gaim_account *account; |
4359 | 691 GtkTreePath *path; |
692 GtkTreeIter iter; | |
693 GtkTreeModel *model; | |
694 GtkTreeViewColumn *column; | |
695 gchar *who; | |
696 int x, y; | |
697 | |
698 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
699 gtkchat = gtkconv->u.chat; | |
4491 | 700 account = gaim_conversation_get_account(conv); |
701 gc = account->gc; | |
4359 | 702 |
703 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); | |
704 | |
705 gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(gtkchat->list), | |
706 event->x, event->y, &path, &column, &x, &y); | |
707 | |
708 if (path == NULL) | |
709 return FALSE; | |
710 | |
711 gtk_tree_selection_select_path(GTK_TREE_SELECTION( | |
712 gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkchat->list))), path); | |
713 | |
714 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path); | |
715 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 1, &who, -1); | |
716 | |
4621
69f028a6f357
[gaim-migrate @ 4912]
Christian Hammond <chipx86@chipx86.com>
parents:
4608
diff
changeset
|
717 if (*who == '@') who++; |
69f028a6f357
[gaim-migrate @ 4912]
Christian Hammond <chipx86@chipx86.com>
parents:
4608
diff
changeset
|
718 if (*who == '%') who++; |
69f028a6f357
[gaim-migrate @ 4912]
Christian Hammond <chipx86@chipx86.com>
parents:
4608
diff
changeset
|
719 if (*who == '+') who++; |
69f028a6f357
[gaim-migrate @ 4912]
Christian Hammond <chipx86@chipx86.com>
parents:
4608
diff
changeset
|
720 |
4359 | 721 if (event->button == 1 && event->type == GDK_2BUTTON_PRESS) { |
722 struct gaim_conversation *c; | |
723 | |
724 if ((c = gaim_find_conversation(who)) == NULL) | |
4491 | 725 c = gaim_conversation_new(GAIM_CONV_IM, account, who); |
4476
62c1e5e656d0
[gaim-migrate @ 4751]
Christian Hammond <chipx86@chipx86.com>
parents:
4466
diff
changeset
|
726 else |
4491 | 727 gaim_conversation_set_account(c, account); |
4359 | 728 } |
729 else if (event->button == 3 && event->type == GDK_BUTTON_PRESS) { | |
730 static GtkWidget *menu = NULL; | |
731 GtkWidget *button; | |
732 | |
733 /* | |
734 * If a menu already exists, destroy it before creating a new one, | |
735 * thus freeing-up the memory it occupied. | |
736 */ | |
737 | |
738 if (menu) | |
739 gtk_widget_destroy(menu); | |
740 | |
741 menu = gtk_menu_new(); | |
742 | |
743 button = gtk_menu_item_new_with_label(_("IM")); | |
744 g_signal_connect(G_OBJECT(button), "activate", | |
745 G_CALLBACK(menu_im_cb), conv); | |
746 g_object_set_data(G_OBJECT(button), "user_data", who); | |
4635 | 747 gtk_menu_shell_append(GTK_MENU_SHELL(menu), button); |
4359 | 748 gtk_widget_show(button); |
749 | |
750 if (gaim_chat_is_user_ignored(GAIM_CHAT(conv), who)) | |
751 button = gtk_menu_item_new_with_label(_("Un-Ignore")); | |
752 else | |
753 button = gtk_menu_item_new_with_label(_("Ignore")); | |
754 | |
755 g_signal_connect(G_OBJECT(button), "activate", | |
756 G_CALLBACK(ignore_cb), conv); | |
757 g_object_set_data(G_OBJECT(button), "user_data", who); | |
4635 | 758 gtk_menu_shell_append(GTK_MENU_SHELL(menu), button); |
4359 | 759 gtk_widget_show(button); |
760 | |
761 if (gc && gc->prpl->get_info) { | |
762 button = gtk_menu_item_new_with_label(_("Info")); | |
763 g_signal_connect(G_OBJECT(button), "activate", | |
764 G_CALLBACK(menu_info_cb), conv); | |
765 g_object_set_data(G_OBJECT(button), "user_data", who); | |
4635 | 766 gtk_menu_shell_append(GTK_MENU_SHELL(menu), button); |
4359 | 767 gtk_widget_show(button); |
768 } | |
769 | |
770 if (gc && gc->prpl->get_cb_away) { | |
771 button = gtk_menu_item_new_with_label(_("Get Away Msg")); | |
772 g_signal_connect(G_OBJECT(button), "activate", | |
773 G_CALLBACK(menu_away_cb), conv); | |
774 g_object_set_data(G_OBJECT(button), "user_data", who); | |
4635 | 775 gtk_menu_shell_append(GTK_MENU_SHELL(menu), button); |
4359 | 776 gtk_widget_show(button); |
777 } | |
778 | |
779 /* Added by Jonas <jonas@birme.se> */ | |
780 if (gc) { | |
4491 | 781 if (find_buddy(gc->account, who)) |
4359 | 782 button = gtk_menu_item_new_with_label(_("Remove")); |
783 else | |
784 button = gtk_menu_item_new_with_label(_("Add")); | |
785 | |
786 g_signal_connect(G_OBJECT(button), "activate", | |
787 G_CALLBACK(menu_add_cb), conv); | |
788 | |
789 g_object_set_data(G_OBJECT(button), "user_data", who); | |
4635 | 790 gtk_menu_shell_append(GTK_MENU_SHELL(menu), button); |
4359 | 791 gtk_widget_show(button); |
792 } | |
793 /* End Jonas */ | |
4635 | 794 |
4359 | 795 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, |
796 event->button, event->time); | |
797 } | |
798 | |
799 return TRUE; | |
800 } | |
801 | |
802 static void | |
803 do_invite(GtkWidget *w, int resp, struct InviteBuddyInfo *info) | |
804 { | |
805 const char *buddy, *message; | |
806 struct gaim_gtk_conversation *gtkconv; | |
807 | |
808 gtkconv = GAIM_GTK_CONVERSATION(info->conv); | |
809 | |
810 if (resp == GTK_RESPONSE_OK) { | |
811 buddy = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(info->entry)->entry)); | |
812 message = gtk_entry_get_text(GTK_ENTRY(info->message)); | |
813 | |
814 if (!g_strcasecmp(buddy, "")) { | |
815 g_free(info); | |
816 | |
817 return; | |
818 } | |
819 | |
820 serv_chat_invite(gaim_conversation_get_gc(info->conv), | |
821 gaim_chat_get_id(GAIM_CHAT(info->conv)), | |
822 message, buddy); | |
823 } | |
824 | |
825 gtk_widget_destroy(invite_dialog); | |
826 invite_dialog = NULL; | |
827 | |
828 g_free(info); | |
829 } | |
830 | |
831 static void | |
832 invite_cb(GtkWidget *widget, struct gaim_conversation *conv) | |
833 { | |
834 struct InviteBuddyInfo *info = NULL; | |
835 | |
836 if (invite_dialog == NULL) { | |
837 struct gaim_connection *gc; | |
838 struct gaim_window *win; | |
839 struct gaim_gtk_window *gtkwin; | |
840 char *filename; | |
841 GtkWidget *label; | |
842 GtkWidget *vbox, *hbox; | |
843 GtkWidget *table; | |
844 GtkWidget *img; | |
845 | |
846 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "dialogs", | |
847 "gaim_question.png", NULL); | |
848 | |
849 img = gtk_image_new_from_file(filename); | |
850 | |
851 g_free(filename); | |
852 | |
853 | |
854 info = g_new0(struct InviteBuddyInfo, 1); | |
855 info->conv = conv; | |
856 | |
857 gc = gaim_conversation_get_gc(conv); | |
858 win = gaim_conversation_get_window(conv); | |
859 gtkwin = GAIM_GTK_WINDOW(win); | |
860 | |
861 /* Create the new dialog. */ | |
862 invite_dialog = gtk_dialog_new_with_buttons( | |
863 _("Gaim - Invite Buddy Into Chat Room"), | |
864 GTK_WINDOW(gtkwin->window), | |
865 GTK_DIALOG_MODAL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, | |
866 GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); | |
867 | |
868 gtk_dialog_set_default_response(GTK_DIALOG(invite_dialog), | |
869 GTK_RESPONSE_OK); | |
870 gtk_container_set_border_width(GTK_CONTAINER(invite_dialog), 6); | |
871 gtk_window_set_resizable(GTK_WINDOW(invite_dialog), FALSE); | |
872 gtk_dialog_set_has_separator(GTK_DIALOG(invite_dialog), FALSE); | |
873 | |
874 /* Setup the outside spacing. */ | |
875 vbox = GTK_DIALOG(invite_dialog)->vbox; | |
876 | |
877 gtk_box_set_spacing(GTK_BOX(vbox), 12); | |
878 gtk_container_set_border_width(GTK_CONTAINER(vbox), 6); | |
879 | |
880 /* Setup the inner hbox and put the dialog's icon in it. */ | |
881 hbox = gtk_hbox_new(FALSE, 12); | |
882 gtk_container_add(GTK_CONTAINER(vbox), hbox); | |
883 gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0); | |
884 gtk_misc_set_alignment(GTK_MISC(img), 0, 0); | |
885 | |
886 /* Setup the right vbox. */ | |
887 vbox = gtk_vbox_new(FALSE, 0); | |
888 gtk_container_add(GTK_CONTAINER(hbox), vbox); | |
889 | |
890 /* Put our happy label in it. */ | |
891 label = gtk_label_new(_("Please enter the name of the user you wish " | |
892 "to invite, along with an optional invite " | |
893 "message.")); | |
894 gtk_widget_set_size_request(label, 350, -1); | |
895 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); | |
896 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); | |
897 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | |
898 | |
899 /* hbox for the table, and to give it some spacing on the left. */ | |
900 hbox = gtk_hbox_new(FALSE, 6); | |
901 gtk_container_add(GTK_CONTAINER(vbox), hbox); | |
902 | |
903 /* Setup the table we're going to use to lay stuff out. */ | |
904 table = gtk_table_new(2, 2, FALSE); | |
905 gtk_table_set_row_spacings(GTK_TABLE(table), 6); | |
906 gtk_table_set_col_spacings(GTK_TABLE(table), 6); | |
907 gtk_container_set_border_width(GTK_CONTAINER(table), 12); | |
908 gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0); | |
909 | |
910 /* Now the Buddy label */ | |
911 label = gtk_label_new(NULL); | |
912 gtk_label_set_markup_with_mnemonic(GTK_LABEL(label), _("_Buddy:")); | |
913 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); | |
914 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1); | |
915 | |
916 /* Now the Buddy drop-down entry field. */ | |
917 info->entry = gtk_combo_new(); | |
918 gtk_combo_set_case_sensitive(GTK_COMBO(info->entry), FALSE); | |
919 gtk_entry_set_activates_default( | |
920 GTK_ENTRY(GTK_COMBO(info->entry)->entry), TRUE); | |
921 | |
922 gtk_table_attach_defaults(GTK_TABLE(table), info->entry, 1, 2, 0, 1); | |
923 gtk_label_set_mnemonic_widget(GTK_LABEL(label), info->entry); | |
924 | |
925 /* Fill in the names. */ | |
926 gtk_combo_set_popdown_strings(GTK_COMBO(info->entry), | |
927 generate_invite_user_names(gc)); | |
928 | |
929 | |
930 /* Now the label for "Message" */ | |
931 label = gtk_label_new(NULL); | |
932 gtk_label_set_markup_with_mnemonic(GTK_LABEL(label), _("_Message:")); | |
933 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); | |
934 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2); | |
935 | |
936 | |
937 /* And finally, the Message entry field. */ | |
938 info->message = gtk_entry_new(); | |
939 gtk_entry_set_activates_default(GTK_ENTRY(info->message), TRUE); | |
940 | |
941 gtk_table_attach_defaults(GTK_TABLE(table), info->message, 1, 2, 1, 2); | |
942 gtk_label_set_mnemonic_widget(GTK_LABEL(label), info->message); | |
943 | |
944 /* Connect the signals. */ | |
945 g_signal_connect(G_OBJECT(invite_dialog), "response", | |
946 G_CALLBACK(do_invite), info); | |
947 } | |
948 | |
949 gtk_widget_show_all(invite_dialog); | |
950 | |
951 if (info != NULL) | |
952 gtk_widget_grab_focus(GTK_COMBO(info->entry)->entry); | |
953 } | |
954 | |
955 static gboolean | |
956 entry_key_pressed_cb_2(GtkWidget *entry, GdkEventKey *event, gpointer data) | |
957 { | |
958 struct gaim_window *win; | |
959 struct gaim_conversation *conv; | |
960 struct gaim_gtk_conversation *gtkconv; | |
4362 | 961 struct gaim_gtk_window *gtkwin; |
4359 | 962 |
963 conv = (struct gaim_conversation *)data; | |
964 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
965 win = gaim_conversation_get_window(conv); | |
4362 | 966 gtkwin = GAIM_GTK_WINDOW(win); |
4359 | 967 |
968 if (event->keyval == GDK_Escape) { | |
969 if (convo_options & OPT_CONVO_ESC_CAN_CLOSE) { | |
970 g_signal_stop_emission_by_name(G_OBJECT(entry), "key_press_event"); | |
971 gaim_conversation_destroy(conv); | |
972 } | |
973 } | |
974 else if (event->keyval == GDK_Page_Up) { | |
975 g_signal_stop_emission_by_name(G_OBJECT(entry), "key_press_event"); | |
976 | |
977 if (!(event->state & GDK_CONTROL_MASK)) | |
978 gtk_imhtml_page_up(GTK_IMHTML(gtkconv->imhtml)); | |
979 } | |
980 else if (event->keyval == GDK_Page_Down) { | |
981 g_signal_stop_emission_by_name(G_OBJECT(entry), "key_press_event"); | |
982 | |
983 if (!(event->state & GDK_CONTROL_MASK)) | |
984 gtk_imhtml_page_down(GTK_IMHTML(gtkconv->imhtml)); | |
985 } | |
986 else if ((event->keyval == GDK_F2) && | |
987 (convo_options & OPT_CONVO_F2_TOGGLES)) { | |
988 gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml), | |
989 !GTK_IMHTML(gtkconv->imhtml)->comments); | |
990 } | |
991 else if (event->keyval == GDK_Return || event->keyval == GDK_KP_Enter) { | |
992 if ((event->state & GDK_CONTROL_MASK) && | |
993 (convo_options & OPT_CONVO_CTL_ENTER)) { | |
994 | |
995 send_cb(NULL, conv); | |
996 g_signal_stop_emission_by_name(G_OBJECT(entry), "key_press_event"); | |
997 | |
998 return TRUE; | |
999 } | |
1000 else if (!(event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) && | |
1001 (convo_options & OPT_CONVO_ENTER_SENDS)) { | |
1002 | |
1003 send_cb(NULL, conv); | |
1004 g_signal_stop_emission_by_name(G_OBJECT(entry), "key_press_event"); | |
1005 | |
1006 return TRUE; | |
1007 } | |
1008 | |
1009 return FALSE; | |
1010 } | |
1011 else if ((event->state & GDK_CONTROL_MASK) && (event->keyval == 'm')) { | |
1012 g_signal_stop_emission_by_name(G_OBJECT(entry), "key_press_event"); | |
1013 gtk_text_buffer_insert_at_cursor(gtkconv->entry_buffer, "\n", 1); | |
1014 } | |
1015 else if (event->state & GDK_CONTROL_MASK) { | |
1016 switch (event->keyval) { | |
1017 case GDK_Up: | |
1018 if (!conv->send_history) | |
1019 break; | |
1020 | |
1021 if (!conv->send_history->prev) { | |
1022 GtkTextIter start, end; | |
1023 | |
1024 if (conv->send_history->data) | |
1025 g_free(conv->send_history->data); | |
1026 | |
1027 gtk_text_buffer_get_start_iter(gtkconv->entry_buffer, | |
1028 &start); | |
1029 gtk_text_buffer_get_end_iter(gtkconv->entry_buffer, &end); | |
1030 | |
1031 conv->send_history->data = | |
1032 gtk_text_buffer_get_text(gtkconv->entry_buffer, | |
1033 &start, &end, FALSE); | |
1034 } | |
1035 | |
1036 if (conv->send_history->next && | |
1037 conv->send_history->next->data) { | |
1038 | |
1039 conv->send_history = conv->send_history->next; | |
1040 gtk_text_buffer_set_text(gtkconv->entry_buffer, | |
1041 conv->send_history->data, -1); | |
1042 } | |
1043 | |
1044 break; | |
1045 | |
1046 case GDK_Down: | |
1047 if (!conv->send_history) | |
1048 break; | |
1049 | |
1050 if (conv->send_history->prev) { | |
1051 conv->send_history = conv->send_history->prev; | |
1052 | |
1053 if (conv->send_history->data) | |
1054 gtk_text_buffer_set_text(gtkconv->entry_buffer, | |
1055 conv->send_history->data, -1); | |
1056 } | |
1057 | |
1058 break; | |
1059 } | |
1060 | |
1061 if (convo_options & OPT_CONVO_CTL_CHARS) { | |
1062 switch (event->keyval) { | |
1063 case 'i': | |
1064 case 'I': | |
1065 quiet_set(gtkconv->toolbar.italic, | |
1066 !gtk_toggle_button_get_active( | |
1067 GTK_TOGGLE_BUTTON(gtkconv->toolbar.italic))); | |
1068 | |
1069 do_italic(gtkconv->toolbar.italic, gtkconv); | |
1070 | |
1071 g_signal_stop_emission_by_name(G_OBJECT(entry), | |
1072 "key_press_event"); | |
1073 break; | |
1074 | |
1075 case 'u': /* ctrl-u is GDK_Clear, which clears the line. */ | |
1076 case 'U': | |
1077 quiet_set(gtkconv->toolbar.underline, | |
1078 !gtk_toggle_button_get_active( | |
1079 GTK_TOGGLE_BUTTON(gtkconv->toolbar.underline))); | |
1080 | |
1081 do_underline(gtkconv->toolbar.underline, gtkconv); | |
1082 | |
1083 g_signal_stop_emission_by_name(G_OBJECT(entry), | |
1084 "key_press_event"); | |
1085 break; | |
1086 | |
1087 case 'b': /* ctrl-b is GDK_Left, which moves backwards. */ | |
1088 case 'B': | |
1089 quiet_set(gtkconv->toolbar.bold, | |
1090 !gtk_toggle_button_get_active( | |
1091 GTK_TOGGLE_BUTTON(gtkconv->toolbar.bold))); | |
1092 | |
1093 do_bold(gtkconv->toolbar.bold, gtkconv); | |
1094 | |
1095 g_signal_stop_emission_by_name(G_OBJECT(entry), | |
1096 "key_press_event"); | |
1097 break; | |
1098 | |
1099 case '-': | |
1100 do_small(NULL, gtkconv); | |
1101 | |
1102 g_signal_stop_emission_by_name(G_OBJECT(entry), | |
1103 "key_press_event"); | |
1104 break; | |
1105 | |
1106 case '=': | |
1107 case '+': | |
1108 do_big(NULL, gtkconv); | |
1109 | |
1110 g_signal_stop_emission_by_name(G_OBJECT(entry), | |
1111 "key_press_event"); | |
1112 break; | |
1113 | |
1114 case '0': | |
1115 do_normal(NULL, gtkconv); | |
1116 | |
1117 g_signal_stop_emission_by_name(G_OBJECT(entry), | |
1118 "key_press_event"); | |
1119 break; | |
1120 | |
1121 case 'f': | |
1122 case 'F': | |
1123 quiet_set(gtkconv->toolbar.normal_size, | |
1124 !gtk_toggle_button_get_active( | |
1125 GTK_TOGGLE_BUTTON(gtkconv->toolbar.normal_size))); | |
1126 | |
1127 toggle_font(gtkconv->toolbar.normal_size, conv); | |
1128 | |
1129 g_signal_stop_emission_by_name(G_OBJECT(entry), | |
1130 "key_press_event"); | |
1131 break; | |
1132 } | |
1133 } | |
1134 | |
1135 if (convo_options & OPT_CONVO_CTL_SMILEYS) { | |
1136 char buf[7]; | |
1137 | |
1138 *buf = '\0'; | |
1139 | |
1140 switch (event->keyval) { | |
1141 case '1': strcpy(buf, ":-)"); break; | |
1142 case '2': strcpy(buf, ":-("); break; | |
1143 case '3': strcpy(buf, ";-)"); break; | |
1144 case '4': strcpy(buf, ":-P"); break; | |
1145 case '5': strcpy(buf, "=-O"); break; | |
1146 case '6': strcpy(buf, ":-*"); break; | |
1147 case '7': strcpy(buf, ">:o"); break; | |
1148 case '8': strcpy(buf, "8-)"); break; | |
1149 case '!': strcpy(buf, ":-$"); break; | |
1150 case '@': strcpy(buf, ":-!"); break; | |
1151 case '#': strcpy(buf, ":-["); break; | |
1152 case '$': strcpy(buf, "O:-)"); break; | |
1153 case '%': strcpy(buf, ":-/"); break; | |
1154 case '^': strcpy(buf, ":'("); break; | |
1155 case '&': strcpy(buf, ":-X"); break; | |
1156 case '*': strcpy(buf, ":-D"); break; | |
1157 default: break; | |
1158 } | |
1159 | |
1160 if (*buf) { | |
1161 gtk_text_buffer_insert_at_cursor(gtkconv->entry_buffer, | |
1162 buf, -1); | |
1163 g_signal_stop_emission_by_name(G_OBJECT(entry), "key_press_event"); | |
1164 } | |
1165 } | |
1166 | |
1167 if (event->keyval == 'l') { | |
1168 gtk_imhtml_clear(GTK_IMHTML(gtkconv->imhtml)); | |
1169 g_string_free(conv->history, TRUE); | |
1170 conv->history = g_string_new(""); | |
1171 } | |
1172 else if ((event->keyval == 'w') && | |
1173 (convo_options & OPT_CONVO_CTL_W_CLOSES)) { | |
1174 | |
1175 g_signal_stop_emission_by_name(G_OBJECT(entry), "key_press_event"); | |
1176 gaim_conversation_destroy(conv); | |
1177 return TRUE; | |
1178 } | |
1179 else if (event->keyval == 'n') { | |
1180 g_signal_stop_emission_by_name(G_OBJECT(entry), "key_press_event"); | |
1181 | |
1182 show_im_dialog(); | |
1183 } | |
1184 else if (event->keyval == 'z') { | |
1185 g_signal_stop_emission_by_name(G_OBJECT(entry), "key_press_event"); | |
1186 | |
4361
25d5b2a7545f
[gaim-migrate @ 4627]
Christian Hammond <chipx86@chipx86.com>
parents:
4360
diff
changeset
|
1187 #ifndef _WIN32 |
4359 | 1188 XIconifyWindow(GDK_DISPLAY(), |
1189 GDK_WINDOW_XWINDOW(gtkwin->window->window), | |
4362 | 1190 ((_XPrivDisplay)GDK_DISPLAY())->default_screen); |
4359 | 1191 #endif |
1192 } | |
1193 else if (event->keyval == '[') { | |
1194 gaim_window_switch_conversation(win, | |
1195 gaim_conversation_get_index(conv) - 1); | |
1196 | |
1197 g_signal_stop_emission_by_name(G_OBJECT(entry), "key_press_event"); | |
1198 } | |
1199 else if (event->keyval == ']') { | |
1200 gaim_window_switch_conversation(win, | |
1201 gaim_conversation_get_index(conv) + 1); | |
1202 | |
1203 g_signal_stop_emission_by_name(G_OBJECT(entry), "key_press_event"); | |
1204 } | |
1205 else if (event->keyval == GDK_Tab) { | |
1206 move_next_tab(conv); | |
1207 | |
1208 g_signal_stop_emission_by_name(G_OBJECT(entry), "key_press_event"); | |
1209 | |
1210 return TRUE; | |
1211 } | |
1212 } | |
1213 else if ((event->keyval == GDK_Tab) && | |
1214 gaim_conversation_get_type(conv) == GAIM_CONV_CHAT && | |
1215 (chat_options & OPT_CHAT_TAB_COMPLETE)) { | |
1216 | |
1217 tab_complete(conv); | |
1218 | |
1219 g_signal_stop_emission_by_name(G_OBJECT(entry), "key_press_event"); | |
1220 | |
1221 return TRUE; | |
1222 } | |
1223 else if ((event->state & GDK_MOD1_MASK) && | |
1224 event->keyval > '0' && event->keyval <= '9') { | |
1225 | |
1226 gaim_window_switch_conversation(win, event->keyval - '1'); | |
1227 | |
1228 g_signal_stop_emission_by_name(G_OBJECT(entry), "key_press_event"); | |
1229 } | |
1230 | |
1231 return FALSE; | |
1232 } | |
1233 | |
1234 /* | |
1235 * NOTE: | |
1236 * This guy just kills a single right click from being propagated any | |
1237 * further. I have no idea *why* we need this, but we do ... It | |
1238 * prevents right clicks on the GtkTextView in a convo dialog from | |
1239 * going all the way down to the notebook. I suspect a bug in | |
1240 * GtkTextView, but I'm not ready to point any fingers yet. | |
1241 */ | |
1242 static gboolean | |
1243 entry_stop_rclick_cb(GtkWidget *widget, GdkEventButton *event, gpointer data) | |
1244 { | |
1245 if (event->button == 3 && event->type == GDK_BUTTON_PRESS) { | |
1246 /* Right single click */ | |
1247 g_signal_stop_emission_by_name(G_OBJECT(widget), "button_press_event"); | |
1248 | |
1249 return TRUE; | |
1250 } | |
1251 | |
1252 return FALSE; | |
1253 } | |
1254 | |
1255 static void | |
4673 | 1256 menu_conv_sel_send_cb(GObject *m, gpointer data) |
4359 | 1257 { |
1258 struct gaim_window *win = g_object_get_data(m, "user_data"); | |
4673 | 1259 struct gaim_account *account = g_object_get_data(m, "gaim_account"); |
4359 | 1260 struct gaim_conversation *conv; |
1261 | |
1262 if (gaim_gtk_is_state_locked()) | |
1263 return; | |
1264 | |
1265 conv = gaim_window_get_active_conversation(win); | |
1266 | |
4491 | 1267 gaim_conversation_set_account(conv, account); |
4359 | 1268 } |
1269 | |
1270 static void | |
1271 insert_text_cb(GtkTextBuffer *textbuffer, GtkTextIter *position, | |
1272 gchar *new_text, gint new_text_length, gpointer user_data) | |
1273 { | |
1274 struct gaim_conversation *conv = (struct gaim_conversation *)user_data; | |
1275 | |
1276 if (conv == NULL) | |
1277 return; | |
1278 | |
1279 if (misc_options & OPT_MISC_STEALTH_TYPING) | |
1280 return; | |
1281 | |
1282 got_typing_keypress(conv, (gtk_text_iter_is_start(position) && | |
1283 gtk_text_iter_is_end(position))); | |
1284 } | |
1285 | |
1286 static void | |
1287 delete_text_cb(GtkTextBuffer *textbuffer, GtkTextIter *start_pos, | |
1288 GtkTextIter *end_pos, gpointer user_data) | |
1289 { | |
1290 struct gaim_conversation *conv = (struct gaim_conversation *)user_data; | |
1291 struct gaim_im *im; | |
1292 | |
1293 if (conv == NULL) | |
1294 return; | |
1295 | |
1296 if (misc_options & OPT_MISC_STEALTH_TYPING) | |
1297 return; | |
1298 | |
1299 im = GAIM_IM(conv); | |
1300 | |
1301 if (gtk_text_iter_is_start(start_pos) && gtk_text_iter_is_end(end_pos)) { | |
1302 | |
1303 /* We deleted all the text, so turn off typing. */ | |
1304 if (gaim_im_get_type_again_timeout(im)) | |
1305 gaim_im_stop_type_again_timeout(im); | |
1306 | |
1307 /* XXX The (char *) should go away! Somebody add consts to stuff! */ | |
1308 serv_send_typing(gaim_conversation_get_gc(conv), | |
1309 (char *)gaim_conversation_get_name(conv), | |
1310 NOT_TYPING); | |
1311 } | |
1312 else { | |
1313 /* We're deleting, but not all of it, so it counts as typing. */ | |
1314 got_typing_keypress(conv, FALSE); | |
1315 } | |
1316 } | |
1317 | |
1318 static void | |
1319 notebook_init_grab(struct gaim_gtk_window *gtkwin, GtkWidget *widget) | |
1320 { | |
1321 static GdkCursor *cursor = NULL; | |
1322 | |
1323 gtkwin->in_drag = TRUE; | |
1324 | |
1325 if (gtkwin->drag_leave_signal) { | |
1326 g_signal_handler_disconnect(G_OBJECT(widget), | |
1327 gtkwin->drag_leave_signal); | |
1328 | |
1329 gtkwin->drag_leave_signal = 0; | |
1330 } | |
1331 | |
1332 if (cursor == NULL) | |
1333 cursor = gdk_cursor_new(GDK_FLEUR); | |
1334 | |
1335 /* Grab the pointer */ | |
1336 gtk_grab_add(gtkwin->notebook); | |
1337 gdk_pointer_grab(gtkwin->notebook->window, FALSE, | |
1338 GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, | |
1339 NULL, cursor, GDK_CURRENT_TIME); | |
1340 } | |
1341 | |
1342 static gboolean | |
1343 notebook_motion_cb(GtkWidget *widget, GdkEventButton *e, | |
1344 struct gaim_window *win) | |
1345 { | |
1346 struct gaim_gtk_window *gtkwin; | |
1347 | |
1348 gtkwin = GAIM_GTK_WINDOW(win); | |
1349 | |
1350 /* | |
1351 * Make sure the user moved the mouse far enough for the | |
1352 * drag to be initiated. | |
1353 */ | |
1354 if (gtkwin->in_predrag) { | |
1355 if (e->x_root < gtkwin->drag_min_x || | |
1356 e->x_root >= gtkwin->drag_max_x || | |
1357 e->y_root < gtkwin->drag_min_y || | |
1358 e->y_root >= gtkwin->drag_max_y) { | |
1359 | |
1360 gtkwin->in_predrag = FALSE; | |
1361 notebook_init_grab(gtkwin, widget); | |
1362 } | |
1363 } | |
1364 else { /* Otherwise, draw the arrows. */ | |
1365 struct gaim_window *dest_win; | |
1366 struct gaim_gtk_window *dest_gtkwin; | |
1367 GtkNotebook *dest_notebook; | |
1368 GtkWidget *tab, *last_vis_tab = NULL; | |
1369 gint nb_x, nb_y, page_num, i, last_vis_tab_loc = -1; | |
1370 gint arrow1_x, arrow1_y, arrow2_x, arrow2_y; | |
1371 gboolean horiz_tabs = FALSE, tab_found = FALSE; | |
1372 GList *l; | |
1373 | |
1374 /* Get the window that the cursor is over. */ | |
1375 dest_win = gaim_gtkwin_get_at_xy(e->x_root, e->y_root); | |
1376 | |
1377 if (dest_win == NULL) { | |
1378 dnd_hints_hide_all(); | |
1379 | |
1380 return TRUE; | |
1381 } | |
1382 | |
1383 dest_gtkwin = GAIM_GTK_WINDOW(dest_win); | |
1384 | |
1385 dest_notebook = GTK_NOTEBOOK(dest_gtkwin->notebook); | |
1386 | |
1387 gdk_window_get_origin(GTK_WIDGET(dest_notebook)->window, &nb_x, &nb_y); | |
1388 | |
1389 arrow1_x = arrow2_x = nb_x; | |
1390 arrow1_y = arrow2_y = nb_y; | |
1391 | |
1392 page_num = gaim_gtkconv_get_dest_tab_at_xy(dest_win, | |
1393 e->x_root, e->y_root); | |
1394 | |
1395 if (gtk_notebook_get_tab_pos(dest_notebook) == GTK_POS_TOP || | |
1396 gtk_notebook_get_tab_pos(dest_notebook) == GTK_POS_BOTTOM) { | |
1397 | |
1398 horiz_tabs = TRUE; | |
1399 } | |
1400 | |
1401 /* Find out where to put the arrows. */ | |
1402 for (l = gaim_window_get_conversations(dest_win), i = 0; | |
1403 l != NULL; | |
1404 l = l->next, i++) { | |
1405 | |
1406 struct gaim_conversation *conv = l->data; | |
1407 | |
1408 tab = GAIM_GTK_CONVERSATION(conv)->tabby; | |
1409 | |
1410 /* | |
1411 * If this is the correct tab, record the positions | |
1412 * for the arrows. | |
1413 */ | |
1414 if (i == page_num) { | |
1415 if (horiz_tabs) { | |
1416 arrow1_x = arrow2_x = nb_x + tab->allocation.x; | |
1417 arrow1_y = nb_y + tab->allocation.y; | |
1418 arrow2_y = nb_y + tab->allocation.y + | |
1419 tab->allocation.height; | |
1420 } | |
1421 else { | |
1422 arrow1_x = nb_x + tab->allocation.x; | |
1423 arrow2_x = nb_x + tab->allocation.x + | |
1424 tab->allocation.width; | |
1425 arrow1_y = arrow2_y = nb_y + tab->allocation.y; | |
1426 } | |
1427 | |
1428 tab_found = TRUE; | |
1429 break; | |
1430 } | |
1431 else { /* Keep track of the right-most tab that we see. */ | |
1432 if (horiz_tabs && tab->allocation.x > last_vis_tab_loc) { | |
1433 last_vis_tab = tab; | |
1434 last_vis_tab_loc = tab->allocation.x; | |
1435 } | |
1436 else if (!horiz_tabs && tab->allocation.y > last_vis_tab_loc) { | |
1437 last_vis_tab = tab; | |
1438 last_vis_tab_loc = tab->allocation.y; | |
1439 } | |
1440 } | |
1441 } | |
1442 | |
1443 /* | |
1444 * If we didn't find the tab, then we'll just place the | |
1445 * arrows to the right/bottom of the last visible tab. | |
1446 */ | |
1447 if (!tab_found && last_vis_tab) { | |
1448 if (horiz_tabs) { | |
1449 arrow1_x = arrow2_x = nb_x + last_vis_tab->allocation.x + | |
1450 last_vis_tab->allocation.width; | |
1451 arrow1_y = nb_y + last_vis_tab->allocation.y; | |
1452 arrow2_y = nb_y + last_vis_tab->allocation.y + | |
1453 last_vis_tab->allocation.height; | |
1454 } | |
1455 else { | |
1456 arrow1_x = nb_x + last_vis_tab->allocation.x; | |
1457 arrow2_x = nb_x + last_vis_tab->allocation.x + | |
1458 last_vis_tab->allocation.width; | |
1459 arrow1_y = arrow2_y = nb_y + last_vis_tab->allocation.y + | |
1460 last_vis_tab->allocation.height; | |
1461 } | |
1462 } | |
1463 | |
1464 if (horiz_tabs) { | |
1465 dnd_hints_show(HINT_ARROW_DOWN, arrow1_x, arrow1_y); | |
1466 dnd_hints_show(HINT_ARROW_UP, arrow2_x, arrow2_y); | |
1467 } | |
1468 else { | |
1469 dnd_hints_show(HINT_ARROW_RIGHT, arrow1_x, arrow1_y); | |
1470 dnd_hints_show(HINT_ARROW_LEFT, arrow2_x, arrow2_y); | |
1471 } | |
1472 } | |
1473 | |
1474 return TRUE; | |
1475 } | |
1476 | |
1477 static gboolean | |
1478 notebook_leave_cb(GtkWidget *widget, GdkEventCrossing *e, | |
1479 struct gaim_window *win) | |
1480 { | |
1481 struct gaim_gtk_window *gtkwin; | |
1482 | |
1483 gtkwin = GAIM_GTK_WINDOW(win); | |
1484 | |
1485 if (gtkwin->in_drag) | |
1486 return FALSE; | |
1487 | |
1488 if (e->x_root < gtkwin->drag_min_x || | |
1489 e->x_root >= gtkwin->drag_max_x || | |
1490 e->y_root < gtkwin->drag_min_y || | |
1491 e->y_root >= gtkwin->drag_max_y) { | |
1492 | |
1493 gtkwin->in_predrag = FALSE; | |
1494 notebook_init_grab(gtkwin, widget); | |
1495 } | |
1496 | |
1497 return TRUE; | |
1498 } | |
1499 | |
1500 /* | |
1501 * THANK YOU GALEON! | |
1502 */ | |
1503 static gboolean | |
1504 notebook_press_cb(GtkWidget *widget, GdkEventButton *e, | |
1505 struct gaim_window *win) | |
1506 { | |
1507 struct gaim_gtk_window *gtkwin; | |
1508 gint nb_x, nb_y, x_rel, y_rel; | |
1509 GList *l; | |
1510 int tab_clicked; | |
1511 | |
1512 if (e->button != 1 || e->type != GDK_BUTTON_PRESS) | |
1513 return FALSE; | |
1514 | |
1515 gtkwin = GAIM_GTK_WINDOW(win); | |
1516 | |
1517 if (gtkwin->in_drag) { | |
1518 debug_printf("Already in the middle of a window " | |
1519 "drag at tab_press_cb\n"); | |
1520 return FALSE; | |
1521 } | |
1522 | |
1523 /* | |
1524 * Make sure a tab was actually clicked. The arrow buttons | |
1525 * mess things up. | |
1526 */ | |
1527 tab_clicked = gaim_gtkconv_get_tab_at_xy(win, e->x_root, e->y_root); | |
1528 | |
1529 if (tab_clicked == -1) | |
1530 return FALSE; | |
1531 | |
1532 /* | |
1533 * Get the relative position of the press event, with regards to | |
1534 * the position of the notebook. | |
1535 */ | |
1536 gdk_window_get_origin(gtkwin->notebook->window, &nb_x, &nb_y); | |
1537 | |
1538 x_rel = e->x_root - nb_x; | |
1539 y_rel = e->y_root - nb_y; | |
1540 | |
1541 /* Reset the min/max x/y */ | |
1542 gtkwin->drag_min_x = 0; | |
1543 gtkwin->drag_min_y = 0; | |
1544 gtkwin->drag_max_x = 0; | |
1545 gtkwin->drag_max_y = 0; | |
1546 | |
1547 /* Find out which tab was dragged. */ | |
1548 for (l = gaim_window_get_conversations(win); l != NULL; l = l->next) { | |
1549 struct gaim_conversation *conv = l->data; | |
1550 GtkWidget *tab = GAIM_GTK_CONVERSATION(conv)->tabby; | |
1551 | |
1552 if (!GTK_WIDGET_VISIBLE(tab)) | |
1553 continue; | |
1554 | |
1555 if (tab->allocation.x > x_rel || tab->allocation.y > y_rel) | |
1556 break; | |
1557 | |
1558 /* Save the borders of the tab. */ | |
1559 gtkwin->drag_min_x = tab->allocation.x + nb_x; | |
1560 gtkwin->drag_min_y = tab->allocation.y + nb_y; | |
1561 gtkwin->drag_max_x = tab->allocation.width + gtkwin->drag_min_x; | |
1562 gtkwin->drag_max_y = tab->allocation.height + gtkwin->drag_min_y; | |
1563 } | |
1564 | |
1565 /* Make sure the click occurred in the tab. */ | |
1566 if (e->x_root < gtkwin->drag_min_x || | |
1567 e->x_root >= gtkwin->drag_max_x || | |
1568 e->y_root < gtkwin->drag_min_y || | |
1569 e->y_root >= gtkwin->drag_max_y) { | |
1570 | |
1571 return FALSE; | |
1572 } | |
1573 | |
1574 gtkwin->in_predrag = TRUE; | |
1575 | |
1576 /* Connect the new motion signals. */ | |
1577 gtkwin->drag_motion_signal = | |
1578 g_signal_connect(G_OBJECT(widget), "motion_notify_event", | |
1579 G_CALLBACK(notebook_motion_cb), win); | |
1580 | |
1581 gtkwin->drag_leave_signal = | |
1582 g_signal_connect(G_OBJECT(widget), "leave_notify_event", | |
1583 G_CALLBACK(notebook_leave_cb), win); | |
1584 | |
1585 return FALSE; | |
1586 } | |
1587 | |
1588 static gboolean | |
1589 notebook_release_cb(GtkWidget *widget, GdkEventButton *e, | |
1590 struct gaim_window *win) | |
1591 { | |
1592 struct gaim_window *dest_win; | |
1593 struct gaim_gtk_window *gtkwin; | |
1594 struct gaim_gtk_window *dest_gtkwin; | |
1595 struct gaim_conversation *conv; | |
1596 GtkNotebook *dest_notebook; | |
1597 gint dest_page_num; | |
1598 | |
1599 /* | |
1600 * Don't check to make sure that the event's window matches the | |
1601 * widget's, because we may be getting an event passed on from the | |
1602 * close button. | |
1603 */ | |
1604 if (e->button != 1 && e->type != GDK_BUTTON_RELEASE) | |
1605 return FALSE; | |
1606 | |
1607 if (gdk_pointer_is_grabbed()) { | |
1608 gdk_pointer_ungrab(GDK_CURRENT_TIME); | |
1609 gtk_grab_remove(widget); | |
1610 } | |
1611 | |
1612 gtkwin = GAIM_GTK_WINDOW(win); | |
1613 | |
1614 if (!gtkwin->in_predrag && !gtkwin->in_drag) { | |
1615 return TRUE; | |
1616 } | |
1617 | |
1618 /* Disconnect the motion signal. */ | |
1619 if (gtkwin->drag_motion_signal) { | |
1620 g_signal_handler_disconnect(G_OBJECT(widget), | |
1621 gtkwin->drag_motion_signal); | |
1622 | |
1623 gtkwin->drag_motion_signal = 0; | |
1624 } | |
1625 | |
1626 /* | |
1627 * If we're in a pre-drag, we'll also need to disconnect the leave | |
1628 * signal. | |
1629 */ | |
1630 if (gtkwin->in_predrag) { | |
1631 gtkwin->in_predrag = FALSE; | |
1632 | |
1633 if (gtkwin->drag_leave_signal) { | |
1634 g_signal_handler_disconnect(G_OBJECT(widget), | |
1635 gtkwin->drag_leave_signal); | |
1636 | |
1637 gtkwin->drag_leave_signal = 0; | |
1638 } | |
1639 } | |
1640 | |
1641 /* If we're not in drag... */ | |
1642 /* We're perfectly normal people! */ | |
1643 if (!gtkwin->in_drag) { | |
1644 return FALSE; | |
1645 } | |
1646 | |
1647 gtkwin->in_drag = FALSE; | |
1648 | |
1649 dnd_hints_hide_all(); | |
1650 | |
4369
7e1fb422e5fd
[gaim-migrate @ 4635]
Christian Hammond <chipx86@chipx86.com>
parents:
4368
diff
changeset
|
1651 dest_win = gaim_gtkwin_get_at_xy(e->x_root, e->y_root); |
4359 | 1652 |
1653 conv = gaim_window_get_active_conversation(win); | |
1654 | |
1655 if (dest_win == NULL) { | |
1656 if (gaim_window_get_conversation_count(win) < 2) | |
1657 return FALSE; | |
1658 | |
1659 if (gaim_window_get_conversation_count(win) > 1) { | |
1660 /* Make a new window to stick this to. */ | |
1661 struct gaim_window *new_win; | |
1662 | |
1663 new_win = gaim_window_new(); | |
1664 gaim_window_remove_conversation(win, | |
1665 gaim_conversation_get_index(conv)); | |
1666 gaim_window_add_conversation(new_win, conv); | |
1667 gaim_window_show(new_win); | |
1668 } | |
1669 | |
1670 return TRUE; | |
1671 } | |
1672 | |
4369
7e1fb422e5fd
[gaim-migrate @ 4635]
Christian Hammond <chipx86@chipx86.com>
parents:
4368
diff
changeset
|
1673 dest_gtkwin = GAIM_GTK_WINDOW(dest_win); |
7e1fb422e5fd
[gaim-migrate @ 4635]
Christian Hammond <chipx86@chipx86.com>
parents:
4368
diff
changeset
|
1674 |
4359 | 1675 /* Get the destination notebook. */ |
1676 dest_notebook = GTK_NOTEBOOK(gtkwin->notebook); | |
1677 | |
1678 /* Get the destination page number. */ | |
1679 dest_page_num = gaim_gtkconv_get_dest_tab_at_xy(dest_win, | |
1680 e->x_root, e->y_root); | |
1681 | |
1682 if (win == dest_win) { | |
1683 gaim_window_move_conversation(win, | |
1684 gaim_conversation_get_index(conv), dest_page_num); | |
1685 } | |
1686 else { | |
1687 size_t pos; | |
1688 | |
1689 gaim_window_remove_conversation(win, | |
1690 gaim_conversation_get_index(conv)); | |
1691 | |
1692 pos = gaim_window_add_conversation(dest_win, conv); | |
1693 | |
1694 gaim_window_move_conversation(dest_win, pos, dest_page_num); | |
1695 | |
1696 gaim_window_switch_conversation(dest_win, dest_page_num); | |
1697 } | |
1698 | |
1699 gtk_widget_grab_focus(GAIM_GTK_CONVERSATION(conv)->entry); | |
1700 | |
1701 return TRUE; | |
1702 } | |
1703 | |
1704 static void | |
1705 switch_conv_cb(GtkNotebook *notebook, GtkWidget *page, gint page_num, | |
1706 gpointer user_data) | |
1707 { | |
1708 struct gaim_window *win; | |
1709 struct gaim_conversation *conv; | |
1710 struct gaim_gtk_conversation *gtkconv; | |
1711 struct gaim_gtk_window *gtkwin; | |
1712 struct gaim_connection *gc; | |
1713 | |
1714 if (gaim_gtk_is_state_locked()) | |
1715 return; | |
1716 | |
1717 win = (struct gaim_window *)user_data; | |
1718 | |
4598
a064e437d5eb
[gaim-migrate @ 4883]
Christian Hammond <chipx86@chipx86.com>
parents:
4596
diff
changeset
|
1719 conv = gaim_window_get_conversation_at(win, page_num); |
a064e437d5eb
[gaim-migrate @ 4883]
Christian Hammond <chipx86@chipx86.com>
parents:
4596
diff
changeset
|
1720 |
a064e437d5eb
[gaim-migrate @ 4883]
Christian Hammond <chipx86@chipx86.com>
parents:
4596
diff
changeset
|
1721 if (conv == NULL) |
a064e437d5eb
[gaim-migrate @ 4883]
Christian Hammond <chipx86@chipx86.com>
parents:
4596
diff
changeset
|
1722 return; |
a064e437d5eb
[gaim-migrate @ 4883]
Christian Hammond <chipx86@chipx86.com>
parents:
4596
diff
changeset
|
1723 |
4359 | 1724 gc = gaim_conversation_get_gc(conv); |
1725 gtkwin = GAIM_GTK_WINDOW(win); | |
1726 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
1727 | |
1728 gaim_conversation_set_unseen(conv, GAIM_UNSEEN_NONE); | |
1729 | |
4364
fa56829b9587
[gaim-migrate @ 4630]
Christian Hammond <chipx86@chipx86.com>
parents:
4363
diff
changeset
|
1730 if (gc != NULL) { |
fa56829b9587
[gaim-migrate @ 4630]
Christian Hammond <chipx86@chipx86.com>
parents:
4363
diff
changeset
|
1731 gtk_widget_set_sensitive(gtkwin->menu.insert_link, TRUE); |
fa56829b9587
[gaim-migrate @ 4630]
Christian Hammond <chipx86@chipx86.com>
parents:
4363
diff
changeset
|
1732 } |
fa56829b9587
[gaim-migrate @ 4630]
Christian Hammond <chipx86@chipx86.com>
parents:
4363
diff
changeset
|
1733 |
4359 | 1734 /* Update the menubar */ |
1735 if (gaim_conversation_get_type(conv) == GAIM_CONV_IM) { | |
1736 gtk_widget_set_sensitive(gtkwin->menu.view_history, TRUE); | |
1737 gtk_widget_set_sensitive(gtkwin->menu.insert_image, | |
1738 (gc && gc->prpl->options & OPT_PROTO_IM_IMAGE)); | |
1739 | |
1740 if (gtkwin->menu.send_as != NULL) | |
1741 update_send_as_selection(win); | |
1742 } | |
1743 else { | |
1744 gtk_widget_set_sensitive(gtkwin->menu.view_history, FALSE); | |
1745 gtk_widget_set_sensitive(gtkwin->menu.insert_image, FALSE); | |
1746 | |
1747 if (gtkwin->menu.send_as != NULL) | |
1748 gtk_widget_hide(gtkwin->menu.send_as); | |
1749 } | |
1750 | |
1751 gaim_gtk_set_state_lock(TRUE); | |
1752 | |
1753 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtkwin->menu.logging), | |
1754 gaim_conversation_is_logging(conv)); | |
1755 | |
1756 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtkwin->menu.sounds), | |
1757 gtkconv->make_sound); | |
1758 | |
1759 gaim_gtk_set_state_lock(FALSE); | |
1760 | |
1761 gtk_widget_grab_focus(gtkconv->entry); | |
4681 | 1762 |
1763 gtk_window_set_title(GTK_WINDOW(gtkwin->window), | |
1764 gtk_label_get_text(GTK_LABEL(gtkconv->tab_label))); | |
4359 | 1765 } |
1766 | |
1767 /************************************************************************** | |
1768 * Utility functions | |
1769 **************************************************************************/ | |
1770 static void | |
1771 do_bold(GtkWidget *bold, struct gaim_gtk_conversation *gtkconv) | |
1772 { | |
1773 if (gaim_gtk_is_state_locked()) | |
1774 return; | |
1775 | |
1776 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(bold))) | |
1777 gaim_gtk_surround(gtkconv, "<B>", "</B>"); | |
1778 else | |
1779 gaim_gtk_advance_past(gtkconv, "<B>", "</B>"); | |
1780 | |
1781 gtk_widget_grab_focus(gtkconv->entry); | |
1782 } | |
1783 | |
1784 static void | |
1785 do_italic(GtkWidget *italic, struct gaim_gtk_conversation *gtkconv) | |
1786 { | |
1787 if (gaim_gtk_is_state_locked()) | |
1788 return; | |
1789 | |
1790 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(italic))) | |
1791 gaim_gtk_surround(gtkconv, "<I>", "</I>"); | |
1792 else | |
1793 gaim_gtk_advance_past(gtkconv, "<I>", "</I>"); | |
1794 | |
1795 gtk_widget_grab_focus(gtkconv->entry); | |
1796 } | |
1797 | |
1798 static void | |
1799 do_underline(GtkWidget *underline, struct gaim_gtk_conversation *gtkconv) | |
1800 { | |
1801 if (gaim_gtk_is_state_locked()) | |
1802 return; | |
1803 | |
1804 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(underline))) | |
1805 gaim_gtk_surround(gtkconv, "<U>", "</U>"); | |
1806 else | |
1807 gaim_gtk_advance_past(gtkconv, "<U>", "</U>"); | |
1808 | |
1809 gtk_widget_grab_focus(gtkconv->entry); | |
1810 } | |
1811 | |
1812 static void | |
1813 do_small(GtkWidget *small, struct gaim_gtk_conversation *gtkconv) | |
1814 { | |
1815 if (gaim_gtk_is_state_locked()) | |
1816 return; | |
1817 | |
1818 gaim_gtk_surround(gtkconv, "<FONT SIZE=\"1\">", "</FONT>"); | |
1819 | |
1820 gtk_widget_grab_focus(gtkconv->entry); | |
1821 } | |
1822 | |
1823 static void | |
1824 do_normal(GtkWidget *small, struct gaim_gtk_conversation *gtkconv) | |
1825 { | |
1826 if (gaim_gtk_is_state_locked()) | |
1827 return; | |
1828 | |
1829 gaim_gtk_surround(gtkconv, "<FONT SIZE=\"3\">", "</FONT>"); | |
1830 | |
1831 gtk_widget_grab_focus(gtkconv->entry); | |
1832 } | |
1833 | |
1834 static void | |
1835 do_big(GtkWidget *small, struct gaim_gtk_conversation *gtkconv) | |
1836 { | |
1837 if (gaim_gtk_is_state_locked()) | |
1838 return; | |
1839 | |
1840 gaim_gtk_surround(gtkconv, "<FONT SIZE=\"5\">", "</FONT>"); | |
1841 | |
1842 gtk_widget_grab_focus(gtkconv->entry); | |
1843 } | |
1844 | |
1845 static void | |
1846 toggle_font(GtkWidget *font, struct gaim_conversation *conv) | |
1847 { | |
1848 struct gaim_gtk_conversation *gtkconv; | |
1849 | |
1850 if (gaim_gtk_is_state_locked()) | |
1851 return; | |
1852 | |
1853 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
1854 | |
1855 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(font))) | |
1856 show_font_dialog(conv, font); | |
1857 else if (gtkconv->dialogs.fg_color != NULL) | |
1858 cancel_font(font, conv); | |
1859 else | |
1860 gaim_gtk_advance_past(gtkconv, "<FONT FACE>", "</FONT>"); | |
1861 } | |
1862 | |
1863 static void | |
1864 toggle_fg_color(GtkWidget *color, struct gaim_conversation *conv) | |
1865 { | |
1866 struct gaim_gtk_conversation *gtkconv; | |
1867 | |
1868 if (gaim_gtk_is_state_locked()) | |
1869 return; | |
1870 | |
1871 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
1872 | |
1873 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(color))) | |
1874 show_fgcolor_dialog(conv, color); | |
1875 else if (gtkconv->dialogs.fg_color != NULL) | |
1876 cancel_fgcolor(color, conv); | |
1877 else | |
1878 gaim_gtk_advance_past(gtkconv, "<FONT COLOR>", "</FONT>"); | |
1879 } | |
1880 | |
1881 static void | |
1882 toggle_bg_color(GtkWidget *color, struct gaim_conversation *conv) | |
1883 { | |
1884 struct gaim_gtk_conversation *gtkconv; | |
1885 | |
1886 if (gaim_gtk_is_state_locked()) | |
1887 return; | |
1888 | |
1889 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
1890 | |
1891 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(color))) | |
1892 show_bgcolor_dialog(conv, color); | |
1893 else if (gtkconv->dialogs.bg_color != NULL) | |
1894 cancel_bgcolor(color, conv); | |
1895 else | |
1896 gaim_gtk_advance_past(gtkconv, "<BODY BGCOLOR>", "</BODY>"); | |
1897 } | |
1898 | |
1899 static void | |
1900 check_everything(GtkTextBuffer *buffer) | |
1901 { | |
1902 struct gaim_conversation *conv; | |
1903 struct gaim_gtk_conversation *gtkconv; | |
1904 | |
1905 conv = (struct gaim_conversation *)g_object_get_data(G_OBJECT(buffer), | |
1906 "user_data"); | |
1907 | |
1908 if (conv == NULL) | |
1909 return; | |
1910 | |
1911 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
1912 | |
1913 /* CONV TODO */ | |
1914 } | |
1915 | |
1916 static void | |
1917 quiet_set(GtkWidget *tb, gboolean active) | |
1918 { | |
1919 gaim_gtk_set_state_lock(TRUE); | |
1920 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tb), active); | |
1921 gaim_gtk_set_state_lock(FALSE); | |
1922 } | |
1923 | |
1924 static void | |
1925 got_typing_keypress(struct gaim_conversation *conv, gboolean first) | |
1926 { | |
1927 struct gaim_im *im; | |
1928 | |
1929 /* | |
1930 * We know we got something, so we at least have to make sure we don't | |
1931 * send TYPED any time soon. | |
1932 */ | |
1933 | |
1934 im = GAIM_IM(conv); | |
1935 | |
1936 if (gaim_im_get_type_again_timeout(im)) | |
1937 gaim_im_stop_type_again_timeout(im); | |
1938 | |
1939 gaim_im_start_type_again_timeout(im); | |
1940 | |
1941 if (first || (gaim_im_get_type_again(im) != 0 && | |
1942 time(NULL) > gaim_im_get_type_again(im))) { | |
1943 | |
1944 int timeout = serv_send_typing(gaim_conversation_get_gc(conv), | |
1945 (char *)gaim_conversation_get_name(conv), | |
1946 TYPING); | |
1947 | |
1948 if (timeout) | |
1949 gaim_im_set_type_again(im, time(NULL) + timeout); | |
1950 else | |
1951 gaim_im_set_type_again(im, 0); | |
1952 } | |
1953 } | |
1954 | |
1955 static void | |
1956 update_send_as_selection(struct gaim_window *win) | |
1957 { | |
4491 | 1958 struct gaim_account *account; |
4359 | 1959 struct gaim_conversation *conv; |
1960 struct gaim_gtk_window *gtkwin; | |
1961 GtkWidget *menu; | |
1962 GList *child; | |
1963 | |
1964 conv = gaim_window_get_active_conversation(win); | |
1965 | |
1966 if (conv == NULL) | |
1967 return; | |
1968 | |
4491 | 1969 account = gaim_conversation_get_account(conv); |
4359 | 1970 gtkwin = GAIM_GTK_WINDOW(win); |
1971 | |
4491 | 1972 if (account == NULL) |
4466
473de7371a97
[gaim-migrate @ 4741]
Christian Hammond <chipx86@chipx86.com>
parents:
4465
diff
changeset
|
1973 return; |
473de7371a97
[gaim-migrate @ 4741]
Christian Hammond <chipx86@chipx86.com>
parents:
4465
diff
changeset
|
1974 |
4364
fa56829b9587
[gaim-migrate @ 4630]
Christian Hammond <chipx86@chipx86.com>
parents:
4363
diff
changeset
|
1975 if (gtkwin->menu.send_as == NULL) |
fa56829b9587
[gaim-migrate @ 4630]
Christian Hammond <chipx86@chipx86.com>
parents:
4363
diff
changeset
|
1976 return; |
fa56829b9587
[gaim-migrate @ 4630]
Christian Hammond <chipx86@chipx86.com>
parents:
4363
diff
changeset
|
1977 |
4359 | 1978 gtk_widget_show(gtkwin->menu.send_as); |
1979 | |
1980 menu = gtk_menu_item_get_submenu( | |
1981 GTK_MENU_ITEM(gtkwin->menu.send_as)); | |
1982 | |
1983 gaim_gtk_set_state_lock(TRUE); | |
1984 | |
1985 for (child = gtk_container_get_children(GTK_CONTAINER(menu)); | |
1986 child != NULL; | |
1987 child = child->next) { | |
1988 | |
1989 GtkWidget *item = child->data; | |
4673 | 1990 struct gaim_account *item_account = g_object_get_data(G_OBJECT(item), |
1991 "gaim_account"); | |
1992 | |
1993 if (account == item_account) { | |
4359 | 1994 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE); |
1995 break; | |
1996 } | |
1997 } | |
1998 | |
1999 gaim_gtk_set_state_lock(FALSE); | |
2000 } | |
2001 | |
2002 static void | |
4360
c435a29370b8
[gaim-migrate @ 4626]
Christian Hammond <chipx86@chipx86.com>
parents:
4359
diff
changeset
|
2003 generate_send_as_items(struct gaim_window *win, |
c435a29370b8
[gaim-migrate @ 4626]
Christian Hammond <chipx86@chipx86.com>
parents:
4359
diff
changeset
|
2004 struct gaim_conversation *deleted_conv) |
4359 | 2005 { |
2006 struct gaim_gtk_window *gtkwin; | |
2007 GtkWidget *menu; | |
2008 GtkWidget *menuitem; | |
2009 GSList *gcs; | |
2010 GList *convs; | |
2011 GSList *group = NULL; | |
2012 gboolean first_offline = TRUE; | |
2013 gboolean found_online = FALSE; | |
4669
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2014 GtkSizeGroup *sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); |
4359 | 2015 |
2016 gtkwin = GAIM_GTK_WINDOW(win); | |
2017 | |
2018 if (gtkwin->menu.send_as != NULL) | |
2019 gtk_widget_destroy(gtkwin->menu.send_as); | |
2020 | |
2021 /* See if we have > 1 connection active. */ | |
2022 if (g_slist_length(connections) < 2) { | |
2023 /* Now make sure we don't have any Offline entries. */ | |
2024 gboolean found_offline = FALSE; | |
2025 | |
2026 for (convs = gaim_get_conversations(); | |
2027 convs != NULL; | |
2028 convs = convs->next) { | |
2029 | |
2030 struct gaim_conversation *conv; | |
4491 | 2031 struct gaim_account *account; |
2032 | |
4359 | 2033 conv = (struct gaim_conversation *)convs->data; |
4491 | 2034 account = gaim_conversation_get_account(conv); |
2035 | |
2036 if (account->gc == NULL) { | |
4359 | 2037 found_offline = TRUE; |
2038 break; | |
2039 } | |
2040 } | |
2041 | |
2042 if (!found_offline) { | |
2043 gtkwin->menu.send_as = NULL; | |
2044 return; | |
2045 } | |
2046 } | |
2047 | |
2048 /* Build the Send As menu */ | |
2049 gtkwin->menu.send_as = gtk_menu_item_new_with_mnemonic(_("_Send As")); | |
2050 gtk_widget_show(gtkwin->menu.send_as); | |
2051 | |
2052 menu = gtk_menu_new(); | |
2053 | |
2054 gtk_menu_shell_append(GTK_MENU_SHELL(gtkwin->menu.menubar), | |
2055 gtkwin->menu.send_as); | |
2056 gtk_menu_item_set_submenu(GTK_MENU_ITEM(gtkwin->menu.send_as), menu); | |
2057 | |
2058 gtk_widget_show(menu); | |
2059 | |
2060 /* Fill it with entries. */ | |
2061 for (gcs = connections; gcs != NULL; gcs = gcs->next) { | |
4668
6e7196dcfd37
[gaim-migrate @ 4979]
Christian Hammond <chipx86@chipx86.com>
parents:
4640
diff
changeset
|
2062 |
4359 | 2063 struct gaim_connection *gc; |
4669
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2064 GtkWidget *box; |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2065 GtkWidget *label; |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2066 GtkWidget *image; |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2067 GdkPixmap *pixmap = NULL; |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2068 GdkBitmap *mask = NULL; |
4359 | 2069 |
2070 found_online = TRUE; | |
2071 | |
2072 gc = (struct gaim_connection *)gcs->data; | |
2073 | |
4669
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2074 /* Create a pixmap for the protocol icon. */ |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2075 create_prpl_icon(gtkwin->window, gc, &pixmap, &mask); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2076 |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2077 /* Now convert it to GtkImage */ |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2078 if (pixmap == NULL) |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2079 image = gtk_image_new(); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2080 else |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2081 image = gtk_image_new_from_pixmap(pixmap, mask); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2082 |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2083 gtk_size_group_add_widget(sg, image); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2084 |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2085 if (pixmap != NULL) g_object_unref(pixmap); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2086 if (mask != NULL) g_object_unref(mask); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2087 |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2088 /* Make our menu item */ |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2089 menuitem = gtk_radio_menu_item_new_with_label(group, gc->username); |
4359 | 2090 group = gtk_radio_menu_item_group(GTK_RADIO_MENU_ITEM(menuitem)); |
2091 | |
4669
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2092 /* Do some evil, see some evil, speak some evil. */ |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2093 box = gtk_hbox_new(FALSE, 0); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2094 |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2095 label = gtk_bin_get_child(GTK_BIN(menuitem)); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2096 g_object_ref(label); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2097 gtk_container_remove(GTK_CONTAINER(menuitem), label); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2098 |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2099 gtk_box_pack_start(GTK_BOX(box), image, FALSE, FALSE, 0); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2100 gtk_box_pack_start(GTK_BOX(box), label, TRUE, TRUE, 4); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2101 |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2102 g_object_unref(label); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2103 |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2104 gtk_container_add(GTK_CONTAINER(menuitem), box); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2105 |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2106 gtk_widget_show(label); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2107 gtk_widget_show(image); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2108 gtk_widget_show(box); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2109 |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2110 /* Set our data and callbacks. */ |
4359 | 2111 g_object_set_data(G_OBJECT(menuitem), "user_data", win); |
4673 | 2112 g_object_set_data(G_OBJECT(menuitem), "gaim_account", gc->account); |
4359 | 2113 |
2114 g_signal_connect(G_OBJECT(menuitem), "activate", | |
4673 | 2115 G_CALLBACK(menu_conv_sel_send_cb), NULL); |
4359 | 2116 |
2117 gtk_widget_show(menuitem); | |
2118 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
2119 } | |
2120 | |
2121 /* | |
2122 * Fill it with any accounts that still has an open (yet disabled) window | |
2123 * (signed off accounts with a window open). | |
2124 */ | |
2125 for (convs = gaim_get_conversations(); | |
2126 convs != NULL; | |
2127 convs = convs->next) { | |
2128 | |
2129 struct gaim_conversation *conv; | |
4491 | 2130 struct gaim_account *account; |
4669
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2131 GtkWidget *box; |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2132 GtkWidget *label; |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2133 GtkWidget *image; |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2134 GdkPixmap *pixmap = NULL; |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2135 GdkBitmap *mask = NULL; |
4359 | 2136 |
2137 conv = (struct gaim_conversation *)convs->data; | |
4360
c435a29370b8
[gaim-migrate @ 4626]
Christian Hammond <chipx86@chipx86.com>
parents:
4359
diff
changeset
|
2138 |
c435a29370b8
[gaim-migrate @ 4626]
Christian Hammond <chipx86@chipx86.com>
parents:
4359
diff
changeset
|
2139 if (conv == deleted_conv) |
c435a29370b8
[gaim-migrate @ 4626]
Christian Hammond <chipx86@chipx86.com>
parents:
4359
diff
changeset
|
2140 continue; |
c435a29370b8
[gaim-migrate @ 4626]
Christian Hammond <chipx86@chipx86.com>
parents:
4359
diff
changeset
|
2141 |
4491 | 2142 account = gaim_conversation_get_account(conv); |
2143 | |
2144 if (account->gc == NULL) { | |
4359 | 2145 if (first_offline && found_online) { |
2146 menuitem = gtk_separator_menu_item_new(); | |
2147 gtk_widget_show(menuitem); | |
2148 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
2149 | |
2150 first_offline = FALSE; | |
2151 } | |
2152 | |
4669
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2153 /* Create a pixmap for the protocol icon. */ |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2154 create_prpl_icon(gtkwin->window, account->gc, &pixmap, &mask); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2155 |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2156 /* Now convert it to GtkImage */ |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2157 if (pixmap == NULL) |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2158 image = gtk_image_new(); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2159 else |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2160 image = gtk_image_new_from_pixmap(pixmap, mask); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2161 |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2162 gtk_size_group_add_widget(sg, image); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2163 |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2164 if (pixmap != NULL) g_object_unref(pixmap); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2165 if (mask != NULL) g_object_unref(mask); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2166 |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2167 /* Make our menu item */ |
4359 | 2168 menuitem = gtk_radio_menu_item_new_with_label(group, |
4491 | 2169 account->username); |
4359 | 2170 group = gtk_radio_menu_item_group(GTK_RADIO_MENU_ITEM(menuitem)); |
2171 | |
4669
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2172 /* Do some evil, see some evil, speak some evil. */ |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2173 box = gtk_hbox_new(FALSE, 0); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2174 |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2175 label = gtk_bin_get_child(GTK_BIN(menuitem)); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2176 g_object_ref(label); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2177 gtk_container_remove(GTK_CONTAINER(menuitem), label); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2178 |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2179 gtk_box_pack_start(GTK_BOX(box), image, FALSE, FALSE, 0); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2180 gtk_box_pack_start(GTK_BOX(box), label, TRUE, TRUE, 4); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2181 |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2182 g_object_unref(label); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2183 |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2184 gtk_container_add(GTK_CONTAINER(menuitem), box); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2185 |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2186 gtk_widget_show(label); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2187 gtk_widget_show(image); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2188 gtk_widget_show(box); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2189 |
4359 | 2190 gtk_widget_set_sensitive(menuitem, FALSE); |
4674 | 2191 g_object_set_data(G_OBJECT(menuitem), "gaim_account", account); |
4359 | 2192 |
2193 gtk_widget_show(menuitem); | |
2194 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
2195 } | |
2196 } | |
2197 | |
4669
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2198 g_object_unref(sg); |
d715736164ae
[gaim-migrate @ 4980]
Christian Hammond <chipx86@chipx86.com>
parents:
4668
diff
changeset
|
2199 |
4359 | 2200 gtk_widget_show(gtkwin->menu.send_as); |
2201 update_send_as_selection(win); | |
2202 } | |
2203 | |
2204 static GList * | |
2205 generate_invite_user_names(struct gaim_connection *gc) | |
2206 { | |
2207 GSList *grp; | |
2208 GSList *bl; | |
2209 struct group *g; | |
2210 struct buddy *buddy; | |
2211 static GList *tmp = NULL; | |
2212 | |
2213 if (tmp) | |
2214 g_list_free(tmp); | |
2215 | |
2216 tmp = g_list_append(NULL, ""); | |
2217 | |
2218 if (gc != NULL) { | |
2219 for (grp = groups; grp != NULL; grp = grp->next) { | |
2220 g = (struct group *)grp->data; | |
2221 | |
2222 for (bl = g->members; bl != NULL; bl = bl->next) { | |
2223 buddy = (struct buddy *)bl->data; | |
2224 | |
2225 if (buddy->present) | |
2226 tmp = g_list_append(tmp, buddy->name); | |
2227 } | |
2228 } | |
2229 } | |
2230 | |
2231 return tmp; | |
2232 } | |
2233 | |
2234 static void | |
2235 add_chat_buddy_common(struct gaim_conversation *conv, const char *name, | |
2236 int pos) | |
2237 { | |
2238 struct gaim_gtk_conversation *gtkconv; | |
2239 struct gaim_gtk_chat_pane *gtkchat; | |
2240 struct gaim_chat *chat; | |
2241 GtkTreeIter iter; | |
2242 GtkListStore *ls; | |
2243 | |
2244 chat = GAIM_CHAT(conv); | |
2245 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
2246 gtkchat = gtkconv->u.chat; | |
2247 | |
2248 ls = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list))); | |
2249 | |
2250 gtk_list_store_append(ls, &iter); | |
2251 gtk_list_store_set(ls, &iter, 0, | |
2252 (gaim_chat_is_user_ignored(chat, name) ? "X" : " "), | |
2253 1, name, -1); | |
2254 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(ls), 1, | |
2255 GTK_SORT_ASCENDING); | |
2256 } | |
2257 | |
2258 static void | |
2259 tab_complete(struct gaim_conversation *conv) | |
2260 { | |
2261 struct gaim_gtk_conversation *gtkconv; | |
2262 struct gaim_chat *chat; | |
2263 GtkTextIter cursor, word_start, start_buffer; | |
2264 int start; | |
2265 int most_matched = -1; | |
2266 char *entered, *partial = NULL; | |
2267 char *text; | |
2268 GList *matches = NULL; | |
2269 GList *nicks = NULL; | |
2270 | |
2271 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
2272 chat = GAIM_CHAT(conv); | |
2273 | |
2274 gtk_text_buffer_get_start_iter(gtkconv->entry_buffer, &start_buffer); | |
2275 gtk_text_buffer_get_iter_at_mark(gtkconv->entry_buffer, &cursor, | |
2276 gtk_text_buffer_get_insert(gtkconv->entry_buffer)); | |
2277 | |
2278 word_start = cursor; | |
2279 | |
2280 /* if there's nothing there just return */ | |
2281 if (!gtk_text_iter_compare(&cursor, &start_buffer)) | |
2282 return; | |
2283 | |
2284 text = gtk_text_buffer_get_text(gtkconv->entry_buffer, &start_buffer, | |
2285 &cursor, FALSE); | |
2286 | |
2287 /* if we're at the end of ": " we need to move back 2 spaces */ | |
2288 start = strlen(text) - 1; | |
2289 | |
2290 if (strlen(text) >= 2 && !strncmp(&text[start-1], ": ", 2)) | |
2291 gtk_text_iter_backward_chars(&word_start, 2); | |
2292 | |
2293 /* find the start of the word that we're tabbing */ | |
2294 while (start >= 0 && text[start] != ' ') { | |
2295 gtk_text_iter_backward_char(&word_start); | |
2296 start--; | |
2297 } | |
2298 | |
2299 g_free(text); | |
2300 | |
2301 entered = gtk_text_buffer_get_text(gtkconv->entry_buffer, &word_start, | |
2302 &cursor, FALSE); | |
2303 | |
2304 if (chat_options & OPT_CHAT_OLD_STYLE_TAB) { | |
2305 if (strlen(entered) >= 2 && | |
2306 !strncmp(": ", entered + strlen(entered) - 2, 2)) { | |
2307 | |
2308 entered[strlen(entered) - 2] = 0; | |
2309 } | |
2310 } | |
2311 | |
2312 if (!strlen(entered)) { | |
2313 g_free(entered); | |
2314 return; | |
2315 } | |
2316 | |
2317 for (nicks = gaim_chat_get_users(chat); | |
2318 nicks != NULL; | |
2319 nicks = nicks->next) { | |
2320 | |
2321 char *nick = nicks->data; | |
2322 /* this checks to see if the current nick could be a completion */ | |
2323 if (g_strncasecmp(nick, entered, strlen(entered))) { | |
4621
69f028a6f357
[gaim-migrate @ 4912]
Christian Hammond <chipx86@chipx86.com>
parents:
4608
diff
changeset
|
2324 if (*nick != '+' && *nick != '@' && *nick != '%') |
4359 | 2325 continue; |
2326 | |
2327 if (g_strncasecmp(nick + 1, entered, strlen(entered))) { | |
2328 if (nick[0] != '@' || nick[1] != '+') | |
2329 continue; | |
2330 | |
2331 if (g_strncasecmp(nick + 2, entered, strlen(entered))) | |
2332 continue; | |
2333 else | |
2334 nick += 2; | |
2335 } | |
2336 else | |
2337 nick++; | |
2338 } | |
2339 | |
2340 /* if we're here, it's a possible completion */ | |
2341 | |
2342 /* if we're doing old-style, just fill in the completion */ | |
2343 if (chat_options & OPT_CHAT_OLD_STYLE_TAB) { | |
2344 gtk_text_buffer_delete(gtkconv->entry_buffer, | |
2345 &word_start, &cursor); | |
2346 | |
2347 if (strlen(nick) == strlen(entered)) { | |
2348 nicks = (nicks->next | |
2349 ? nicks->next | |
2350 : gaim_chat_get_users(chat)); | |
2351 | |
2352 nick = nicks->data; | |
2353 | |
2354 if (*nick == '@') nick++; | |
4621
69f028a6f357
[gaim-migrate @ 4912]
Christian Hammond <chipx86@chipx86.com>
parents:
4608
diff
changeset
|
2355 if (*nick == '%') nick++; |
4359 | 2356 if (*nick == '+') nick++; |
2357 } | |
2358 | |
2359 gtk_text_buffer_get_start_iter(gtkconv->entry_buffer, | |
2360 &start_buffer); | |
2361 gtk_text_buffer_get_iter_at_mark(gtkconv->entry_buffer, &cursor, | |
2362 gtk_text_buffer_get_insert(gtkconv->entry_buffer)); | |
2363 | |
2364 if (!gtk_text_iter_compare(&cursor, &start_buffer)) { | |
2365 char *tmp = g_strdup_printf("%s: ", nick); | |
2366 gtk_text_buffer_insert_at_cursor(gtkconv->entry_buffer, | |
2367 tmp, -1); | |
2368 g_free(tmp); | |
2369 } | |
2370 else | |
2371 gtk_text_buffer_insert_at_cursor(gtkconv->entry_buffer, | |
2372 nick, -1); | |
2373 | |
2374 g_free(entered); | |
2375 | |
2376 return; | |
2377 } | |
2378 | |
2379 /* we're only here if we're doing new style */ | |
2380 if (most_matched == -1) { | |
2381 /* | |
2382 * this will only get called once, since from now | |
2383 * on most_matched is >= 0 | |
2384 */ | |
2385 most_matched = strlen(nick); | |
2386 partial = g_strdup(nick); | |
2387 } | |
2388 else if (most_matched) { | |
2389 while (g_strncasecmp(nick, partial, most_matched)) | |
2390 most_matched--; | |
2391 | |
2392 partial[most_matched] = 0; | |
2393 } | |
2394 | |
2395 matches = g_list_append(matches, nick); | |
2396 } | |
2397 | |
2398 /* we're only here if we're doing new style */ | |
2399 | |
2400 /* if there weren't any matches, return */ | |
2401 if (!matches) { | |
2402 /* if matches isn't set partials won't be either */ | |
2403 g_free(entered); | |
2404 return; | |
2405 } | |
2406 | |
2407 gtk_text_buffer_delete(gtkconv->entry_buffer, &word_start, &cursor); | |
2408 | |
2409 if (!matches->next) { | |
2410 /* there was only one match. fill it in. */ | |
2411 gtk_text_buffer_get_start_iter(gtkconv->entry_buffer, &start_buffer); | |
2412 gtk_text_buffer_get_iter_at_mark(gtkconv->entry_buffer, &cursor, | |
2413 gtk_text_buffer_get_insert(gtkconv->entry_buffer)); | |
2414 | |
2415 if (!gtk_text_iter_compare(&cursor, &start_buffer)) { | |
2416 char *tmp = g_strdup_printf("%s: ", (char *)matches->data); | |
2417 gtk_text_buffer_insert_at_cursor(gtkconv->entry_buffer, tmp, -1); | |
2418 g_free(tmp); | |
2419 } | |
2420 else | |
2421 gtk_text_buffer_insert_at_cursor(gtkconv->entry_buffer, | |
2422 matches->data, -1); | |
2423 | |
2424 matches = g_list_remove(matches, matches->data); | |
2425 } | |
2426 else { | |
2427 /* | |
2428 * there were lots of matches, fill in as much as possible | |
2429 * and display all of them | |
2430 */ | |
2431 char *addthis = g_malloc0(1); | |
2432 | |
2433 while (matches) { | |
2434 char *tmp = addthis; | |
2435 addthis = g_strconcat(tmp, matches->data, " ", NULL); | |
2436 g_free(tmp); | |
2437 matches = g_list_remove(matches, matches->data); | |
2438 } | |
2439 | |
2440 gaim_conversation_write(conv, NULL, addthis, -1, WFLAG_NOLOG, | |
2441 time(NULL)); | |
2442 gtk_text_buffer_insert_at_cursor(gtkconv->entry_buffer, partial, -1); | |
2443 g_free(addthis); | |
2444 } | |
2445 | |
2446 g_free(entered); | |
2447 g_free(partial); | |
2448 } | |
2449 | |
2450 static gboolean | |
2451 meify(char *message, size_t len) | |
2452 { | |
2453 /* | |
2454 * Read /me-ify: If the message (post-HTML) starts with /me, | |
2455 * remove the "/me " part of it (including that space) and return TRUE. | |
2456 */ | |
2457 char *c; | |
2458 gboolean inside_html = 0; | |
2459 | |
2460 if (message == NULL) | |
2461 return FALSE; /* Umm.. this would be very bad if this happens. */ | |
2462 | |
2463 if (len == -1) | |
2464 len = strlen(message); | |
2465 | |
2466 for (c = message; *c != '\0'; c++, len--) { | |
2467 if (inside_html) { | |
2468 if (*c == '>') | |
2469 inside_html = FALSE; | |
2470 } | |
2471 else { | |
2472 if (*c == '<') | |
2473 inside_html = TRUE; | |
2474 else | |
2475 break; | |
2476 } | |
2477 } | |
2478 | |
2479 if (*c != '\0' && !g_strncasecmp(c, "/me ", 4)) { | |
2480 memmove(c, c + 4, len - 3); | |
2481 | |
2482 return TRUE; | |
2483 } | |
2484 | |
2485 return FALSE; | |
2486 } | |
2487 | |
2488 static GtkItemFactoryEntry menu_items[] = | |
2489 { | |
2490 /* Conversation menu */ | |
4596 | 2491 { N_("/_Conversation"), NULL, NULL, 0, "<Branch>" }, |
2492 { N_("/Conversation/_Save As..."), NULL, menu_save_as_cb, 0, | |
4359 | 2493 "<StockItem>", GTK_STOCK_SAVE_AS }, |
4596 | 2494 { N_("/Conversation/View _History..."), NULL, menu_view_history_cb, 0, NULL }, |
4359 | 2495 { "/Conversation/sep1", NULL, NULL, 0, "<Separator>" }, |
4596 | 2496 { N_("/Conversation/Insert _URL..."), NULL, menu_insert_link_cb, 0, |
4359 | 2497 "<StockItem>", GAIM_STOCK_LINK }, |
4596 | 2498 { N_("/Conversation/Insert _Image..."), NULL, menu_insert_image_cb, 0, |
4359 | 2499 "<StockItem>", GAIM_STOCK_IMAGE }, |
2500 { "/Conversation/sep2", NULL, NULL, 0, "<Separator>" }, | |
4596 | 2501 { N_("/Conversation/_Close"), NULL, menu_close_conv_cb, 0, |
4359 | 2502 "<StockItem>", GTK_STOCK_CLOSE }, |
2503 | |
2504 /* Options */ | |
4596 | 2505 { N_("/_Options"), NULL, NULL, 0, "<Branch>" }, |
2506 { N_("/Options/Enable _Logging"), NULL, menu_logging_cb, 0, "<CheckItem>" }, | |
2507 { N_("/Options/Enable _Sounds"), NULL, menu_sounds_cb, 0, "<CheckItem>" }, | |
4359 | 2508 }; |
2509 | |
4602
4128761bacb8
[gaim-migrate @ 4889]
Christian Hammond <chipx86@chipx86.com>
parents:
4598
diff
changeset
|
2510 static const int menu_item_count = |
4359 | 2511 sizeof(menu_items) / sizeof(*menu_items); |
2512 | |
4602
4128761bacb8
[gaim-migrate @ 4889]
Christian Hammond <chipx86@chipx86.com>
parents:
4598
diff
changeset
|
2513 static char * |
4128761bacb8
[gaim-migrate @ 4889]
Christian Hammond <chipx86@chipx86.com>
parents:
4598
diff
changeset
|
2514 item_factory_translate_func (const char *path, gpointer func_data) |
4128761bacb8
[gaim-migrate @ 4889]
Christian Hammond <chipx86@chipx86.com>
parents:
4598
diff
changeset
|
2515 { |
4128761bacb8
[gaim-migrate @ 4889]
Christian Hammond <chipx86@chipx86.com>
parents:
4598
diff
changeset
|
2516 return _(path); |
4128761bacb8
[gaim-migrate @ 4889]
Christian Hammond <chipx86@chipx86.com>
parents:
4598
diff
changeset
|
2517 } |
4128761bacb8
[gaim-migrate @ 4889]
Christian Hammond <chipx86@chipx86.com>
parents:
4598
diff
changeset
|
2518 |
4359 | 2519 static GtkWidget * |
2520 setup_menubar(struct gaim_window *win) | |
2521 { | |
2522 struct gaim_gtk_window *gtkwin; | |
2523 GtkWidget *hb; | |
2524 | |
2525 gtkwin = GAIM_GTK_WINDOW(win); | |
2526 | |
2527 /* Create the handle box. */ | |
2528 hb = gtk_handle_box_new(); | |
2529 | |
4630 | 2530 gtkwin->menu.item_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, |
2531 "<main>", NULL); | |
2532 | |
2533 gtk_item_factory_set_translate_func (gtkwin->menu.item_factory, | |
4602
4128761bacb8
[gaim-migrate @ 4889]
Christian Hammond <chipx86@chipx86.com>
parents:
4598
diff
changeset
|
2534 item_factory_translate_func, |
4128761bacb8
[gaim-migrate @ 4889]
Christian Hammond <chipx86@chipx86.com>
parents:
4598
diff
changeset
|
2535 NULL, NULL); |
4630 | 2536 |
2537 gtk_item_factory_create_items(gtkwin->menu.item_factory, menu_item_count, | |
4359 | 2538 menu_items, win); |
2539 | |
4630 | 2540 gtkwin->menu.menubar = gtk_item_factory_get_widget(gtkwin->menu.item_factory, |
2541 "<main>"); | |
2542 gtkwin->menu.view_history = gtk_item_factory_get_widget(gtkwin->menu.item_factory, | |
4359 | 2543 "/Conversation/View History..."); |
4630 | 2544 gtkwin->menu.insert_link = gtk_item_factory_get_widget(gtkwin->menu.item_factory, |
4359 | 2545 "/Conversation/Insert URL..."); |
4630 | 2546 gtkwin->menu.insert_image = gtk_item_factory_get_widget(gtkwin->menu.item_factory, |
4359 | 2547 "/Conversation/Insert Image..."); |
4630 | 2548 gtkwin->menu.logging = gtk_item_factory_get_widget(gtkwin->menu.item_factory, |
4359 | 2549 "/Options/Enable Logging"); |
4630 | 2550 gtkwin->menu.sounds = gtk_item_factory_get_widget(gtkwin->menu.item_factory, |
4359 | 2551 "/Options/Enable Sounds"); |
2552 | |
4360
c435a29370b8
[gaim-migrate @ 4626]
Christian Hammond <chipx86@chipx86.com>
parents:
4359
diff
changeset
|
2553 generate_send_as_items(win, NULL); |
4359 | 2554 |
2555 gtk_container_add(GTK_CONTAINER(hb), gtkwin->menu.menubar); | |
2556 | |
2557 gtk_widget_show(gtkwin->menu.menubar); | |
2558 gtk_widget_show(hb); | |
2559 | |
2560 return hb; | |
2561 } | |
2562 | |
2563 static void | |
2564 setup_im_buttons(struct gaim_conversation *conv, GtkWidget *parent) | |
2565 { | |
2566 struct gaim_connection *gc; | |
2567 struct gaim_gtk_conversation *gtkconv; | |
2568 struct gaim_gtk_im_pane *gtkim; | |
2569 GaimConversationType type = GAIM_CONV_IM; | |
2570 | |
2571 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
2572 gtkim = gtkconv->u.im; | |
2573 gc = gaim_conversation_get_gc(conv); | |
2574 | |
2575 /* From right to left... */ | |
2576 | |
2577 /* Send button */ | |
2578 gtkconv->send = gaim_gtk_change_text(_("Send"), gtkconv->send, | |
2579 GAIM_STOCK_SEND, type); | |
2580 gtk_tooltips_set_tip(gtkconv->tooltips, gtkconv->send, _("Send"), NULL); | |
2581 | |
2582 gtk_box_pack_end(GTK_BOX(parent), gtkconv->send, FALSE, FALSE, 0); | |
2583 | |
2584 /* Separator */ | |
2585 if (gtkim->sep2 != NULL) | |
2586 gtk_widget_destroy(gtkim->sep2); | |
2587 | |
2588 gtkim->sep2 = gtk_vseparator_new(); | |
2589 gtk_box_pack_end(GTK_BOX(parent), gtkim->sep2, FALSE, TRUE, 0); | |
2590 gtk_widget_show(gtkim->sep2); | |
2591 | |
2592 /* Now, um, just kind of all over the place. Huh? */ | |
2593 | |
2594 /* Add button */ | |
4608 | 2595 if (find_buddy(gaim_conversation_get_account(conv), |
4359 | 2596 gaim_conversation_get_name(conv)) == NULL) { |
2597 gtkim->add = gaim_gtk_change_text(_("Add"), gtkim->add, | |
2598 GTK_STOCK_ADD, type); | |
2599 gtk_tooltips_set_tip(gtkconv->tooltips, gtkim->add, | |
4370
d856987c72ca
[gaim-migrate @ 4636]
Christian Hammond <chipx86@chipx86.com>
parents:
4369
diff
changeset
|
2600 _("Add the user to your buddy list"), NULL); |
4359 | 2601 } |
2602 else { | |
2603 gtkim->add = gaim_gtk_change_text(_("Remove"), gtkim->add, | |
2604 GTK_STOCK_REMOVE, type); | |
2605 gtk_tooltips_set_tip(gtkconv->tooltips, gtkim->add, | |
4370
d856987c72ca
[gaim-migrate @ 4636]
Christian Hammond <chipx86@chipx86.com>
parents:
4369
diff
changeset
|
2606 _("Remove the user from your buddy list"), NULL); |
4359 | 2607 } |
2608 | |
2609 gtk_box_pack_start(GTK_BOX(parent), gtkim->add, | |
2610 FALSE, FALSE, 0); | |
2611 | |
2612 /* Warn button */ | |
2613 gtkim->warn = gaim_gtk_change_text(_("Warn"), gtkim->warn, | |
2614 GAIM_STOCK_WARN, type); | |
2615 gtk_box_pack_start(GTK_BOX(parent), gtkim->warn, FALSE, FALSE, 0); | |
4370
d856987c72ca
[gaim-migrate @ 4636]
Christian Hammond <chipx86@chipx86.com>
parents:
4369
diff
changeset
|
2616 gtk_tooltips_set_tip(gtkconv->tooltips, gtkim->warn, |
d856987c72ca
[gaim-migrate @ 4636]
Christian Hammond <chipx86@chipx86.com>
parents:
4369
diff
changeset
|
2617 _("Warn the user"), NULL); |
4359 | 2618 |
2619 /* Info button */ | |
2620 gtkconv->info = gaim_gtk_change_text(_("Info"), gtkconv->info, | |
2621 GAIM_STOCK_INFO, type); | |
2622 gtk_box_pack_start(GTK_BOX(parent), gtkconv->info, FALSE, FALSE, 0); | |
2623 gtk_tooltips_set_tip(gtkconv->tooltips, gtkconv->info, | |
4370
d856987c72ca
[gaim-migrate @ 4636]
Christian Hammond <chipx86@chipx86.com>
parents:
4369
diff
changeset
|
2624 _("Get the user's information"), NULL); |
4359 | 2625 |
2626 /* Block button */ | |
2627 gtkim->block = gaim_gtk_change_text(_("Block"), gtkim->block, | |
2628 GAIM_STOCK_BLOCK, type); | |
2629 gtk_box_pack_start(GTK_BOX(parent), gtkim->block, FALSE, FALSE, 0); | |
2630 gtk_tooltips_set_tip(gtkconv->tooltips, gtkim->block, | |
4370
d856987c72ca
[gaim-migrate @ 4636]
Christian Hammond <chipx86@chipx86.com>
parents:
4369
diff
changeset
|
2631 _("Block the user"), NULL); |
4359 | 2632 |
2633 gtk_button_set_relief(GTK_BUTTON(gtkconv->info), GTK_RELIEF_NONE); | |
2634 gtk_button_set_relief(GTK_BUTTON(gtkim->add), GTK_RELIEF_NONE); | |
2635 gtk_button_set_relief(GTK_BUTTON(gtkim->warn), GTK_RELIEF_NONE); | |
2636 gtk_button_set_relief(GTK_BUTTON(gtkconv->send), GTK_RELIEF_NONE); | |
2637 gtk_button_set_relief(GTK_BUTTON(gtkim->block), GTK_RELIEF_NONE); | |
2638 | |
2639 gtk_size_group_add_widget(gtkconv->sg, gtkconv->info); | |
2640 gtk_size_group_add_widget(gtkconv->sg, gtkim->add); | |
2641 gtk_size_group_add_widget(gtkconv->sg, gtkim->warn); | |
2642 gtk_size_group_add_widget(gtkconv->sg, gtkconv->send); | |
2643 gtk_size_group_add_widget(gtkconv->sg, gtkim->block); | |
2644 | |
2645 gtk_box_reorder_child(GTK_BOX(parent), gtkim->warn, 1); | |
2646 gtk_box_reorder_child(GTK_BOX(parent), gtkim->block, 2); | |
4370
d856987c72ca
[gaim-migrate @ 4636]
Christian Hammond <chipx86@chipx86.com>
parents:
4369
diff
changeset
|
2647 gtk_box_reorder_child(GTK_BOX(parent), gtkim->add, 3); |
4359 | 2648 gtk_box_reorder_child(GTK_BOX(parent), gtkconv->info, 4); |
2649 | |
2650 gaim_gtkconv_update_buttons_by_protocol(conv); | |
2651 | |
2652 g_signal_connect(G_OBJECT(gtkconv->send), "clicked", | |
2653 G_CALLBACK(send_cb), conv); | |
2654 g_signal_connect(G_OBJECT(gtkconv->info), "clicked", | |
2655 G_CALLBACK(info_cb), conv); | |
2656 g_signal_connect(G_OBJECT(gtkim->warn), "clicked", | |
2657 G_CALLBACK(warn_cb), conv); | |
2658 g_signal_connect(G_OBJECT(gtkim->block), "clicked", | |
2659 G_CALLBACK(block_cb), conv); | |
2660 } | |
2661 | |
2662 static void | |
2663 setup_chat_buttons(struct gaim_conversation *conv, GtkWidget *parent) | |
2664 { | |
2665 struct gaim_connection *gc; | |
2666 struct gaim_gtk_conversation *gtkconv; | |
2667 struct gaim_gtk_chat_pane *gtkchat; | |
2668 struct gaim_gtk_window *gtkwin; | |
2669 GtkWidget *sep; | |
2670 | |
2671 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
2672 gtkchat = gtkconv->u.chat; | |
2673 gtkwin = GAIM_GTK_WINDOW(gaim_conversation_get_window(conv)); | |
2674 gc = gaim_conversation_get_gc(conv); | |
2675 | |
2676 /* Send button */ | |
2677 gtkconv->send = gaim_gtk_change_text(_("Send"), gtkconv->send, | |
2678 GAIM_STOCK_SEND, GAIM_CONV_CHAT); | |
2679 gtk_tooltips_set_tip(gtkconv->tooltips, gtkconv->send, _("Send"), NULL); | |
2680 | |
2681 gtk_box_pack_end(GTK_BOX(parent), gtkconv->send, FALSE, FALSE, 0); | |
2682 | |
2683 /* Separator */ | |
2684 sep = gtk_vseparator_new(); | |
2685 gtk_box_pack_end(GTK_BOX(parent), sep, FALSE, TRUE, 0); | |
2686 gtk_widget_show(sep); | |
2687 | |
2688 /* Invite */ | |
2689 gtkchat->invite = gaim_gtk_change_text(_("Invite"), gtkchat->invite, | |
2690 GAIM_STOCK_INVITE, GAIM_CONV_CHAT); | |
2691 gtk_tooltips_set_tip(gtkconv->tooltips, gtkchat->invite, | |
2692 _("Invite a user"), NULL); | |
2693 gtk_box_pack_end(GTK_BOX(parent), gtkchat->invite, FALSE, FALSE, 0); | |
2694 | |
2695 /* Set the relief on these. */ | |
2696 gtk_button_set_relief(GTK_BUTTON(gtkchat->invite), GTK_RELIEF_NONE); | |
2697 gtk_button_set_relief(GTK_BUTTON(gtkconv->send), GTK_RELIEF_NONE); | |
2698 | |
2699 /* Callbacks */ | |
2700 g_signal_connect(G_OBJECT(gtkconv->send), "clicked", | |
2701 G_CALLBACK(send_cb), conv); | |
2702 g_signal_connect(G_OBJECT(gtkchat->invite), "clicked", | |
2703 G_CALLBACK(invite_cb), conv); | |
2704 } | |
2705 | |
2706 static GtkWidget * | |
2707 build_conv_toolbar(struct gaim_conversation *conv) | |
2708 { | |
2709 struct gaim_gtk_conversation *gtkconv; | |
2710 GtkWidget *vbox; | |
2711 GtkWidget *hbox; | |
2712 GtkWidget *button; | |
2713 GtkWidget *sep; | |
2714 GtkSizeGroup *sg; | |
2715 | |
2716 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
2717 | |
2718 sg = gtk_size_group_new(GTK_SIZE_GROUP_BOTH); | |
2719 | |
2720 vbox = gtk_vbox_new(FALSE, 0); | |
2721 sep = gtk_hseparator_new(); | |
2722 gtk_box_pack_start(GTK_BOX(vbox), sep, FALSE, FALSE, 0); | |
2723 | |
2724 hbox = gtk_hbox_new(FALSE, 5); | |
2725 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); | |
2726 | |
2727 /* Bold */ | |
2728 button = gaim_pixbuf_toolbar_button_from_stock(GTK_STOCK_BOLD); | |
2729 gtk_size_group_add_widget(sg, button); | |
2730 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); | |
2731 gtk_tooltips_set_tip(gtkconv->tooltips, button, _("Bold"), NULL); | |
2732 | |
2733 g_signal_connect(G_OBJECT(button), "clicked", | |
2734 G_CALLBACK(do_bold), gtkconv); | |
2735 | |
2736 gtkconv->toolbar.bold = button; | |
2737 | |
2738 /* Italic */ | |
2739 button = gaim_pixbuf_toolbar_button_from_stock(GTK_STOCK_ITALIC); | |
2740 gtk_size_group_add_widget(sg, button); | |
2741 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); | |
2742 gtk_tooltips_set_tip(gtkconv->tooltips, button, _("Italic"), NULL); | |
2743 | |
2744 g_signal_connect(G_OBJECT(button), "clicked", | |
2745 G_CALLBACK(do_italic), gtkconv); | |
2746 | |
2747 gtkconv->toolbar.italic = button; | |
2748 | |
2749 /* Underline */ | |
2750 button = gaim_pixbuf_toolbar_button_from_stock(GTK_STOCK_UNDERLINE); | |
2751 gtk_size_group_add_widget(sg, button); | |
2752 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); | |
2753 gtk_tooltips_set_tip(gtkconv->tooltips, button, _("Underline"), NULL); | |
2754 | |
2755 g_signal_connect(G_OBJECT(button), "clicked", | |
2756 G_CALLBACK(do_underline), gtkconv); | |
2757 | |
2758 gtkconv->toolbar.underline = button; | |
2759 | |
2760 /* Sep */ | |
2761 sep = gtk_vseparator_new(); | |
2762 gtk_box_pack_start(GTK_BOX(hbox), sep, FALSE, FALSE, 0); | |
2763 | |
2764 /* Increase font size */ | |
2765 button = gaim_pixbuf_toolbar_button_from_stock(GAIM_STOCK_TEXT_BIGGER); | |
2766 gtk_size_group_add_widget(sg, button); | |
2767 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); | |
2768 gtk_tooltips_set_tip(gtkconv->tooltips, button, | |
2769 _("Larger font size"), NULL); | |
2770 | |
2771 g_signal_connect(G_OBJECT(button), "clicked", | |
2772 G_CALLBACK(do_big), gtkconv); | |
2773 | |
2774 /* Normal font size */ | |
2775 button = gaim_pixbuf_toolbar_button_from_stock(GAIM_STOCK_TEXT_NORMAL); | |
2776 gtk_size_group_add_widget(sg, button); | |
2777 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); | |
2778 gtk_tooltips_set_tip(gtkconv->tooltips, button, | |
2779 _("Normal font size"), NULL); | |
2780 | |
2781 g_signal_connect(G_OBJECT(button), "clicked", | |
2782 G_CALLBACK(do_normal), gtkconv); | |
2783 | |
2784 gtkconv->toolbar.normal_size = button; | |
2785 | |
2786 /* Decrease font size */ | |
2787 button = gaim_pixbuf_toolbar_button_from_stock(GAIM_STOCK_TEXT_SMALLER); | |
2788 gtk_size_group_add_widget(sg, button); | |
2789 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); | |
2790 gtk_tooltips_set_tip(gtkconv->tooltips, button, | |
2791 _("Smaller font size"), NULL); | |
2792 | |
2793 g_signal_connect(G_OBJECT(button), "clicked", | |
2794 G_CALLBACK(do_small), gtkconv); | |
2795 | |
2796 /* Sep */ | |
2797 sep = gtk_vseparator_new(); | |
2798 gtk_box_pack_start(GTK_BOX(hbox), sep, FALSE, FALSE, 0); | |
2799 | |
2800 /* Foreground Color */ | |
2801 button = gaim_pixbuf_toolbar_button_from_stock(GAIM_STOCK_FGCOLOR); | |
2802 gtk_size_group_add_widget(sg, button); | |
2803 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); | |
2804 gtk_tooltips_set_tip(gtkconv->tooltips, button, | |
2805 _("Foreground font color"), NULL); | |
2806 | |
2807 g_signal_connect(G_OBJECT(button), "clicked", | |
2808 G_CALLBACK(toggle_fg_color), conv); | |
2809 | |
2810 gtkconv->toolbar.fgcolor = button; | |
2811 | |
2812 /* Background Color */ | |
2813 button = gaim_pixbuf_toolbar_button_from_stock(GAIM_STOCK_BGCOLOR); | |
2814 gtk_size_group_add_widget(sg, button); | |
2815 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); | |
2816 gtk_tooltips_set_tip(gtkconv->tooltips, button, | |
2817 _("Background color"), NULL); | |
2818 | |
2819 g_signal_connect(G_OBJECT(button), "clicked", | |
2820 G_CALLBACK(toggle_bg_color), conv); | |
2821 | |
2822 gtkconv->toolbar.bgcolor = button; | |
2823 | |
2824 /* Sep */ | |
2825 sep = gtk_vseparator_new(); | |
2826 gtk_box_pack_start(GTK_BOX(hbox), sep, FALSE, FALSE, 0); | |
2827 | |
2828 /* Insert IM Image */ | |
2829 button = gaim_pixbuf_toolbar_button_from_stock(GAIM_STOCK_IMAGE); | |
2830 gtk_size_group_add_widget(sg, button); | |
2831 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); | |
2832 gtk_tooltips_set_tip(gtkconv->tooltips, button, _("Insert image"), NULL); | |
2833 | |
2834 g_signal_connect(G_OBJECT(button), "clicked", | |
2835 G_CALLBACK(insert_image_cb), conv); | |
2836 | |
2837 gtkconv->toolbar.image = button; | |
2838 | |
2839 /* Insert Link */ | |
2840 button = gaim_pixbuf_toolbar_button_from_stock(GAIM_STOCK_LINK); | |
2841 gtk_size_group_add_widget(sg, button); | |
2842 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); | |
2843 gtk_tooltips_set_tip(gtkconv->tooltips, button, _("Insert link"), NULL); | |
2844 | |
2845 g_signal_connect(G_OBJECT(button), "clicked", | |
2846 G_CALLBACK(insert_link_cb), conv); | |
2847 | |
2848 gtkconv->toolbar.link = button; | |
2849 | |
2850 /* Insert Smiley */ | |
2851 button = gaim_pixbuf_toolbar_button_from_stock(GAIM_STOCK_SMILEY); | |
2852 gtk_size_group_add_widget(sg, button); | |
2853 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); | |
2854 gtk_tooltips_set_tip(gtkconv->tooltips, button, _("Insert smiley"), NULL); | |
2855 | |
2856 g_signal_connect(G_OBJECT(button), "clicked", | |
2857 G_CALLBACK(insert_smiley_cb), conv); | |
2858 | |
2859 gtkconv->toolbar.smiley = button; | |
2860 | |
2861 | |
2862 sep = gtk_hseparator_new(); | |
2863 gtk_box_pack_start(GTK_BOX(vbox), sep, FALSE, FALSE, 0); | |
2864 | |
2865 gtk_widget_show_all(vbox); | |
2866 | |
2867 return vbox; | |
2868 } | |
2869 | |
2870 static GtkWidget * | |
2871 setup_chat_pane(struct gaim_conversation *conv) | |
2872 { | |
2873 struct gaim_gtk_conversation *gtkconv; | |
2874 struct gaim_gtk_chat_pane *gtkchat; | |
2875 struct gaim_connection *gc; | |
2876 GtkWidget *vpaned, *hpaned; | |
2877 GtkWidget *vbox, *hbox; | |
2878 GtkWidget *lbox, *bbox; | |
2879 GtkWidget *label; | |
2880 GtkWidget *sw2; | |
2881 GtkWidget *list; | |
2882 GtkWidget *button; | |
2883 GtkWidget *frame; | |
2884 GtkListStore *ls; | |
2885 GtkCellRenderer *rend; | |
2886 GtkTreeViewColumn *col; | |
2887 | |
2888 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
2889 gtkchat = gtkconv->u.chat; | |
2890 gc = gaim_conversation_get_gc(conv); | |
2891 | |
2892 /* Setup the outer pane. */ | |
2893 vpaned = gtk_vpaned_new(); | |
2894 gtk_widget_show(vpaned); | |
2895 | |
2896 /* Setup the top part of the pane. */ | |
2897 vbox = gtk_vbox_new(FALSE, 5); | |
2898 gtk_paned_pack1(GTK_PANED(vpaned), vbox, TRUE, FALSE); | |
2899 gtk_widget_show(vbox); | |
2900 | |
2901 if (gc->prpl->options & OPT_PROTO_CHAT_TOPIC) | |
2902 { | |
2903 hbox = gtk_hbox_new(FALSE, 0); | |
2904 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5); | |
2905 gtk_widget_show(hbox); | |
2906 | |
2907 label = gtk_label_new(_("Topic:")); | |
2908 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5); | |
2909 gtk_widget_show(label); | |
2910 | |
2911 gtkchat->topic_text = gtk_entry_new(); | |
4635 | 2912 gtk_editable_set_editable(GTK_EDITABLE(gtkchat->topic_text), FALSE); |
4359 | 2913 gtk_box_pack_start(GTK_BOX(hbox), gtkchat->topic_text, TRUE, TRUE, 5); |
2914 gtk_widget_show(gtkchat->topic_text); | |
2915 } | |
2916 | |
2917 /* Setup the horizontal pane. */ | |
2918 hpaned = gtk_hpaned_new(); | |
2919 gtk_box_pack_start(GTK_BOX(vbox), hpaned, TRUE, TRUE, 5); | |
2920 gtk_widget_show(hpaned); | |
2921 | |
2922 /* Setup the scrolled window to put gtkimhtml in. */ | |
2923 gtkconv->sw = gtk_scrolled_window_new(NULL, NULL); | |
2924 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(gtkconv->sw), | |
2925 GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); | |
2926 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(gtkconv->sw), | |
2927 GTK_SHADOW_IN); | |
2928 gtk_paned_pack1(GTK_PANED(hpaned), gtkconv->sw, TRUE, TRUE); | |
2929 | |
2930 gtk_widget_set_size_request(gtkconv->sw, | |
2931 buddy_chat_size.width, buddy_chat_size.height); | |
2932 gtk_widget_show(gtkconv->sw); | |
2933 | |
2934 /* Setup gtkihmtml. */ | |
2935 gtkconv->imhtml = gtk_imhtml_new(NULL, NULL); | |
2936 gtk_container_add(GTK_CONTAINER(gtkconv->sw), gtkconv->imhtml); | |
2937 | |
2938 gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml), | |
2939 (convo_options & OPT_CONVO_SHOW_TIME)); | |
2940 | |
2941 g_signal_connect_after(G_OBJECT(gtkconv->imhtml), "button_press_event", | |
2942 G_CALLBACK(entry_stop_rclick_cb), NULL); | |
2943 | |
2944 gaim_setup_imhtml(gtkconv->imhtml); | |
2945 | |
2946 gtk_widget_show(gtkconv->imhtml); | |
2947 | |
2948 /* Build the right pane. */ | |
2949 lbox = gtk_vbox_new(FALSE, 5); | |
4409
0521eec12c33
[gaim-migrate @ 4682]
Christian Hammond <chipx86@chipx86.com>
parents:
4398
diff
changeset
|
2950 gtk_paned_pack2(GTK_PANED(hpaned), lbox, FALSE, TRUE); |
4359 | 2951 gtk_widget_show(lbox); |
2952 | |
2953 /* Setup the label telling how many people are in the room. */ | |
2954 gtkchat->count = gtk_label_new(_("0 people in room")); | |
2955 gtk_box_pack_start(GTK_BOX(lbox), gtkchat->count, FALSE, FALSE, 0); | |
2956 gtk_widget_show(gtkchat->count); | |
2957 | |
2958 /* Setup the list of users. */ | |
2959 sw2 = gtk_scrolled_window_new(NULL, NULL); | |
2960 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw2), | |
2961 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); | |
2962 gtk_box_pack_start(GTK_BOX(lbox), sw2, TRUE, TRUE, 0); | |
2963 gtk_widget_show(sw2); | |
2964 | |
2965 ls = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING); | |
2966 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(ls), 1, | |
2967 GTK_SORT_ASCENDING); | |
2968 | |
2969 list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(ls)); | |
2970 | |
2971 rend = gtk_cell_renderer_text_new(); | |
2972 col = gtk_tree_view_column_new_with_attributes(NULL, rend, | |
2973 "text", 0, NULL); | |
2974 gtk_tree_view_column_set_clickable(GTK_TREE_VIEW_COLUMN(col), TRUE); | |
2975 | |
2976 g_signal_connect(G_OBJECT(list), "button_press_event", | |
2977 G_CALLBACK(right_click_chat_cb), conv); | |
2978 | |
2979 gtk_tree_view_append_column(GTK_TREE_VIEW(list), col); | |
2980 | |
2981 col = gtk_tree_view_column_new_with_attributes(NULL, rend, | |
2982 "text", 1, NULL); | |
2983 gtk_tree_view_column_set_clickable(GTK_TREE_VIEW_COLUMN(col), TRUE); | |
2984 | |
2985 #if 0 | |
2986 g_signal_connect(G_OBJECT(list), "button_press_event", | |
2987 G_CALLBACK(right_click_chat), conv); | |
2988 #endif | |
2989 | |
2990 gtk_tree_view_append_column(GTK_TREE_VIEW(list), col); | |
2991 | |
2992 gtk_widget_set_size_request(list, 150, -1); | |
2993 | |
2994 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(list), FALSE); | |
2995 gtk_widget_show(list); | |
2996 | |
2997 gtkchat->list = list; | |
2998 | |
2999 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(sw2), list); | |
3000 | |
3001 /* Setup the user list toolbar. */ | |
3002 bbox = gtk_hbox_new(TRUE, 5); | |
3003 gtk_box_pack_start(GTK_BOX(lbox), bbox, FALSE, FALSE, 0); | |
3004 gtk_widget_show(bbox); | |
3005 | |
3006 /* IM */ | |
3007 button = gaim_pixbuf_button_from_stock(NULL, GTK_STOCK_REDO, | |
3008 GAIM_BUTTON_VERTICAL); | |
3009 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); | |
3010 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
4370
d856987c72ca
[gaim-migrate @ 4636]
Christian Hammond <chipx86@chipx86.com>
parents:
4369
diff
changeset
|
3011 gtk_tooltips_set_tip(gtkconv->tooltips, button, _("IM the user"), NULL); |
4359 | 3012 g_signal_connect(G_OBJECT(button), "clicked", |
3013 G_CALLBACK(im_cb), conv); | |
3014 | |
3015 gtk_widget_show(button); | |
3016 | |
3017 /* Ignore */ | |
3018 button = gaim_pixbuf_button_from_stock(NULL, GAIM_STOCK_IGNORE, | |
3019 GAIM_BUTTON_VERTICAL); | |
3020 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); | |
3021 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
4370
d856987c72ca
[gaim-migrate @ 4636]
Christian Hammond <chipx86@chipx86.com>
parents:
4369
diff
changeset
|
3022 gtk_tooltips_set_tip(gtkconv->tooltips, button, |
d856987c72ca
[gaim-migrate @ 4636]
Christian Hammond <chipx86@chipx86.com>
parents:
4369
diff
changeset
|
3023 _("Ignore the user"), NULL); |
4359 | 3024 g_signal_connect(G_OBJECT(button), "clicked", |
3025 G_CALLBACK(ignore_cb), conv); | |
3026 gtk_widget_show(button); | |
3027 | |
3028 /* Info */ | |
3029 button = gaim_pixbuf_button_from_stock(NULL, GAIM_STOCK_INFO, | |
3030 GAIM_BUTTON_VERTICAL); | |
3031 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); | |
3032 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
3033 gtk_tooltips_set_tip(gtkconv->tooltips, button, | |
4370
d856987c72ca
[gaim-migrate @ 4636]
Christian Hammond <chipx86@chipx86.com>
parents:
4369
diff
changeset
|
3034 _("Get the user's information"), NULL); |
4359 | 3035 g_signal_connect(G_OBJECT(button), "clicked", |
3036 G_CALLBACK(info_cb), conv); | |
3037 | |
3038 gtk_widget_show(button); | |
3039 | |
3040 gtkconv->info = button; | |
3041 | |
3042 /* Build the toolbar. */ | |
3043 vbox = gtk_vbox_new(FALSE, 5); | |
4409
0521eec12c33
[gaim-migrate @ 4682]
Christian Hammond <chipx86@chipx86.com>
parents:
4398
diff
changeset
|
3044 gtk_paned_pack2(GTK_PANED(vpaned), vbox, FALSE, FALSE); |
4359 | 3045 gtk_widget_show(vbox); |
3046 | |
3047 gtkconv->toolbar.toolbar = build_conv_toolbar(conv); | |
3048 gtk_box_pack_start(GTK_BOX(vbox), gtkconv->toolbar.toolbar, | |
3049 FALSE, FALSE, 0); | |
3050 | |
3051 /* Setup the entry widget. */ | |
3052 frame = gtk_frame_new(NULL); | |
3053 gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN); | |
3054 gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0); | |
3055 gtk_widget_show(frame); | |
3056 | |
3057 gtkconv->entry_buffer = gtk_text_buffer_new(NULL); | |
3058 g_object_set_data(G_OBJECT(gtkconv->entry_buffer), "user_data", conv); | |
3059 gtkconv->entry = gtk_text_view_new_with_buffer(gtkconv->entry_buffer); | |
3060 | |
3061 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(gtkconv->entry), GTK_WRAP_WORD); | |
3062 gtk_widget_set_size_request(gtkconv->entry, buddy_chat_size.width, | |
3063 MAX(buddy_chat_size.entry_height, 25)); | |
3064 | |
3065 /* Connect the signal handlers. */ | |
3066 g_signal_connect_swapped(G_OBJECT(gtkconv->entry), "key_press_event", | |
3067 G_CALLBACK(entry_key_pressed_cb_1), | |
3068 gtkconv->entry_buffer); | |
3069 g_signal_connect_after(G_OBJECT(gtkconv->entry), "button_press_event", | |
3070 G_CALLBACK(entry_stop_rclick_cb), NULL); | |
3071 g_signal_connect(G_OBJECT(gtkconv->entry), "key_press_event", | |
3072 G_CALLBACK(entry_key_pressed_cb_2), conv); | |
3073 | |
3074 #ifdef USE_GTKSPELL | |
3075 if (convo_options & OPT_CONVO_CHECK_SPELLING) | |
3076 gtkspell_new_attach(GTK_TEXT_VIEW(gtkconv->entry), NULL, NULL); | |
3077 #endif | |
3078 | |
3079 gtk_container_add(GTK_CONTAINER(frame), GTK_WIDGET(gtkconv->entry)); | |
3080 gtk_widget_show(gtkconv->entry); | |
3081 | |
3082 /* Setup the bottom button box. */ | |
3083 gtkconv->bbox = gtk_hbox_new(FALSE, 5); | |
3084 gtk_box_pack_start(GTK_BOX(vbox), gtkconv->bbox, FALSE, FALSE, 0); | |
3085 gtk_widget_show(gtkconv->bbox); | |
3086 | |
3087 setup_chat_buttons(conv, gtkconv->bbox); | |
3088 | |
3089 return vpaned; | |
3090 } | |
3091 | |
3092 static GtkWidget * | |
3093 setup_im_pane(struct gaim_conversation *conv) | |
3094 { | |
3095 struct gaim_gtk_conversation *gtkconv; | |
3096 struct gaim_gtk_im_pane *gtkim; | |
3097 GtkWidget *paned; | |
3098 GtkWidget *vbox; | |
3099 GtkWidget *vbox2; | |
3100 GtkWidget *frame; | |
3101 | |
3102 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
3103 gtkim = gtkconv->u.im; | |
3104 | |
3105 /* Setup the outer pane. */ | |
3106 paned = gtk_vpaned_new(); | |
3107 gtk_widget_show(paned); | |
3108 | |
3109 /* Setup the top part of the pane. */ | |
3110 vbox = gtk_vbox_new(FALSE, 5); | |
4409
0521eec12c33
[gaim-migrate @ 4682]
Christian Hammond <chipx86@chipx86.com>
parents:
4398
diff
changeset
|
3111 gtk_paned_pack1(GTK_PANED(paned), vbox, TRUE, TRUE); |
4359 | 3112 gtk_widget_show(vbox); |
3113 | |
3114 /* Setup the gtkimhtml widget. */ | |
3115 gtkconv->sw = gtk_scrolled_window_new(NULL, NULL); | |
3116 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(gtkconv->sw), | |
3117 GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); | |
3118 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(gtkconv->sw), | |
3119 GTK_SHADOW_IN); | |
3120 gtk_box_pack_start(GTK_BOX(vbox), gtkconv->sw, TRUE, TRUE, 0); | |
3121 gtk_widget_set_size_request(gtkconv->sw, conv_size.width, conv_size.height); | |
3122 gtk_widget_show(gtkconv->sw); | |
3123 | |
3124 gtkconv->imhtml = gtk_imhtml_new(NULL, NULL); | |
3125 gtk_container_add(GTK_CONTAINER(gtkconv->sw), gtkconv->imhtml); | |
3126 | |
3127 g_signal_connect_after(G_OBJECT(gtkconv->imhtml), "button_press_event", | |
3128 G_CALLBACK(entry_stop_rclick_cb), NULL); | |
3129 | |
3130 gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml), | |
3131 (convo_options & OPT_CONVO_SHOW_TIME)); | |
3132 | |
3133 gaim_setup_imhtml(gtkconv->imhtml); | |
3134 | |
3135 gtk_widget_show(gtkconv->imhtml); | |
3136 | |
3137 vbox2 = gtk_vbox_new(FALSE, 5); | |
3138 gtk_paned_pack2(GTK_PANED(paned), vbox2, FALSE, FALSE); | |
3139 gtk_widget_show(vbox2); | |
3140 | |
3141 /* Build the toolbar. */ | |
3142 gtkconv->toolbar.toolbar = build_conv_toolbar(conv); | |
3143 gtk_box_pack_start(GTK_BOX(vbox2), gtkconv->toolbar.toolbar, | |
3144 FALSE, FALSE, 0); | |
3145 | |
3146 /* Setup the entry widget. */ | |
3147 frame = gtk_frame_new(NULL); | |
3148 gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN); | |
3149 gtk_box_pack_start(GTK_BOX(vbox2), frame, TRUE, TRUE, 0); | |
3150 gtk_widget_show(frame); | |
3151 | |
3152 gtkconv->entry_buffer = gtk_text_buffer_new(NULL); | |
3153 g_object_set_data(G_OBJECT(gtkconv->entry_buffer), "user_data", conv); | |
3154 gtkconv->entry = gtk_text_view_new_with_buffer(gtkconv->entry_buffer); | |
3155 | |
3156 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(gtkconv->entry), GTK_WRAP_WORD); | |
3157 gtk_widget_set_size_request(gtkconv->entry, conv_size.width - 20, | |
3158 MAX(conv_size.entry_height, 25)); | |
3159 | |
3160 /* Connect the signal handlers. */ | |
3161 g_signal_connect_swapped(G_OBJECT(gtkconv->entry), "key_press_event", | |
3162 G_CALLBACK(entry_key_pressed_cb_1), | |
3163 gtkconv->entry_buffer); | |
3164 g_signal_connect(G_OBJECT(gtkconv->entry), "key_press_event", | |
3165 G_CALLBACK(entry_key_pressed_cb_2), conv); | |
3166 g_signal_connect_after(G_OBJECT(gtkconv->entry), "button_press_event", | |
3167 G_CALLBACK(entry_stop_rclick_cb), NULL); | |
3168 | |
3169 g_signal_connect(G_OBJECT(gtkconv->entry_buffer), "insert_text", | |
3170 G_CALLBACK(insert_text_cb), conv); | |
3171 g_signal_connect(G_OBJECT(gtkconv->entry_buffer), "delete_range", | |
3172 G_CALLBACK(delete_text_cb), conv); | |
3173 | |
3174 #ifdef USE_GTKSPELL | |
3175 if (convo_options & OPT_CONVO_CHECK_SPELLING) | |
3176 gtkspell_new_attach(GTK_TEXT_VIEW(gtkconv->entry), NULL, NULL); | |
3177 #endif | |
3178 | |
3179 gtk_container_add(GTK_CONTAINER(frame), GTK_WIDGET(gtkconv->entry)); | |
3180 gtk_widget_show(gtkconv->entry); | |
3181 | |
3182 gtkconv->bbox = gtk_hbox_new(FALSE, 5); | |
3183 gtk_box_pack_start(GTK_BOX(vbox2), gtkconv->bbox, FALSE, FALSE, 0); | |
3184 gtk_widget_show(gtkconv->bbox); | |
3185 | |
3186 setup_im_buttons(conv, gtkconv->bbox); | |
3187 | |
3188 return paned; | |
3189 } | |
3190 | |
3191 static void | |
3192 move_next_tab(struct gaim_conversation *conv) | |
3193 { | |
3194 struct gaim_conversation *next_conv = NULL; | |
3195 struct gaim_window *win; | |
3196 GList *l; | |
3197 int index, i; | |
3198 | |
3199 win = gaim_conversation_get_window(conv); | |
3200 index = gaim_conversation_get_index(conv); | |
3201 | |
3202 /* First check the tabs after this position. */ | |
3203 for (l = g_list_nth(gaim_window_get_conversations(win), index); | |
3204 l != NULL; | |
3205 l = l->next) { | |
3206 | |
3207 next_conv = (struct gaim_conversation *)l->data; | |
3208 | |
3209 if (gaim_conversation_get_unseen(next_conv) > 0) | |
3210 break; | |
3211 | |
3212 next_conv = NULL; | |
3213 } | |
3214 | |
3215 if (next_conv == NULL) { | |
3216 | |
3217 /* Now check before this position. */ | |
3218 for (l = gaim_window_get_conversations(win), i = 0; | |
3219 l != NULL && i < index; | |
3220 l = l->next) { | |
3221 | |
3222 next_conv = (struct gaim_conversation *)l->data; | |
3223 | |
3224 if (gaim_conversation_get_unseen(next_conv) > 0) | |
3225 break; | |
3226 | |
3227 next_conv = NULL; | |
3228 } | |
3229 | |
3230 if (next_conv == NULL) { | |
3231 /* Okay, just grab the next conversation tab. */ | |
3232 if (index == gaim_window_get_conversation_count(win) - 1) | |
3233 next_conv = gaim_window_get_conversation_at(win, 0); | |
3234 else | |
3235 next_conv = gaim_window_get_conversation_at(win, index + 1); | |
3236 } | |
3237 } | |
3238 | |
3239 if (next_conv != NULL && next_conv != conv) { | |
3240 gaim_window_switch_conversation(win, | |
3241 gaim_conversation_get_index(next_conv)); | |
3242 } | |
3243 } | |
3244 | |
3245 | |
3246 /************************************************************************** | |
3247 * GTK+ window ops | |
3248 **************************************************************************/ | |
4465
6e37eb000b7a
[gaim-migrate @ 4740]
Christian Hammond <chipx86@chipx86.com>
parents:
4454
diff
changeset
|
3249 static struct gaim_conversation_ui_ops * |
6e37eb000b7a
[gaim-migrate @ 4740]
Christian Hammond <chipx86@chipx86.com>
parents:
4454
diff
changeset
|
3250 gaim_gtk_get_conversation_ui_ops(void) |
4359 | 3251 { |
4465
6e37eb000b7a
[gaim-migrate @ 4740]
Christian Hammond <chipx86@chipx86.com>
parents:
4454
diff
changeset
|
3252 return gaim_get_gtk_conversation_ui_ops(); |
4359 | 3253 } |
3254 | |
3255 static void | |
3256 gaim_gtk_new_window(struct gaim_window *win) | |
3257 { | |
3258 struct gaim_gtk_window *gtkwin; | |
3259 GtkPositionType pos; | |
3260 GtkWidget *testidea; | |
3261 GtkWidget *menubar; | |
3262 | |
3263 gtkwin = g_malloc0(sizeof(struct gaim_gtk_window)); | |
3264 | |
3265 win->ui_data = gtkwin; | |
3266 | |
3267 /* Create the window. */ | |
3268 gtkwin->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); | |
3269 gtk_window_set_role(GTK_WINDOW(gtkwin->window), "conversation"); | |
4635 | 3270 gtk_window_set_resizable(GTK_WINDOW(gtkwin->window), TRUE); |
4510
4c394222c732
[gaim-migrate @ 4786]
Christian Hammond <chipx86@chipx86.com>
parents:
4505
diff
changeset
|
3271 gtk_container_set_border_width(GTK_CONTAINER(gtkwin->window), 0); |
4359 | 3272 gtk_widget_realize(gtkwin->window); |
3273 | |
3274 g_signal_connect(G_OBJECT(gtkwin->window), "delete_event", | |
3275 G_CALLBACK(close_win_cb), win); | |
3276 | |
3277 /* Create the notebook. */ | |
3278 gtkwin->notebook = gtk_notebook_new(); | |
3279 | |
3280 pos = ((im_options & OPT_IM_SIDE_TAB) | |
3281 ? ((im_options & OPT_IM_BR_TAB) ? GTK_POS_RIGHT : GTK_POS_LEFT) | |
3282 : ((im_options & OPT_IM_BR_TAB) ? GTK_POS_BOTTOM : GTK_POS_TOP)); | |
3283 | |
3284 #if 0 | |
3285 gtk_notebook_set_tab_hborder(GTK_NOTEBOOK(gtkwin->notebook), 0); | |
3286 gtk_notebook_set_tab_vborder(GTK_NOTEBOOK(gtkwin->notebook), 0); | |
3287 #endif | |
3288 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(gtkwin->notebook), pos); | |
3289 gtk_notebook_set_scrollable(GTK_NOTEBOOK(gtkwin->notebook), TRUE); | |
3290 gtk_notebook_popup_enable(GTK_NOTEBOOK(gtkwin->notebook)); | |
3291 gtk_widget_show(gtkwin->notebook); | |
3292 | |
3293 g_signal_connect_after(G_OBJECT(gtkwin->notebook), "switch_page", | |
3294 G_CALLBACK(switch_conv_cb), win); | |
3295 | |
3296 /* Setup the tab drag and drop signals. */ | |
4486 | 3297 gtk_widget_add_events(gtkwin->notebook, |
3298 GDK_BUTTON1_MOTION_MASK | GDK_LEAVE_NOTIFY_MASK); | |
3299 g_signal_connect(G_OBJECT(gtkwin->notebook), "button_press_event", | |
4572
06084165a966
[gaim-migrate @ 4853]
Christian Hammond <chipx86@chipx86.com>
parents:
4571
diff
changeset
|
3300 G_CALLBACK(notebook_press_cb), win); |
4486 | 3301 g_signal_connect(G_OBJECT(gtkwin->notebook), "button_release_event", |
4572
06084165a966
[gaim-migrate @ 4853]
Christian Hammond <chipx86@chipx86.com>
parents:
4571
diff
changeset
|
3302 G_CALLBACK(notebook_release_cb), win); |
06084165a966
[gaim-migrate @ 4853]
Christian Hammond <chipx86@chipx86.com>
parents:
4571
diff
changeset
|
3303 |
4359 | 3304 testidea = gtk_vbox_new(FALSE, 0); |
4572
06084165a966
[gaim-migrate @ 4853]
Christian Hammond <chipx86@chipx86.com>
parents:
4571
diff
changeset
|
3305 |
4359 | 3306 /* Setup the menubar. */ |
3307 menubar = setup_menubar(win); | |
3308 gtk_box_pack_start(GTK_BOX(testidea), menubar, FALSE, TRUE, 0); | |
3309 | |
3310 gtk_box_pack_start(GTK_BOX(testidea), gtkwin->notebook, TRUE, TRUE, 0); | |
3311 | |
3312 gtk_container_add(GTK_CONTAINER(gtkwin->window), testidea); | |
3313 | |
3314 gtk_widget_show(testidea); | |
3315 } | |
3316 | |
3317 static void | |
3318 gaim_gtk_destroy_window(struct gaim_window *win) | |
3319 { | |
3320 struct gaim_gtk_window *gtkwin = GAIM_GTK_WINDOW(win); | |
3321 | |
4369
7e1fb422e5fd
[gaim-migrate @ 4635]
Christian Hammond <chipx86@chipx86.com>
parents:
4368
diff
changeset
|
3322 gaim_gtk_set_state_lock(TRUE); |
7e1fb422e5fd
[gaim-migrate @ 4635]
Christian Hammond <chipx86@chipx86.com>
parents:
4368
diff
changeset
|
3323 |
4359 | 3324 gtk_widget_destroy(gtkwin->window); |
3325 | |
4369
7e1fb422e5fd
[gaim-migrate @ 4635]
Christian Hammond <chipx86@chipx86.com>
parents:
4368
diff
changeset
|
3326 gaim_gtk_set_state_lock(FALSE); |
7e1fb422e5fd
[gaim-migrate @ 4635]
Christian Hammond <chipx86@chipx86.com>
parents:
4368
diff
changeset
|
3327 |
4630 | 3328 g_object_unref(G_OBJECT(gtkwin->menu.item_factory)); |
3329 | |
4359 | 3330 g_free(gtkwin); |
3331 win->ui_data = NULL; | |
3332 } | |
3333 | |
3334 static void | |
3335 gaim_gtk_show(struct gaim_window *win) | |
3336 { | |
3337 struct gaim_gtk_window *gtkwin = GAIM_GTK_WINDOW(win); | |
3338 | |
3339 gtk_widget_show(gtkwin->window); | |
3340 } | |
3341 | |
3342 static void | |
3343 gaim_gtk_hide(struct gaim_window *win) | |
3344 { | |
3345 struct gaim_gtk_window *gtkwin = GAIM_GTK_WINDOW(win); | |
3346 | |
3347 gtk_widget_hide(gtkwin->window); | |
3348 } | |
3349 | |
3350 static void | |
3351 gaim_gtk_raise(struct gaim_window *win) | |
3352 { | |
3353 struct gaim_gtk_window *gtkwin = GAIM_GTK_WINDOW(win); | |
3354 | |
4526 | 3355 gdk_window_raise(gtkwin->window->window); |
4359 | 3356 } |
3357 | |
3358 static void | |
3359 gaim_gtk_flash(struct gaim_window *win) | |
3360 { | |
3361 #ifdef _WIN32 | |
3362 struct gaim_gtk_window *gtkwin = GAIM_GTK_WINDOW(win); | |
3363 | |
3364 wgaim_im_blink(gtkwin->window); | |
3365 #endif | |
3366 } | |
3367 | |
3368 static void | |
3369 gaim_gtk_switch_conversation(struct gaim_window *win, unsigned int index) | |
3370 { | |
3371 struct gaim_gtk_window *gtkwin; | |
3372 | |
3373 gtkwin = GAIM_GTK_WINDOW(win); | |
3374 | |
3375 gtk_notebook_set_current_page(GTK_NOTEBOOK(gtkwin->notebook), index); | |
3376 } | |
3377 | |
3378 static void | |
3379 gaim_gtk_add_conversation(struct gaim_window *win, | |
3380 struct gaim_conversation *conv) | |
3381 { | |
3382 struct gaim_gtk_window *gtkwin; | |
3383 struct gaim_gtk_conversation *gtkconv; | |
3384 GtkWidget *pane = NULL; | |
3385 GtkWidget *tab_cont; | |
3386 GtkWidget *tabby; | |
3387 gboolean new_ui; | |
4383
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3388 GaimConversationType conv_type; |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3389 const char *name; |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3390 |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3391 name = gaim_conversation_get_name(conv); |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3392 conv_type = gaim_conversation_get_type(conv); |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3393 gtkwin = GAIM_GTK_WINDOW(win); |
4359 | 3394 |
3395 if (conv->ui_data != NULL) { | |
3396 gtkconv = (struct gaim_gtk_conversation *)conv->ui_data; | |
3397 | |
3398 tab_cont = gtkconv->tab_cont; | |
3399 | |
3400 new_ui = FALSE; | |
3401 } | |
3402 else { | |
3403 gtkconv = g_malloc0(sizeof(struct gaim_gtk_conversation)); | |
3404 conv->ui_data = gtkconv; | |
3405 | |
3406 /* Setup some initial variables. */ | |
3407 gtkconv->sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); | |
3408 gtkconv->tooltips = gtk_tooltips_new(); | |
3409 | |
4421 | 3410 /* Setup the foreground and background colors */ |
3411 gaim_gtkconv_update_font_colors(conv); | |
3412 | |
4438
2054d8429925
[gaim-migrate @ 4713]
Christian Hammond <chipx86@chipx86.com>
parents:
4421
diff
changeset
|
3413 /* Setup the font face */ |
2054d8429925
[gaim-migrate @ 4713]
Christian Hammond <chipx86@chipx86.com>
parents:
4421
diff
changeset
|
3414 gaim_gtkconv_update_font_face(conv); |
2054d8429925
[gaim-migrate @ 4713]
Christian Hammond <chipx86@chipx86.com>
parents:
4421
diff
changeset
|
3415 |
4383
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3416 if (conv_type == GAIM_CONV_CHAT) { |
4359 | 3417 gtkconv->u.chat = g_malloc0(sizeof(struct gaim_gtk_chat_pane)); |
3418 | |
3419 pane = setup_chat_pane(conv); | |
3420 } | |
4383
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3421 else if (conv_type == GAIM_CONV_IM) { |
4359 | 3422 gtkconv->u.im = g_malloc0(sizeof(struct gaim_gtk_im_pane)); |
3423 gtkconv->u.im->a_virgin = TRUE; | |
3424 | |
3425 pane = setup_im_pane(conv); | |
3426 } | |
3427 | |
3428 if (pane == NULL) { | |
4572
06084165a966
[gaim-migrate @ 4853]
Christian Hammond <chipx86@chipx86.com>
parents:
4571
diff
changeset
|
3429 if (conv_type == GAIM_CONV_CHAT) g_free(gtkconv->u.chat); |
06084165a966
[gaim-migrate @ 4853]
Christian Hammond <chipx86@chipx86.com>
parents:
4571
diff
changeset
|
3430 else if (conv_type == GAIM_CONV_IM) g_free(gtkconv->u.im); |
4359 | 3431 |
3432 g_free(gtkconv); | |
3433 conv->ui_data = NULL; | |
3434 | |
3435 return; | |
3436 } | |
3437 | |
4383
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3438 /* |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3439 * Write the New Conversation log string. |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3440 * |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3441 * This should probably be elsewhere, but then, logging should |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3442 * be moved out in some way, either via plugin or via a new API. |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3443 */ |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3444 if (gaim_conversation_is_logging(conv) && |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3445 conv_type != GAIM_CONV_MISC) { |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3446 |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3447 FILE *fd; |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3448 char filename[256]; |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3449 |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3450 g_snprintf(filename, sizeof(filename), "%s%s", name, |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3451 (conv_type == GAIM_CONV_CHAT ? ".chat" : "")); |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3452 |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3453 fd = open_log_file(filename, (conv_type == GAIM_CONV_CHAT)); |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3454 |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3455 if (fd) { |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3456 if (!(logging_options & OPT_LOG_STRIP_HTML)) |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3457 fprintf(fd, |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3458 "<HR><BR><H3 Align=Center> " |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3459 "---- New Conversation @ %s ----</H3><BR>\n", |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3460 full_date()); |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3461 else |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3462 fprintf(fd, "---- New Conversation @ %s ----\n", |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3463 full_date()); |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3464 |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3465 fclose(fd); |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3466 } |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3467 } |
f7a84034f97f
[gaim-migrate @ 4649]
Christian Hammond <chipx86@chipx86.com>
parents:
4382
diff
changeset
|
3468 |
4359 | 3469 /* Setup the container for the tab. */ |
3470 gtkconv->tab_cont = tab_cont = gtk_vbox_new(FALSE, 5); | |
3471 gtk_container_set_border_width(GTK_CONTAINER(tab_cont), 5); | |
3472 gtk_container_add(GTK_CONTAINER(tab_cont), pane); | |
3473 gtk_widget_show(pane); | |
3474 | |
3475 new_ui = TRUE; | |
4636 | 3476 |
3477 gtk_widget_grab_focus(pane); | |
3478 | |
4359 | 3479 gtkconv->make_sound = TRUE; |
3480 } | |
3481 | |
3482 gtkconv->tabby = tabby = gtk_hbox_new(FALSE, 5); | |
3483 | |
3484 /* Close button. */ | |
3485 gtkconv->close = gtk_button_new(); | |
3486 gtk_widget_set_size_request(GTK_WIDGET(gtkconv->close), 16, 16); | |
3487 gtk_container_add(GTK_CONTAINER(gtkconv->close), | |
4445 | 3488 gtk_image_new_from_stock(GTK_STOCK_CLOSE, |
3489 GTK_ICON_SIZE_MENU)); | |
4359 | 3490 gtk_button_set_relief(GTK_BUTTON(gtkconv->close), GTK_RELIEF_NONE); |
3491 gtk_tooltips_set_tip(gtkconv->tooltips, gtkconv->close, | |
4572
06084165a966
[gaim-migrate @ 4853]
Christian Hammond <chipx86@chipx86.com>
parents:
4571
diff
changeset
|
3492 _("Close conversation"), NULL); |
4359 | 3493 |
3494 g_signal_connect(G_OBJECT(gtkconv->close), "clicked", | |
4571
51e988d015ed
[gaim-migrate @ 4852]
Christian Hammond <chipx86@chipx86.com>
parents:
4561
diff
changeset
|
3495 G_CALLBACK(close_conv_cb), conv); |
4359 | 3496 |
3497 /* Tab label. */ | |
3498 gtkconv->tab_label = gtk_label_new(gaim_conversation_get_title(conv)); | |
3499 #if 0 | |
3500 gtk_misc_set_alignment(GTK_MISC(gtkconv->tab_label), 0.00, 0.5); | |
3501 gtk_misc_set_padding(GTK_MISC(gtkconv->tab_label), 4, 0); | |
3502 #endif | |
3503 | |
3504 /* Pack it all together. */ | |
3505 gtk_box_pack_start(GTK_BOX(tabby), gtkconv->tab_label, TRUE, TRUE, 0); | |
4445 | 3506 gtk_widget_show(gtkconv->tab_label); |
3507 gtk_box_pack_start(GTK_BOX(tabby), gtkconv->close, FALSE, FALSE, 0); | |
3508 if (!(convo_options & OPT_CONVO_NO_X_ON_TAB)) | |
3509 gtk_widget_show_all(gtkconv->close); | |
3510 gtk_widget_show(tabby); | |
4359 | 3511 |
3512 | |
3513 /* Add this pane to the conversations notebook. */ | |
3514 gtk_notebook_append_page(GTK_NOTEBOOK(gtkwin->notebook), tab_cont, tabby); | |
3515 gtk_notebook_set_menu_label_text(GTK_NOTEBOOK(gtkwin->notebook), tab_cont, | |
3516 gaim_conversation_get_title(conv)); | |
3517 | |
3518 gtk_widget_show(tab_cont); | |
3519 | |
3520 /* Er, bug in notebooks? Switch to the page manually. */ | |
3521 if (gaim_window_get_conversation_count(win) == 1) | |
3522 gtk_notebook_set_current_page(GTK_NOTEBOOK(gtkwin->notebook), 0); | |
3523 | |
3524 if ((gtk_notebook_get_current_page(GTK_NOTEBOOK(gtkwin->notebook)) == 0) || | |
3525 (conv == g_list_nth_data(gaim_window_get_conversations(win), 0))) { | |
3526 | |
3527 gtk_widget_grab_focus(gtkconv->entry); | |
3528 } | |
3529 | |
3530 gaim_gtkconv_update_buddy_icon(conv); | |
3531 | |
3532 if (!new_ui) | |
3533 g_object_unref(gtkconv->tab_cont); | |
3534 | |
3535 if (gaim_window_get_conversation_count(win) == 1) | |
3536 update_send_as_selection(win); | |
3537 } | |
3538 | |
3539 static void | |
3540 gaim_gtk_remove_conversation(struct gaim_window *win, | |
3541 struct gaim_conversation *conv) | |
3542 { | |
3543 struct gaim_gtk_window *gtkwin; | |
3544 struct gaim_gtk_conversation *gtkconv; | |
3545 unsigned int index; | |
3546 | |
3547 index = gaim_conversation_get_index(conv); | |
3548 | |
3549 gtkwin = GAIM_GTK_WINDOW(win); | |
3550 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
3551 | |
3552 g_object_ref(gtkconv->tab_cont); | |
3553 gtk_object_sink(GTK_OBJECT(gtkconv->tab_cont)); | |
3554 | |
3555 gaim_gtk_set_state_lock(TRUE); | |
3556 | |
3557 gtk_notebook_remove_page(GTK_NOTEBOOK(gtkwin->notebook), index); | |
3558 | |
3559 gaim_gtk_set_state_lock(FALSE); | |
3560 | |
3561 /* If this window is setup with an inactive gc, regenerate the menu. */ | |
3562 if (gaim_conversation_get_type(conv) == GAIM_CONV_IM && | |
3563 gaim_conversation_get_gc(conv) == NULL) { | |
3564 | |
4360
c435a29370b8
[gaim-migrate @ 4626]
Christian Hammond <chipx86@chipx86.com>
parents:
4359
diff
changeset
|
3565 generate_send_as_items(win, conv); |
4359 | 3566 } |
3567 } | |
3568 | |
3569 static void | |
3570 gaim_gtk_move_conversation(struct gaim_window *win, | |
3571 struct gaim_conversation *conv, | |
3572 unsigned int new_index) | |
3573 { | |
3574 struct gaim_gtk_window *gtkwin; | |
3575 struct gaim_gtk_conversation *gtkconv; | |
3576 | |
3577 gtkwin = GAIM_GTK_WINDOW(win); | |
3578 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
3579 | |
4415
c90039137172
[gaim-migrate @ 4688]
Christian Hammond <chipx86@chipx86.com>
parents:
4409
diff
changeset
|
3580 if (new_index > gaim_conversation_get_index(conv)) |
c90039137172
[gaim-migrate @ 4688]
Christian Hammond <chipx86@chipx86.com>
parents:
4409
diff
changeset
|
3581 new_index--; |
c90039137172
[gaim-migrate @ 4688]
Christian Hammond <chipx86@chipx86.com>
parents:
4409
diff
changeset
|
3582 |
4359 | 3583 gtk_notebook_reorder_child(GTK_NOTEBOOK(gtkwin->notebook), |
3584 gtkconv->tab_cont, new_index); | |
3585 } | |
3586 | |
3587 static int | |
3588 gaim_gtk_get_active_index(const struct gaim_window *win) | |
3589 { | |
3590 struct gaim_gtk_window *gtkwin; | |
3591 | |
3592 gtkwin = GAIM_GTK_WINDOW(win); | |
3593 | |
3594 return gtk_notebook_get_current_page(GTK_NOTEBOOK(gtkwin->notebook)); | |
3595 } | |
3596 | |
4465
6e37eb000b7a
[gaim-migrate @ 4740]
Christian Hammond <chipx86@chipx86.com>
parents:
4454
diff
changeset
|
3597 static struct gaim_window_ui_ops window_ui_ops = |
4359 | 3598 { |
4465
6e37eb000b7a
[gaim-migrate @ 4740]
Christian Hammond <chipx86@chipx86.com>
parents:
4454
diff
changeset
|
3599 gaim_gtk_get_conversation_ui_ops, |
4359 | 3600 gaim_gtk_new_window, |
3601 gaim_gtk_destroy_window, | |
3602 gaim_gtk_show, | |
3603 gaim_gtk_hide, | |
3604 gaim_gtk_raise, | |
3605 gaim_gtk_flash, | |
3606 gaim_gtk_switch_conversation, | |
3607 gaim_gtk_add_conversation, | |
3608 gaim_gtk_remove_conversation, | |
3609 gaim_gtk_move_conversation, | |
3610 gaim_gtk_get_active_index | |
3611 }; | |
3612 | |
3613 static void | |
3614 update_convo_add_button(struct gaim_conversation *conv) | |
3615 { | |
3616 struct gaim_gtk_conversation *gtkconv; | |
3617 struct gaim_connection *gc; | |
3618 GaimConversationType type; | |
3619 GtkWidget *parent; | |
3620 | |
3621 type = gaim_conversation_get_type(conv); | |
3622 gc = gaim_conversation_get_gc(conv); | |
3623 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
3624 parent = gtk_widget_get_parent(gtkconv->u.im->add); | |
3625 | |
4491 | 3626 if (find_buddy(gc->account, gaim_conversation_get_name(conv))) { |
4397
ce3a0eba91ef
[gaim-migrate @ 4666]
Christian Hammond <chipx86@chipx86.com>
parents:
4387
diff
changeset
|
3627 gtkconv->u.im->add = |
ce3a0eba91ef
[gaim-migrate @ 4666]
Christian Hammond <chipx86@chipx86.com>
parents:
4387
diff
changeset
|
3628 gaim_gtk_change_text(_("Remove"), gtkconv->u.im->add, |
ce3a0eba91ef
[gaim-migrate @ 4666]
Christian Hammond <chipx86@chipx86.com>
parents:
4387
diff
changeset
|
3629 GTK_STOCK_REMOVE, type); |
ce3a0eba91ef
[gaim-migrate @ 4666]
Christian Hammond <chipx86@chipx86.com>
parents:
4387
diff
changeset
|
3630 gtk_tooltips_set_tip(gtkconv->tooltips, gtkconv->u.im->add, |
ce3a0eba91ef
[gaim-migrate @ 4666]
Christian Hammond <chipx86@chipx86.com>
parents:
4387
diff
changeset
|
3631 _("Remove the user from your buddy list"), NULL); |
ce3a0eba91ef
[gaim-migrate @ 4666]
Christian Hammond <chipx86@chipx86.com>
parents:
4387
diff
changeset
|
3632 |
4359 | 3633 gtk_widget_set_sensitive(gtkconv->u.im->add, |
3634 (gc != NULL && gc->prpl->remove_buddy != NULL)); | |
3635 } else { | |
4397
ce3a0eba91ef
[gaim-migrate @ 4666]
Christian Hammond <chipx86@chipx86.com>
parents:
4387
diff
changeset
|
3636 gtkconv->u.im->add = |
ce3a0eba91ef
[gaim-migrate @ 4666]
Christian Hammond <chipx86@chipx86.com>
parents:
4387
diff
changeset
|
3637 gaim_gtk_change_text(_("Add"), gtkconv->u.im->add, |
ce3a0eba91ef
[gaim-migrate @ 4666]
Christian Hammond <chipx86@chipx86.com>
parents:
4387
diff
changeset
|
3638 GTK_STOCK_ADD, type); |
ce3a0eba91ef
[gaim-migrate @ 4666]
Christian Hammond <chipx86@chipx86.com>
parents:
4387
diff
changeset
|
3639 gtk_tooltips_set_tip(gtkconv->tooltips, gtkconv->u.im->add, |
ce3a0eba91ef
[gaim-migrate @ 4666]
Christian Hammond <chipx86@chipx86.com>
parents:
4387
diff
changeset
|
3640 _("Add the user to your buddy list"), NULL); |
4359 | 3641 |
3642 gtk_widget_set_sensitive(gtkconv->u.im->add, | |
3643 (gc != NULL && gc->prpl->add_buddy != NULL)); | |
3644 } | |
3645 | |
4397
ce3a0eba91ef
[gaim-migrate @ 4666]
Christian Hammond <chipx86@chipx86.com>
parents:
4387
diff
changeset
|
3646 g_signal_connect(G_OBJECT(gtkconv->u.im->add), "clicked", |
ce3a0eba91ef
[gaim-migrate @ 4666]
Christian Hammond <chipx86@chipx86.com>
parents:
4387
diff
changeset
|
3647 G_CALLBACK(add_cb), conv); |
ce3a0eba91ef
[gaim-migrate @ 4666]
Christian Hammond <chipx86@chipx86.com>
parents:
4387
diff
changeset
|
3648 |
ce3a0eba91ef
[gaim-migrate @ 4666]
Christian Hammond <chipx86@chipx86.com>
parents:
4387
diff
changeset
|
3649 gtk_box_pack_start(GTK_BOX(parent), gtkconv->u.im->add, |
ce3a0eba91ef
[gaim-migrate @ 4666]
Christian Hammond <chipx86@chipx86.com>
parents:
4387
diff
changeset
|
3650 FALSE, FALSE, 0); |
ce3a0eba91ef
[gaim-migrate @ 4666]
Christian Hammond <chipx86@chipx86.com>
parents:
4387
diff
changeset
|
3651 gtk_box_reorder_child(GTK_BOX(parent), gtkconv->u.im->add, 3); |
ce3a0eba91ef
[gaim-migrate @ 4666]
Christian Hammond <chipx86@chipx86.com>
parents:
4387
diff
changeset
|
3652 gtk_button_set_relief(GTK_BUTTON(gtkconv->u.im->add), GTK_RELIEF_NONE); |
ce3a0eba91ef
[gaim-migrate @ 4666]
Christian Hammond <chipx86@chipx86.com>
parents:
4387
diff
changeset
|
3653 gtk_size_group_add_widget(gtkconv->sg, gtkconv->u.im->add); |
4359 | 3654 } |
3655 | |
4465
6e37eb000b7a
[gaim-migrate @ 4740]
Christian Hammond <chipx86@chipx86.com>
parents:
4454
diff
changeset
|
3656 struct gaim_window_ui_ops * |
6e37eb000b7a
[gaim-migrate @ 4740]
Christian Hammond <chipx86@chipx86.com>
parents:
4454
diff
changeset
|
3657 gaim_get_gtk_window_ui_ops(void) |
4359 | 3658 { |
4465
6e37eb000b7a
[gaim-migrate @ 4740]
Christian Hammond <chipx86@chipx86.com>
parents:
4454
diff
changeset
|
3659 return &window_ui_ops; |
4359 | 3660 } |
3661 | |
3662 /************************************************************************** | |
4465
6e37eb000b7a
[gaim-migrate @ 4740]
Christian Hammond <chipx86@chipx86.com>
parents:
4454
diff
changeset
|
3663 * Conversation UI operations |
4359 | 3664 **************************************************************************/ |
3665 static void | |
3666 gaim_gtkconv_destroy(struct gaim_conversation *conv) | |
3667 { | |
3668 struct gaim_gtk_conversation *gtkconv = GAIM_GTK_CONVERSATION(conv); | |
3669 | |
3670 if (gtkconv->dialogs.fg_color != NULL) | |
3671 gtk_widget_destroy(gtkconv->dialogs.fg_color); | |
3672 | |
3673 if (gtkconv->dialogs.bg_color != NULL) | |
3674 gtk_widget_destroy(gtkconv->dialogs.bg_color); | |
3675 | |
3676 if (gtkconv->dialogs.font != NULL) | |
3677 gtk_widget_destroy(gtkconv->dialogs.font); | |
3678 | |
3679 if (gtkconv->dialogs.smiley != NULL) | |
3680 gtk_widget_destroy(gtkconv->dialogs.smiley); | |
3681 | |
3682 if (gtkconv->dialogs.link != NULL) | |
3683 gtk_widget_destroy(gtkconv->dialogs.link); | |
3684 | |
3685 if (gtkconv->dialogs.log != NULL) | |
3686 gtk_widget_destroy(gtkconv->dialogs.log); | |
3687 | |
4571
51e988d015ed
[gaim-migrate @ 4852]
Christian Hammond <chipx86@chipx86.com>
parents:
4561
diff
changeset
|
3688 gtk_widget_destroy(gtkconv->tab_cont); |
51e988d015ed
[gaim-migrate @ 4852]
Christian Hammond <chipx86@chipx86.com>
parents:
4561
diff
changeset
|
3689 |
4359 | 3690 if (gaim_conversation_get_type(conv) == GAIM_CONV_IM) { |
3691 if (gtkconv->u.im->save_icon != NULL) | |
3692 gtk_widget_destroy(gtkconv->u.im->save_icon); | |
3693 | |
3694 if (gtkconv->u.im->anim != NULL) | |
3695 gdk_pixbuf_animation_unref(gtkconv->u.im->anim); | |
3696 | |
3697 g_free(gtkconv->u.im); | |
3698 } | |
3699 else if (gaim_conversation_get_type(conv) == GAIM_CONV_CHAT) { | |
3700 g_free(gtkconv->u.chat); | |
3701 } | |
3702 | |
4633 | 3703 gtk_object_sink(GTK_OBJECT(gtkconv->tooltips)); |
3704 | |
4359 | 3705 g_free(gtkconv); |
3706 } | |
3707 | |
3708 static void | |
3709 gaim_gtkconv_write_im(struct gaim_conversation *conv, const char *who, | |
3710 const char *message, size_t len, int flags, time_t mtime) | |
3711 { | |
3712 struct gaim_gtk_conversation *gtkconv; | |
3713 | |
3714 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
3715 | |
4382
76223649765b
[gaim-migrate @ 4648]
Christian Hammond <chipx86@chipx86.com>
parents:
4378
diff
changeset
|
3716 /* Play a sound, if specified in prefs. */ |
4359 | 3717 if (gtkconv->make_sound) { |
3718 if (flags & WFLAG_RECV) { | |
3719 if (gtkconv->u.im->a_virgin && | |
3720 (sound_options & OPT_SOUND_FIRST_RCV)) { | |
3721 | |
4561 | 3722 gaim_sound_play_event(GAIM_SOUND_FIRST_RECEIVE); |
4359 | 3723 } |
3724 else | |
4561 | 3725 gaim_sound_play_event(GAIM_SOUND_RECEIVE); |
4359 | 3726 } |
3727 else { | |
4561 | 3728 gaim_sound_play_event(GAIM_SOUND_SEND); |
4359 | 3729 } |
3730 } | |
3731 | |
3732 gtkconv->u.im->a_virgin = FALSE; | |
3733 | |
3734 gaim_conversation_write(conv, who, message, len, flags, mtime); | |
3735 } | |
3736 | |
3737 static void | |
3738 gaim_gtkconv_write_chat(struct gaim_conversation *conv, const char *who, | |
3739 const char *message, int flags, time_t mtime) | |
3740 { | |
3741 struct gaim_gtk_conversation *gtkconv; | |
3742 | |
3743 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
3744 | |
4382
76223649765b
[gaim-migrate @ 4648]
Christian Hammond <chipx86@chipx86.com>
parents:
4378
diff
changeset
|
3745 /* Play a sound, if specified in prefs. */ |
4359 | 3746 if (gtkconv->make_sound) { |
3747 if (!(flags & WFLAG_WHISPER) && (flags & WFLAG_SEND)) | |
4561 | 3748 gaim_sound_play_event(GAIM_SOUND_CHAT_YOU_SAY); |
4359 | 3749 else if (flags & WFLAG_RECV) { |
3750 if ((flags & WFLAG_NICK) && (sound_options & OPT_SOUND_CHAT_NICK)) | |
4561 | 3751 gaim_sound_play_event(GAIM_SOUND_CHAT_NICK); |
4359 | 3752 else |
4561 | 3753 gaim_sound_play_event(GAIM_SOUND_CHAT_SAY); |
4359 | 3754 } |
3755 } | |
3756 | |
3757 if (chat_options & OPT_CHAT_COLORIZE) | |
3758 flags |= WFLAG_COLORIZE; | |
3759 | |
3760 gaim_conversation_write(conv, who, message, -1, flags, mtime); | |
3761 } | |
3762 | |
3763 static void | |
3764 gaim_gtkconv_write_conv(struct gaim_conversation *conv, const char *who, | |
3765 const char *message, size_t length, int flags, | |
3766 time_t mtime) | |
3767 { | |
3768 struct gaim_gtk_conversation *gtkconv; | |
3769 struct gaim_connection *gc; | |
3770 int gtk_font_options = 0; | |
3771 GString *log_str; | |
3772 FILE *fd; | |
3773 char buf[BUF_LONG]; | |
3774 char buf2[BUF_LONG]; | |
3775 char mdate[64]; | |
3776 char color[10]; | |
3777 char *str; | |
3778 char *with_font_tag; | |
3779 | |
3780 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
3781 gc = gaim_conversation_get_gc(conv); | |
3782 | |
3783 strftime(mdate, sizeof(mdate), "%H:%M:%S", localtime(&mtime)); | |
3784 | |
3785 gtk_font_options ^= GTK_IMHTML_NO_COMMENTS; | |
3786 | |
3787 if (convo_options & OPT_CONVO_IGNORE_COLOUR) | |
3788 gtk_font_options ^= GTK_IMHTML_NO_COLOURS; | |
3789 | |
3790 if (convo_options & OPT_CONVO_IGNORE_FONTS) | |
3791 gtk_font_options ^= GTK_IMHTML_NO_FONTS; | |
3792 | |
3793 if (convo_options & OPT_CONVO_IGNORE_SIZES) | |
3794 gtk_font_options ^= GTK_IMHTML_NO_SIZES; | |
3795 | |
3796 if (!(logging_options & OPT_LOG_STRIP_HTML)) | |
3797 gtk_font_options ^= GTK_IMHTML_RETURN_LOG; | |
3798 | |
3799 if (flags & WFLAG_SYSTEM) { | |
3800 if (convo_options & OPT_CONVO_SHOW_TIME) | |
3801 g_snprintf(buf, BUF_LONG, "<FONT SIZE=\"2\">(%s) </FONT><B>%s</B>", | |
3802 mdate, message); | |
3803 else | |
3804 g_snprintf(buf, BUF_LONG, "<B>%s</B>", message); | |
3805 | |
3806 g_snprintf(buf2, sizeof(buf2), | |
3807 "<FONT SIZE=\"2\"><!--(%s) --></FONT><B>%s</B><BR>", | |
3808 mdate, message); | |
3809 | |
3810 gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), buf2, -1, 0); | |
3811 | |
3812 if (logging_options & OPT_LOG_STRIP_HTML) { | |
3813 char *t1 = strip_html(buf); | |
3814 | |
3815 conv->history = g_string_append(conv->history, t1); | |
3816 conv->history = g_string_append(conv->history, "\n"); | |
3817 | |
3818 g_free(t1); | |
3819 } | |
3820 else { | |
3821 conv->history = g_string_append(conv->history, buf); | |
3822 conv->history = g_string_append(conv->history, "<BR>\n"); | |
3823 } | |
3824 | |
3825 if (!(flags & WFLAG_NOLOG) && gaim_conversation_is_logging(conv)) { | |
3826 | |
3827 char *t1; | |
3828 char nm[256]; | |
3829 | |
3830 if (logging_options & OPT_LOG_STRIP_HTML) | |
3831 t1 = strip_html(buf); | |
3832 else | |
3833 t1 = buf; | |
3834 | |
3835 if (gaim_conversation_get_type(conv) == GAIM_CONV_CHAT) | |
3836 g_snprintf(nm, sizeof(nm), "%s.chat", | |
3837 gaim_conversation_get_name(conv)); | |
3838 else | |
3839 strncpy(nm, gaim_conversation_get_name(conv), sizeof(nm)); | |
3840 | |
3841 fd = open_log_file(nm, | |
3842 (gaim_conversation_get_type(conv) == GAIM_CONV_CHAT)); | |
3843 | |
3844 if (fd) { | |
3845 if (logging_options & OPT_LOG_STRIP_HTML) | |
3846 fprintf(fd, "%s\n", t1); | |
3847 else | |
3848 fprintf(fd, "%s<BR>\n", t1); | |
3849 | |
3850 fclose(fd); | |
3851 } | |
3852 | |
3853 if (logging_options & OPT_LOG_STRIP_HTML) | |
3854 g_free(t1); | |
3855 } | |
3856 } | |
3857 else if (flags & WFLAG_NOLOG) { | |
3858 g_snprintf(buf, BUF_LONG, | |
3859 "<B><FONT COLOR=\"#777777\">%s</FONT></B><BR>", | |
3860 message); | |
3861 | |
3862 gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), buf, -1, 0); | |
3863 } | |
3864 else { | |
3865 char *new_message = g_strdup(message); | |
3866 | |
3867 if (flags & WFLAG_WHISPER) { | |
3868 str = g_malloc(1024); | |
3869 | |
3870 /* If we're whispering, it's not an autoresponse. */ | |
3871 if (meify(new_message, length)) { | |
3872 g_snprintf(str, 1024, "***%s", who); | |
3873 strcpy(color, "#6C2585"); | |
3874 } | |
3875 else { | |
3876 g_snprintf(str, 1024, "*%s*:", who); | |
3877 strcpy(color, "#00FF00"); | |
3878 } | |
3879 } | |
3880 else { | |
3881 if (meify(new_message, length)) { | |
3882 str = g_malloc(1024); | |
3883 | |
3884 if (flags & WFLAG_AUTO) | |
3885 g_snprintf(str, 1024, "%s ***%s", AUTO_RESPONSE, who); | |
3886 else | |
3887 g_snprintf(str, 1024, "***%s", who); | |
3888 | |
3889 if (flags & WFLAG_NICK) | |
3890 strcpy(color, "#AF7F00"); | |
3891 else | |
3892 strcpy(color, "#062585"); | |
3893 } | |
3894 else { | |
3895 str = g_malloc(1024); | |
3896 | |
3897 if (flags & WFLAG_AUTO) | |
3898 g_snprintf(str, 1024, "%s %s", who, AUTO_RESPONSE); | |
3899 else | |
3900 g_snprintf(str, 1024, "%s:", who); | |
3901 | |
3902 if (flags & WFLAG_NICK) | |
3903 strcpy(color, "#AF7F00"); | |
3904 else if (flags & WFLAG_RECV) { | |
3905 if (flags & WFLAG_COLORIZE) { | |
3906 const char *u; | |
3907 int m = 0; | |
3908 | |
3909 for (u = who; *u != '\0'; u++) | |
3910 m += *u; | |
3911 | |
3912 m = m % NUM_NICK_COLORS; | |
3913 | |
3914 strcpy(color, nick_colors[m]); | |
3915 } | |
3916 else | |
3917 strcpy(color, "#A82F2F"); | |
3918 } | |
3919 else if (flags & WFLAG_SEND) | |
3920 strcpy(color, "#16569E"); | |
3921 } | |
3922 } | |
3923 | |
3924 if (convo_options & OPT_CONVO_SHOW_TIME) | |
3925 g_snprintf(buf, BUF_LONG, | |
3926 "<FONT COLOR=\"%s\"><FONT SIZE=\"2\">(%s) </FONT>" | |
3927 "<B>%s</B></FONT> ", color, mdate, str); | |
3928 else | |
3929 g_snprintf(buf, BUF_LONG, | |
3930 "<FONT COLOR=\"%s\"><B>%s</B></FONT> ", color, str); | |
3931 | |
3932 g_snprintf(buf2, BUF_LONG, | |
3933 "<FONT COLOR=\"%s\"><FONT SIZE=\"2\"><!--(%s) --></FONT>" | |
3934 "<B>%s</B></FONT> ", | |
3935 color, mdate, str); | |
3936 | |
3937 g_free(str); | |
3938 | |
3939 gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), buf2, -1, 0); | |
3940 | |
4608 | 3941 if(gc) |
3942 with_font_tag = g_strdup_printf("<font sml=\"%s\">%s</font>", | |
4359 | 3943 gc->prpl->name, new_message); |
4608 | 3944 else |
3945 with_font_tag = g_strdup(new_message); | |
4359 | 3946 |
3947 log_str = gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), | |
3948 with_font_tag, length, | |
3949 gtk_font_options); | |
3950 | |
3951 gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), "<BR>", -1, 0); | |
3952 | |
3953 /* XXX This needs to be updated for the new length argument. */ | |
3954 if (logging_options & OPT_LOG_STRIP_HTML) { | |
3955 char *t1, *t2; | |
3956 | |
3957 t1 = strip_html(buf); | |
3958 t2 = strip_html(new_message); | |
3959 | |
3960 conv->history = g_string_append(conv->history, t1); | |
3961 conv->history = g_string_append(conv->history, t2); | |
3962 conv->history = g_string_append(conv->history, "\n"); | |
3963 | |
3964 g_free(t1); | |
3965 g_free(t2); | |
3966 } | |
3967 else { | |
3968 char *t1, *t2; | |
3969 | |
3970 t1 = html_logize(buf); | |
3971 t2 = html_logize(new_message); | |
3972 | |
3973 conv->history = g_string_append(conv->history, t1); | |
3974 conv->history = g_string_append(conv->history, t2); | |
3975 conv->history = g_string_append(conv->history, "\n"); | |
3976 conv->history = g_string_append(conv->history, log_str->str); | |
3977 conv->history = g_string_append(conv->history, "<BR>\n"); | |
3978 | |
3979 g_free(t1); | |
3980 g_free(t2); | |
3981 } | |
3982 | |
3983 /* XXX This needs to be updated for the new length argument. */ | |
3984 if (gaim_conversation_is_logging(conv)) { | |
3985 char *t1, *t2; | |
3986 char nm[256]; | |
3987 | |
3988 if (gaim_conversation_get_type(conv) == GAIM_CONV_CHAT) | |
3989 g_snprintf(nm, sizeof(nm), "%s.chat", | |
3990 gaim_conversation_get_name(conv)); | |
3991 else | |
3992 strncpy(nm, gaim_conversation_get_name(conv), sizeof(nm)); | |
3993 | |
3994 if (logging_options & OPT_LOG_STRIP_HTML) { | |
3995 t1 = strip_html(buf); | |
3996 t2 = strip_html(with_font_tag); | |
3997 } | |
3998 else { | |
3999 t1 = html_logize(buf); | |
4000 t2 = html_logize(with_font_tag); | |
4001 } | |
4002 | |
4003 fd = open_log_file(nm, | |
4004 (gaim_conversation_get_type(conv) == GAIM_CONV_CHAT)); | |
4005 | |
4006 if (fd) { | |
4007 if (logging_options & OPT_LOG_STRIP_HTML) | |
4008 fprintf(fd, "%s%s\n", t1, t2); | |
4009 else { | |
4010 fprintf(fd, "%s%s%s<BR>\n", t1, t2, log_str->str); | |
4011 g_string_free(log_str, TRUE); | |
4012 } | |
4013 | |
4014 fclose(fd); | |
4015 } | |
4016 | |
4017 g_free(t1); | |
4018 g_free(t2); | |
4019 } | |
4020 | |
4021 g_free(with_font_tag); | |
4022 g_free(new_message); | |
4023 } | |
4024 } | |
4025 | |
4026 static void | |
4027 gaim_gtkconv_chat_add_user(struct gaim_conversation *conv, const char *user) | |
4028 { | |
4029 struct gaim_chat *chat; | |
4030 struct gaim_gtk_conversation *gtkconv; | |
4031 struct gaim_gtk_chat_pane *gtkchat; | |
4032 char tmp[BUF_LONG]; | |
4033 int num_users; | |
4034 int pos; | |
4035 | |
4036 chat = GAIM_CHAT(conv); | |
4037 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
4038 gtkchat = gtkconv->u.chat; | |
4039 | |
4040 num_users = g_list_length(gaim_chat_get_users(chat)); | |
4041 | |
4042 g_snprintf(tmp, sizeof(tmp), | |
4043 ngettext("%d person in room", "%d people in room", | |
4044 num_users), | |
4045 num_users); | |
4046 | |
4047 gtk_label_set_text(GTK_LABEL(gtkchat->count), tmp); | |
4048 | |
4049 if (gtkconv->make_sound) | |
4561 | 4050 gaim_sound_play_event(GAIM_SOUND_CHAT_JOIN); |
4359 | 4051 |
4052 pos = g_list_index(gaim_chat_get_users(chat), user); | |
4053 | |
4054 add_chat_buddy_common(conv, user, pos); | |
4055 } | |
4056 | |
4057 static void | |
4058 gaim_gtkconv_chat_rename_user(struct gaim_conversation *conv, | |
4059 const char *old_name, const char *new_name) | |
4060 { | |
4061 struct gaim_chat *chat; | |
4062 struct gaim_gtk_conversation *gtkconv; | |
4063 struct gaim_gtk_chat_pane *gtkchat; | |
4064 GtkTreeIter iter; | |
4065 GtkTreeModel *model; | |
4066 GList *names; | |
4067 int pos; | |
4068 int f = 1; | |
4069 | |
4070 chat = GAIM_CHAT(conv); | |
4071 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
4072 gtkchat = gtkconv->u.chat; | |
4073 | |
4074 for (names = gaim_chat_get_users(chat); | |
4075 names != NULL; | |
4076 names = names->next) { | |
4077 | |
4078 char *u = (char *)names->data; | |
4079 | |
4080 if (!g_strcasecmp(u, old_name)) { | |
4081 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); | |
4082 | |
4083 if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) | |
4084 break; | |
4085 | |
4086 while (f != 0) { | |
4087 char *val; | |
4088 | |
4089 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 1, &val, -1); | |
4090 | |
4640 | 4091 if (!g_strcasecmp(old_name, val)) { |
4359 | 4092 gtk_list_store_remove(GTK_LIST_STORE(model), &iter); |
4640 | 4093 break; |
4094 } | |
4359 | 4095 |
4096 f = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter); | |
4097 | |
4098 g_free(val); | |
4099 } | |
4100 | |
4101 break; | |
4102 } | |
4103 } | |
4104 | |
4105 if (!names) | |
4106 return; | |
4107 | |
4108 pos = g_list_index(gaim_chat_get_users(chat), new_name); | |
4109 | |
4110 add_chat_buddy_common(conv, new_name, pos); | |
4111 } | |
4112 | |
4113 static void | |
4114 gaim_gtkconv_chat_remove_user(struct gaim_conversation *conv, const char *user) | |
4115 { | |
4116 struct gaim_chat *chat; | |
4117 struct gaim_gtk_conversation *gtkconv; | |
4118 struct gaim_gtk_chat_pane *gtkchat; | |
4119 GtkTreeIter iter; | |
4120 GtkTreeModel *model; | |
4121 GList *names; | |
4122 char tmp[BUF_LONG]; | |
4123 int num_users; | |
4124 int f = 1; | |
4125 | |
4126 chat = GAIM_CHAT(conv); | |
4127 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
4128 gtkchat = gtkconv->u.chat; | |
4129 | |
4130 num_users = g_list_length(gaim_chat_get_users(chat)) - 1; | |
4131 | |
4132 for (names = gaim_chat_get_users(chat); | |
4133 names != NULL; | |
4134 names = names->next) { | |
4135 | |
4136 char *u = (char *)names->data; | |
4137 | |
4138 if (!g_strcasecmp(u, user)) { | |
4139 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); | |
4140 | |
4141 if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) | |
4142 break; | |
4143 | |
4144 while (f != 0) { | |
4145 char *val; | |
4146 | |
4147 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 1, &val, -1); | |
4148 | |
4149 if (!g_strcasecmp(user, val)) | |
4150 gtk_list_store_remove(GTK_LIST_STORE(model), &iter); | |
4151 | |
4152 f = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter); | |
4153 | |
4154 g_free(val); | |
4155 } | |
4156 | |
4157 break; | |
4158 } | |
4159 } | |
4160 | |
4161 if (names == NULL) | |
4162 return; | |
4163 | |
4164 g_snprintf(tmp, sizeof(tmp), | |
4165 ngettext("%d person in room", "%d people in room", | |
4166 num_users), num_users); | |
4167 | |
4168 gtk_label_set_text(GTK_LABEL(gtkchat->count), tmp); | |
4169 | |
4170 if (gtkconv->make_sound) | |
4561 | 4171 gaim_sound_play_event(GAIM_SOUND_CHAT_LEAVE); |
4359 | 4172 } |
4173 | |
4174 static void | |
4175 gaim_gtkconv_set_title(struct gaim_conversation *conv, const char *title) | |
4176 { | |
4177 struct gaim_gtk_conversation *gtkconv; | |
4681 | 4178 struct gaim_window *win; |
4179 struct gaim_gtk_window *gtkwin; | |
4180 | |
4181 win = gaim_conversation_get_window(conv); | |
4182 gtkwin = GAIM_GTK_WINDOW(win); | |
4359 | 4183 gtkconv = GAIM_GTK_CONVERSATION(conv); |
4184 | |
4185 gtk_label_set_text(GTK_LABEL(gtkconv->tab_label), title); | |
4681 | 4186 |
4187 if(conv == gaim_window_get_active_conversation(win)) | |
4188 gtk_window_set_title(GTK_WINDOW(gtkwin->window), title); | |
4359 | 4189 } |
4190 | |
4191 static void | |
4192 gaim_gtkconv_updated(struct gaim_conversation *conv, GaimConvUpdateType type) | |
4193 { | |
4194 struct gaim_window *win; | |
4195 struct gaim_gtk_conversation *gtkconv; | |
4196 struct gaim_gtk_chat_pane *gtkchat; | |
4197 struct gaim_chat *chat; | |
4198 | |
4199 win = gaim_conversation_get_window(conv); | |
4200 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
4201 | |
4491 | 4202 if (type == GAIM_CONV_UPDATE_ACCOUNT) { |
4359 | 4203 gaim_conversation_autoset_title(conv); |
4204 gaim_gtkconv_update_buddy_icon(conv); | |
4205 gaim_gtkconv_update_buttons_by_protocol(conv); | |
4206 | |
4207 update_send_as_selection(win); | |
4208 | |
4209 smiley_themeize(gtkconv->imhtml); | |
4210 } | |
4211 else if (type == GAIM_CONV_UPDATE_TYPING || | |
4212 type == GAIM_CONV_UPDATE_UNSEEN) { | |
4213 | |
4214 GtkStyle *style; | |
4215 struct gaim_im *im = NULL; | |
4216 | |
4217 if (gaim_conversation_get_type(conv) == GAIM_CONV_IM) | |
4218 im = GAIM_IM(conv); | |
4219 | |
4220 style = gtk_style_new(); | |
4221 | |
4222 if (!GTK_WIDGET_REALIZED(gtkconv->tab_label)) | |
4223 gtk_widget_realize(gtkconv->tab_label); | |
4224 | |
4635 | 4225 style->font_desc = pango_font_description_copy( |
4226 gtk_widget_get_style(gtkconv->tab_label)->font_desc); | |
4359 | 4227 |
4228 if (im != NULL && gaim_im_get_typing_state(im) == TYPING) { | |
4577 | 4229 style->fg[GTK_STATE_NORMAL].red = 0x4646; |
4230 style->fg[GTK_STATE_NORMAL].green = 0xA0A0; | |
4231 style->fg[GTK_STATE_NORMAL].blue = 0x4646; | |
4232 style->fg[GTK_STATE_ACTIVE] = style->fg[GTK_STATE_NORMAL]; | |
4359 | 4233 } |
4234 else if (im != NULL && gaim_im_get_typing_state(im) == TYPED) { | |
4577 | 4235 style->fg[GTK_STATE_NORMAL].red = 0xD1D1; |
4236 style->fg[GTK_STATE_NORMAL].green = 0x9494; | |
4237 style->fg[GTK_STATE_NORMAL].blue = 0x0C0C; | |
4238 style->fg[GTK_STATE_ACTIVE] = style->fg[GTK_STATE_NORMAL]; | |
4359 | 4239 } |
4240 else if (gaim_conversation_get_unseen(conv) == GAIM_UNSEEN_NICK) { | |
4577 | 4241 style->fg[GTK_STATE_ACTIVE].red = 0x3131; |
4242 style->fg[GTK_STATE_ACTIVE].green = 0x4E4E; | |
4243 style->fg[GTK_STATE_ACTIVE].blue = 0x6C6C; | |
4578 | 4244 style->fg[GTK_STATE_NORMAL] = style->fg[GTK_STATE_ACTIVE]; |
4359 | 4245 } |
4246 else if (gaim_conversation_get_unseen(conv) == GAIM_UNSEEN_TEXT) { | |
4577 | 4247 style->fg[GTK_STATE_ACTIVE].red = 0xDFDF; |
4248 style->fg[GTK_STATE_ACTIVE].green = 0x4242; | |
4249 style->fg[GTK_STATE_ACTIVE].blue = 0x1E1E; | |
4578 | 4250 style->fg[GTK_STATE_NORMAL] = style->fg[GTK_STATE_ACTIVE]; |
4359 | 4251 } |
4252 | |
4253 gtk_widget_set_style(gtkconv->tab_label, style); | |
4635 | 4254 g_object_unref(G_OBJECT(style)); |
4359 | 4255 } |
4256 else if (type == GAIM_CONV_UPDATE_TOPIC) { | |
4257 chat = GAIM_CHAT(conv); | |
4258 gtkchat = gtkconv->u.chat; | |
4259 | |
4260 gtk_entry_set_text(GTK_ENTRY(gtkchat->topic_text), | |
4261 gaim_chat_get_topic(chat)); | |
4262 } | |
4263 else if (type == GAIM_CONV_ACCOUNT_ONLINE || | |
4264 type == GAIM_CONV_ACCOUNT_OFFLINE) { | |
4265 | |
4360
c435a29370b8
[gaim-migrate @ 4626]
Christian Hammond <chipx86@chipx86.com>
parents:
4359
diff
changeset
|
4266 generate_send_as_items(win, NULL); |
4359 | 4267 } |
4397
ce3a0eba91ef
[gaim-migrate @ 4666]
Christian Hammond <chipx86@chipx86.com>
parents:
4387
diff
changeset
|
4268 else if(type == GAIM_CONV_UPDATE_ADD || |
ce3a0eba91ef
[gaim-migrate @ 4666]
Christian Hammond <chipx86@chipx86.com>
parents:
4387
diff
changeset
|
4269 type == GAIM_CONV_UPDATE_REMOVE) { |
ce3a0eba91ef
[gaim-migrate @ 4666]
Christian Hammond <chipx86@chipx86.com>
parents:
4387
diff
changeset
|
4270 |
ce3a0eba91ef
[gaim-migrate @ 4666]
Christian Hammond <chipx86@chipx86.com>
parents:
4387
diff
changeset
|
4271 update_convo_add_button(conv); |
ce3a0eba91ef
[gaim-migrate @ 4666]
Christian Hammond <chipx86@chipx86.com>
parents:
4387
diff
changeset
|
4272 } |
4359 | 4273 } |
4274 | |
4465
6e37eb000b7a
[gaim-migrate @ 4740]
Christian Hammond <chipx86@chipx86.com>
parents:
4454
diff
changeset
|
4275 static struct gaim_conversation_ui_ops conversation_ui_ops = |
4359 | 4276 { |
4277 gaim_gtkconv_destroy, /* destroy_conversation */ | |
4278 gaim_gtkconv_write_chat, /* write_chat */ | |
4279 gaim_gtkconv_write_im, /* write_im */ | |
4280 gaim_gtkconv_write_conv, /* write_conv */ | |
4281 gaim_gtkconv_chat_add_user, /* chat_add_user */ | |
4282 gaim_gtkconv_chat_rename_user, /* chat_rename_user */ | |
4283 gaim_gtkconv_chat_remove_user, /* chat_remove_user */ | |
4284 gaim_gtkconv_set_title, /* set_title */ | |
4285 NULL, /* update_progress */ | |
4286 gaim_gtkconv_updated /* updated */ | |
4287 }; | |
4288 | |
4465
6e37eb000b7a
[gaim-migrate @ 4740]
Christian Hammond <chipx86@chipx86.com>
parents:
4454
diff
changeset
|
4289 struct gaim_conversation_ui_ops * |
6e37eb000b7a
[gaim-migrate @ 4740]
Christian Hammond <chipx86@chipx86.com>
parents:
4454
diff
changeset
|
4290 gaim_get_gtk_conversation_ui_ops(void) |
4359 | 4291 { |
4465
6e37eb000b7a
[gaim-migrate @ 4740]
Christian Hammond <chipx86@chipx86.com>
parents:
4454
diff
changeset
|
4292 return &conversation_ui_ops; |
4359 | 4293 } |
4294 | |
4295 /************************************************************************** | |
4296 * Public conversation utility functions | |
4297 **************************************************************************/ | |
4298 void | |
4299 gaim_gtk_set_state_lock(gboolean lock) | |
4300 { | |
4301 state_lock = lock; | |
4302 } | |
4303 | |
4304 gboolean | |
4305 gaim_gtk_is_state_locked(void) | |
4306 { | |
4307 return state_lock; | |
4308 } | |
4309 | |
4310 void | |
4311 gaim_gtkconv_toggle_smileys(void) | |
4312 { | |
4313 GList *cl; | |
4314 struct gaim_conversation *conv; | |
4315 struct gaim_gtk_conversation *gtkconv; | |
4316 | |
4317 for (cl = gaim_get_conversations(); cl != NULL; cl = cl->next) { | |
4318 | |
4319 conv = (struct gaim_conversation *)cl->data; | |
4320 | |
4398
a8249a5250b6
[gaim-migrate @ 4667]
Christian Hammond <chipx86@chipx86.com>
parents:
4397
diff
changeset
|
4321 if (!GAIM_IS_GTK_CONVERSATION(conv)) |
4359 | 4322 continue; |
4323 | |
4324 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
4325 | |
4326 gtk_imhtml_show_smileys(GTK_IMHTML(gtkconv->imhtml), | |
4327 (convo_options & OPT_CONVO_SHOW_SMILEY)); | |
4328 } | |
4329 } | |
4330 | |
4331 void | |
4332 gaim_gtkconv_toggle_timestamps(void) | |
4333 { | |
4334 GList *cl; | |
4335 struct gaim_conversation *conv; | |
4336 struct gaim_gtk_conversation *gtkconv; | |
4337 | |
4338 for (cl = gaim_get_conversations(); cl != NULL; cl = cl->next) { | |
4339 | |
4340 conv = (struct gaim_conversation *)cl->data; | |
4341 | |
4398
a8249a5250b6
[gaim-migrate @ 4667]
Christian Hammond <chipx86@chipx86.com>
parents:
4397
diff
changeset
|
4342 if (!GAIM_IS_GTK_CONVERSATION(conv)) |
4359 | 4343 continue; |
4344 | |
4345 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
4346 | |
4347 gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml), | |
4348 (convo_options & OPT_CONVO_SHOW_TIME)); | |
4349 } | |
4350 } | |
4351 | |
4352 void | |
4353 gaim_gtkconv_toggle_spellchk(void) | |
4354 { | |
4355 #ifdef USE_GTKSPELL | |
4356 GList *cl; | |
4357 struct gaim_conversation *conv; | |
4358 struct gaim_gtk_conversation *gtkconv; | |
4359 GtkSpell *spell; | |
4360 | |
4361 for (cl = gaim_get_conversations(); cl != NULL; cl = cl->next) { | |
4362 | |
4363 conv = (struct gaim_conversation *)cl->data; | |
4364 | |
4398
a8249a5250b6
[gaim-migrate @ 4667]
Christian Hammond <chipx86@chipx86.com>
parents:
4397
diff
changeset
|
4365 if (!GAIM_IS_GTK_CONVERSATION(conv)) |
4359 | 4366 continue; |
4367 | |
4368 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
4369 | |
4370 if (convo_options & OPT_CONVO_CHECK_SPELLING) | |
4371 gtkspell_new_attach(GTK_TEXT_VIEW(gtkconv->entry), NULL, NULL); | |
4372 else { | |
4373 spell = gtkspell_get_from_text_view(GTK_TEXT_VIEW(gtkconv->entry)); | |
4374 gtkspell_detach(spell); | |
4375 } | |
4376 } | |
4377 #endif | |
4378 } | |
4379 | |
4445 | 4380 void |
4381 gaim_gtkconv_toggle_close_buttons(void) | |
4382 { | |
4383 GList *cl; | |
4384 struct gaim_conversation *conv; | |
4385 struct gaim_gtk_conversation *gtkconv; | |
4386 | |
4387 for (cl = gaim_get_conversations(); cl != NULL; cl = cl->next) { | |
4388 conv = (struct gaim_conversation *)cl->data; | |
4389 if (!GAIM_IS_GTK_CONVERSATION(conv)) | |
4390 continue; | |
4391 | |
4392 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
4393 | |
4394 if (convo_options & OPT_CONVO_NO_X_ON_TAB) | |
4395 gtk_widget_hide(gtkconv->close); | |
4396 else | |
4397 gtk_widget_show_all(gtkconv->close); | |
4398 } | |
4399 } | |
4400 | |
4359 | 4401 static void |
4402 remove_icon(struct gaim_gtk_conversation *gtkconv) | |
4403 { | |
4404 if (gtkconv == NULL) | |
4405 return; | |
4406 | |
4407 if (gtkconv->u.im->icon != NULL) | |
4408 gtk_container_remove(GTK_CONTAINER(gtkconv->bbox), | |
4409 gtkconv->u.im->icon->parent->parent); | |
4410 | |
4411 if (gtkconv->u.im->anim != NULL) | |
4412 gdk_pixbuf_animation_unref(gtkconv->u.im->anim); | |
4413 | |
4414 if (gtkconv->u.im->icon_timer != 0) | |
4415 g_source_remove(gtkconv->u.im->icon_timer); | |
4416 | |
4417 if (gtkconv->u.im->iter != NULL) | |
4418 g_object_unref(G_OBJECT(gtkconv->u.im->iter)); | |
4419 | |
4420 gtkconv->u.im->icon_timer = 0; | |
4421 gtkconv->u.im->icon = NULL; | |
4422 gtkconv->u.im->anim = NULL; | |
4423 gtkconv->u.im->iter = NULL; | |
4424 } | |
4425 | |
4426 static gboolean | |
4427 redraw_icon(gpointer data) | |
4428 { | |
4429 struct gaim_conversation *conv = (struct gaim_conversation *)data; | |
4430 struct gaim_gtk_conversation *gtkconv; | |
4431 | |
4432 GdkPixbuf *buf; | |
4433 GdkPixbuf *scale; | |
4434 GdkPixmap *pm; | |
4435 GdkBitmap *bm; | |
4436 gint delay; | |
4437 | |
4438 if (!g_list_find(gaim_get_ims(), conv)) { | |
4439 debug_printf("I think this is a bug.\n"); | |
4440 return FALSE; | |
4441 } | |
4442 | |
4443 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
4444 | |
4445 gdk_pixbuf_animation_iter_advance(gtkconv->u.im->iter, NULL); | |
4446 buf = gdk_pixbuf_animation_iter_get_pixbuf(gtkconv->u.im->iter); | |
4447 | |
4448 scale = gdk_pixbuf_scale_simple(buf, | |
4449 MAX(gdk_pixbuf_get_width(buf) * SCALE(gtkconv->u.im->anim) / | |
4450 gdk_pixbuf_animation_get_width(gtkconv->u.im->anim), 1), | |
4451 MAX(gdk_pixbuf_get_height(buf) * SCALE(gtkconv->u.im->anim) / | |
4452 gdk_pixbuf_animation_get_height(gtkconv->u.im->anim), 1), | |
4453 GDK_INTERP_NEAREST); | |
4454 | |
4455 gdk_pixbuf_render_pixmap_and_mask(scale, &pm, &bm, 100); | |
4456 gdk_pixbuf_unref(scale); | |
4635 | 4457 gtk_image_set_from_pixmap(GTK_IMAGE(gtkconv->u.im->icon), pm, bm); |
4359 | 4458 gdk_pixmap_unref(pm); |
4459 gtk_widget_queue_draw(gtkconv->u.im->icon); | |
4460 | |
4461 if (bm) | |
4462 gdk_bitmap_unref(bm); | |
4463 | |
4464 delay = gdk_pixbuf_animation_iter_get_delay_time(gtkconv->u.im->iter) / 10; | |
4465 | |
4466 gtkconv->u.im->icon_timer = g_timeout_add(delay * 10, redraw_icon, conv); | |
4467 | |
4468 return FALSE; | |
4469 } | |
4470 | |
4471 static void | |
4472 start_anim(GtkObject *obj, struct gaim_conversation *conv) | |
4473 { | |
4474 struct gaim_gtk_conversation *gtkconv; | |
4475 int delay; | |
4476 | |
4398
a8249a5250b6
[gaim-migrate @ 4667]
Christian Hammond <chipx86@chipx86.com>
parents:
4397
diff
changeset
|
4477 if (!GAIM_IS_GTK_CONVERSATION(conv)) |
4359 | 4478 return; |
4479 | |
4480 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
4481 | |
4482 delay = gdk_pixbuf_animation_iter_get_delay_time(gtkconv->u.im->iter) / 10; | |
4483 | |
4484 if (gtkconv->u.im->anim) | |
4485 gtkconv->u.im->icon_timer = g_timeout_add(delay * 10, redraw_icon, | |
4486 conv); | |
4487 } | |
4488 | |
4489 static void | |
4490 stop_anim(GtkObject *obj, struct gaim_conversation *conv) | |
4491 { | |
4492 struct gaim_gtk_conversation *gtkconv; | |
4493 | |
4398
a8249a5250b6
[gaim-migrate @ 4667]
Christian Hammond <chipx86@chipx86.com>
parents:
4397
diff
changeset
|
4494 if (!GAIM_IS_GTK_CONVERSATION(conv)) |
4359 | 4495 return; |
4496 | |
4497 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
4498 | |
4499 if (gtkconv->u.im->icon_timer != 0) | |
4500 g_source_remove(gtkconv->u.im->icon_timer); | |
4501 | |
4502 gtkconv->u.im->icon_timer = 0; | |
4503 } | |
4504 | |
4505 static gboolean | |
4506 icon_menu(GtkObject *obj, GdkEventButton *e, struct gaim_conversation *conv) | |
4507 { | |
4508 struct gaim_gtk_conversation *gtkconv; | |
4509 static GtkWidget *menu = NULL; | |
4510 GtkWidget *button; | |
4511 | |
4512 if (e->button != 3 || e->type != GDK_BUTTON_PRESS) | |
4513 return FALSE; | |
4514 | |
4515 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
4516 | |
4517 /* | |
4518 * If a menu already exists, destroy it before creating a new one, | |
4519 * thus freeing-up the memory it occupied. | |
4520 */ | |
4521 if (menu != NULL) | |
4522 gtk_widget_destroy(menu); | |
4523 | |
4524 menu = gtk_menu_new(); | |
4525 | |
4526 if (gtkconv->u.im->icon_timer) { | |
4527 button = gtk_menu_item_new_with_label(_("Disable Animation")); | |
4528 g_signal_connect(GTK_OBJECT(button), "activate", | |
4529 G_CALLBACK(stop_anim), conv); | |
4530 gtk_menu_shell_append(GTK_MENU_SHELL(menu), button); | |
4531 gtk_widget_show(button); | |
4532 } | |
4533 else if (gtkconv->u.im->anim && | |
4534 !(gdk_pixbuf_animation_is_static_image(gtkconv->u.im->anim))) | |
4535 { | |
4536 button = gtk_menu_item_new_with_label(_("Enable Animation")); | |
4537 g_signal_connect(GTK_OBJECT(button), "activate", | |
4538 G_CALLBACK(start_anim), conv); | |
4539 gtk_menu_shell_append(GTK_MENU_SHELL(menu), button); | |
4540 gtk_widget_show(button); | |
4541 } | |
4542 | |
4543 button = gtk_menu_item_new_with_label(_("Hide Icon")); | |
4544 g_signal_connect_swapped(GTK_OBJECT(button), "activate", | |
4515
9b9737a00a96
[gaim-migrate @ 4793]
Christian Hammond <chipx86@chipx86.com>
parents:
4513
diff
changeset
|
4545 G_CALLBACK(remove_icon), gtkconv); |
4359 | 4546 gtk_menu_shell_append(GTK_MENU_SHELL(menu), button); |
4547 gtk_widget_show(button); | |
4548 | |
4549 button = gtk_menu_item_new_with_label(_("Save Icon As...")); | |
4550 g_signal_connect(GTK_OBJECT(button), "activate", | |
4551 G_CALLBACK(gaim_gtk_save_icon_dialog), conv); | |
4552 gtk_menu_shell_append(GTK_MENU_SHELL(menu), button); | |
4553 gtk_widget_show(button); | |
4554 | |
4555 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, e->button, e->time); | |
4556 | |
4557 return TRUE; | |
4558 } | |
4559 | |
4560 void | |
4561 gaim_gtkconv_update_buddy_icon(struct gaim_conversation *conv) | |
4562 { | |
4563 struct gaim_gtk_conversation *gtkconv; | |
4564 | |
4565 char filename[256]; | |
4566 FILE *file; | |
4567 GError *err = NULL; | |
4568 | |
4569 void *data; | |
4570 int len, delay; | |
4571 | |
4572 GdkPixbuf *buf; | |
4573 | |
4574 GtkWidget *event; | |
4575 GtkWidget *frame; | |
4576 GdkPixbuf *scale; | |
4577 GdkPixmap *pm; | |
4578 GdkBitmap *bm; | |
4579 int sf = 0; | |
4580 | |
4398
a8249a5250b6
[gaim-migrate @ 4667]
Christian Hammond <chipx86@chipx86.com>
parents:
4397
diff
changeset
|
4581 if (conv == NULL || !GAIM_IS_GTK_CONVERSATION(conv) || |
4359 | 4582 gaim_conversation_get_type(conv) != GAIM_CONV_IM) { |
4583 | |
4584 return; | |
4585 } | |
4586 | |
4587 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
4588 | |
4589 remove_icon(gtkconv); | |
4590 | |
4591 if (im_options & OPT_IM_HIDE_ICONS) | |
4592 return; | |
4593 | |
4594 if (gaim_conversation_get_gc(conv) == NULL) | |
4595 return; | |
4596 | |
4597 data = get_icon_data(gaim_conversation_get_gc(conv), | |
4598 normalize(gaim_conversation_get_name(conv)), | |
4599 &len); | |
4600 | |
4601 if (!data) | |
4602 return; | |
4603 | |
4604 /* this is such an evil hack, i don't know why i'm even considering it. | |
4605 * we'll do it differently when gdk-pixbuf-loader isn't leaky anymore. */ | |
4606 g_snprintf(filename, sizeof(filename), | |
4607 "%s" G_DIR_SEPARATOR_S "gaimicon-%s.%d", | |
4608 g_get_tmp_dir(), gaim_conversation_get_name(conv), getpid()); | |
4609 | |
4478
fa2d74e20a89
[gaim-migrate @ 4753]
Christian Hammond <chipx86@chipx86.com>
parents:
4476
diff
changeset
|
4610 if (!(file = fopen(filename, "wb"))) |
4359 | 4611 return; |
4612 | |
4613 fwrite(data, 1, len, file); | |
4614 fclose(file); | |
4615 | |
4616 gtkconv->u.im->anim = gdk_pixbuf_animation_new_from_file(filename, &err); | |
4617 | |
4618 if (err) { | |
4619 debug_printf("Buddy icon error: %s\n", err->message); | |
4620 g_error_free(err); | |
4621 } | |
4622 | |
4623 /* make sure we remove the file as soon as possible */ | |
4624 unlink(filename); | |
4625 | |
4626 if (!gtkconv->u.im->anim) | |
4627 return; | |
4628 | |
4629 if (gdk_pixbuf_animation_is_static_image(gtkconv->u.im->anim)) { | |
4630 gtkconv->u.im->iter = NULL; | |
4631 delay = 0; | |
4632 buf = gdk_pixbuf_animation_get_static_image(gtkconv->u.im->anim); | |
4633 } else { | |
4634 gtkconv->u.im->iter = | |
4635 gdk_pixbuf_animation_get_iter(gtkconv->u.im->anim, NULL); | |
4636 buf = gdk_pixbuf_animation_iter_get_pixbuf(gtkconv->u.im->iter); | |
4637 delay = gdk_pixbuf_animation_iter_get_delay_time(gtkconv->u.im->iter); | |
4638 delay = delay / 10; | |
4639 } | |
4640 | |
4641 sf = SCALE(gtkconv->u.im->anim); | |
4642 scale = gdk_pixbuf_scale_simple(buf, | |
4643 MAX(gdk_pixbuf_get_width(buf) * sf / | |
4644 gdk_pixbuf_animation_get_width(gtkconv->u.im->anim), 1), | |
4645 MAX(gdk_pixbuf_get_height(buf) * sf / | |
4646 gdk_pixbuf_animation_get_height(gtkconv->u.im->anim), 1), | |
4647 GDK_INTERP_NEAREST); | |
4648 | |
4649 if (delay) | |
4650 gtkconv->u.im->icon_timer = g_timeout_add(delay * 10, redraw_icon, | |
4651 conv); | |
4652 | |
4653 gdk_pixbuf_render_pixmap_and_mask(scale, &pm, &bm, 100); | |
4654 gdk_pixbuf_unref(scale); | |
4655 | |
4656 frame = gtk_frame_new(NULL); | |
4657 gtk_frame_set_shadow_type(GTK_FRAME(frame), | |
4658 (bm ? GTK_SHADOW_NONE : GTK_SHADOW_IN)); | |
4659 gtk_box_pack_start(GTK_BOX(gtkconv->bbox), frame, FALSE, FALSE, 5); | |
4660 gtk_box_reorder_child(GTK_BOX(gtkconv->bbox), frame, 0); | |
4661 gtk_widget_show(frame); | |
4662 | |
4663 event = gtk_event_box_new(); | |
4664 gtk_container_add(GTK_CONTAINER(frame), event); | |
4665 g_signal_connect(GTK_OBJECT(event), "button-press-event", | |
4666 G_CALLBACK(icon_menu), conv); | |
4667 gtk_widget_show(event); | |
4668 | |
4635 | 4669 gtkconv->u.im->icon = gtk_image_new_from_pixmap(pm, bm); |
4359 | 4670 gtk_widget_set_size_request(gtkconv->u.im->icon, sf, sf); |
4671 gtk_container_add(GTK_CONTAINER(event), gtkconv->u.im->icon); | |
4672 gtk_widget_show(gtkconv->u.im->icon); | |
4673 | |
4674 if(im_options & OPT_IM_NO_ANIMATION) | |
4675 stop_anim(NULL, conv); | |
4676 | |
4677 gdk_pixmap_unref(pm); | |
4678 | |
4679 if (bm) | |
4680 gdk_bitmap_unref(bm); | |
4681 } | |
4682 | |
4683 void | |
4684 gaim_gtkconv_hide_buddy_icons(void) | |
4685 { | |
4686 gaim_conversation_foreach(gaim_gtkconv_update_buddy_icon); | |
4687 } | |
4688 | |
4689 void | |
4690 gaim_gtkconv_set_anim(void) | |
4691 { | |
4692 GList *l; | |
4693 | |
4694 if (im_options & OPT_IM_HIDE_ICONS) | |
4695 return; | |
4696 | |
4697 if (im_options & OPT_IM_NO_ANIMATION) { | |
4698 for (l = gaim_get_ims(); l != NULL; l = l->next) | |
4699 stop_anim(NULL, (struct gaim_conversation *)l->data); | |
4700 } else { | |
4701 for (l = gaim_get_ims(); l != NULL; l = l->next) | |
4702 start_anim(NULL, (struct gaim_conversation *)l->data); | |
4703 } | |
4704 } | |
4705 | |
4706 void | |
4707 gaim_gtkconv_update_font_buttons(void) | |
4708 { | |
4709 GList *l; | |
4710 struct gaim_conversation *conv; | |
4711 struct gaim_gtk_conversation *gtkconv; | |
4712 | |
4713 for (l = gaim_get_ims(); l != NULL; l = l->next) { | |
4714 conv = (struct gaim_conversation *)l->data; | |
4715 | |
4398
a8249a5250b6
[gaim-migrate @ 4667]
Christian Hammond <chipx86@chipx86.com>
parents:
4397
diff
changeset
|
4716 if (!GAIM_IS_GTK_CONVERSATION(conv)) |
4359 | 4717 continue; |
4718 | |
4719 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
4720 | |
4721 if (gtkconv->toolbar.bold != NULL) | |
4722 gtk_widget_set_sensitive(gtkconv->toolbar.bold, | |
4723 (!(font_options & OPT_FONT_BOLD))); | |
4724 | |
4725 if (gtkconv->toolbar.italic != NULL) | |
4726 gtk_widget_set_sensitive(gtkconv->toolbar.italic, | |
4727 (!(font_options & OPT_FONT_ITALIC))); | |
4728 | |
4729 if (gtkconv->toolbar.underline != NULL) | |
4730 gtk_widget_set_sensitive(gtkconv->toolbar.underline, | |
4731 (!(font_options & OPT_FONT_UNDERLINE))); | |
4732 } | |
4733 } | |
4734 | |
4735 void | |
4421 | 4736 gaim_gtkconv_update_font_colors(struct gaim_conversation *conv) |
4737 { | |
4438
2054d8429925
[gaim-migrate @ 4713]
Christian Hammond <chipx86@chipx86.com>
parents:
4421
diff
changeset
|
4738 struct gaim_gtk_conversation *gtkconv; |
2054d8429925
[gaim-migrate @ 4713]
Christian Hammond <chipx86@chipx86.com>
parents:
4421
diff
changeset
|
4739 |
2054d8429925
[gaim-migrate @ 4713]
Christian Hammond <chipx86@chipx86.com>
parents:
4421
diff
changeset
|
4740 if (!GAIM_IS_GTK_CONVERSATION(conv)) |
2054d8429925
[gaim-migrate @ 4713]
Christian Hammond <chipx86@chipx86.com>
parents:
4421
diff
changeset
|
4741 return; |
2054d8429925
[gaim-migrate @ 4713]
Christian Hammond <chipx86@chipx86.com>
parents:
4421
diff
changeset
|
4742 |
2054d8429925
[gaim-migrate @ 4713]
Christian Hammond <chipx86@chipx86.com>
parents:
4421
diff
changeset
|
4743 gtkconv = GAIM_GTK_CONVERSATION(conv); |
4421 | 4744 |
4438
2054d8429925
[gaim-migrate @ 4713]
Christian Hammond <chipx86@chipx86.com>
parents:
4421
diff
changeset
|
4745 gtkconv->fg_color.red = fgcolor.red; |
2054d8429925
[gaim-migrate @ 4713]
Christian Hammond <chipx86@chipx86.com>
parents:
4421
diff
changeset
|
4746 gtkconv->fg_color.blue = fgcolor.blue; |
2054d8429925
[gaim-migrate @ 4713]
Christian Hammond <chipx86@chipx86.com>
parents:
4421
diff
changeset
|
4747 gtkconv->fg_color.green = fgcolor.green; |
2054d8429925
[gaim-migrate @ 4713]
Christian Hammond <chipx86@chipx86.com>
parents:
4421
diff
changeset
|
4748 |
2054d8429925
[gaim-migrate @ 4713]
Christian Hammond <chipx86@chipx86.com>
parents:
4421
diff
changeset
|
4749 gtkconv->bg_color.red = bgcolor.red; |
2054d8429925
[gaim-migrate @ 4713]
Christian Hammond <chipx86@chipx86.com>
parents:
4421
diff
changeset
|
4750 gtkconv->bg_color.blue = bgcolor.blue; |
2054d8429925
[gaim-migrate @ 4713]
Christian Hammond <chipx86@chipx86.com>
parents:
4421
diff
changeset
|
4751 gtkconv->bg_color.green = bgcolor.green; |
2054d8429925
[gaim-migrate @ 4713]
Christian Hammond <chipx86@chipx86.com>
parents:
4421
diff
changeset
|
4752 } |
2054d8429925
[gaim-migrate @ 4713]
Christian Hammond <chipx86@chipx86.com>
parents:
4421
diff
changeset
|
4753 |
2054d8429925
[gaim-migrate @ 4713]
Christian Hammond <chipx86@chipx86.com>
parents:
4421
diff
changeset
|
4754 void |
2054d8429925
[gaim-migrate @ 4713]
Christian Hammond <chipx86@chipx86.com>
parents:
4421
diff
changeset
|
4755 gaim_gtkconv_update_font_face(struct gaim_conversation *conv) |
2054d8429925
[gaim-migrate @ 4713]
Christian Hammond <chipx86@chipx86.com>
parents:
4421
diff
changeset
|
4756 { |
2054d8429925
[gaim-migrate @ 4713]
Christian Hammond <chipx86@chipx86.com>
parents:
4421
diff
changeset
|
4757 struct gaim_gtk_conversation *gtkconv; |
2054d8429925
[gaim-migrate @ 4713]
Christian Hammond <chipx86@chipx86.com>
parents:
4421
diff
changeset
|
4758 |
2054d8429925
[gaim-migrate @ 4713]
Christian Hammond <chipx86@chipx86.com>
parents:
4421
diff
changeset
|
4759 if (!GAIM_IS_GTK_CONVERSATION(conv)) |
2054d8429925
[gaim-migrate @ 4713]
Christian Hammond <chipx86@chipx86.com>
parents:
4421
diff
changeset
|
4760 return; |
2054d8429925
[gaim-migrate @ 4713]
Christian Hammond <chipx86@chipx86.com>
parents:
4421
diff
changeset
|
4761 |
2054d8429925
[gaim-migrate @ 4713]
Christian Hammond <chipx86@chipx86.com>
parents:
4421
diff
changeset
|
4762 gtkconv = GAIM_GTK_CONVERSATION(conv); |
2054d8429925
[gaim-migrate @ 4713]
Christian Hammond <chipx86@chipx86.com>
parents:
4421
diff
changeset
|
4763 |
2054d8429925
[gaim-migrate @ 4713]
Christian Hammond <chipx86@chipx86.com>
parents:
4421
diff
changeset
|
4764 strncpy(gtkconv->fontface, fontface, 128); |
4421 | 4765 } |
4766 | |
4767 void | |
4359 | 4768 gaim_gtkconv_update_tabs(void) |
4769 { | |
4770 GList *l; | |
4771 GtkPositionType pos; | |
4772 struct gaim_window *win; | |
4773 struct gaim_gtk_window *gtkwin; | |
4774 | |
4775 pos = ((im_options & OPT_IM_SIDE_TAB) | |
4776 ? ((im_options & OPT_IM_BR_TAB) ? GTK_POS_RIGHT : GTK_POS_LEFT) | |
4777 : ((im_options & OPT_IM_BR_TAB) ? GTK_POS_BOTTOM : GTK_POS_TOP)); | |
4778 | |
4779 for (l = gaim_get_windows(); l != NULL; l = l->next) { | |
4780 win = (struct gaim_window *)l->data; | |
4781 | |
4398
a8249a5250b6
[gaim-migrate @ 4667]
Christian Hammond <chipx86@chipx86.com>
parents:
4397
diff
changeset
|
4782 if (!GAIM_IS_GTK_WINDOW(win)) |
4359 | 4783 continue; |
4784 | |
4785 gtkwin = GAIM_GTK_WINDOW(win); | |
4786 | |
4787 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(gtkwin->notebook), pos); | |
4788 } | |
4789 } | |
4790 | |
4791 void | |
4792 gaim_gtkconv_update_chat_button_style() | |
4793 { | |
4794 GSList *l; | |
4795 struct gaim_connection *g; | |
4796 GtkWidget *parent; | |
4797 GaimConversationType type = GAIM_CONV_CHAT; | |
4798 | |
4799 for (l = connections; l != NULL; l = l->next) { | |
4800 GSList *bcs; | |
4801 struct gaim_conversation *conv; | |
4802 struct gaim_gtk_conversation *gtkconv; | |
4803 struct gaim_gtk_window *gtkwin; | |
4804 | |
4805 g = (struct gaim_connection *)l->data; | |
4806 | |
4807 for (bcs = g->buddy_chats; bcs != NULL; bcs = bcs->next) { | |
4808 conv = (struct gaim_conversation *)bcs->data; | |
4809 | |
4810 if (gaim_conversation_get_type(conv) != GAIM_CONV_CHAT) | |
4811 continue; | |
4812 | |
4398
a8249a5250b6
[gaim-migrate @ 4667]
Christian Hammond <chipx86@chipx86.com>
parents:
4397
diff
changeset
|
4813 if (!GAIM_IS_GTK_CONVERSATION(conv)) |
4359 | 4814 continue; |
4815 | |
4816 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
4817 gtkwin = GAIM_GTK_WINDOW(gaim_conversation_get_window(conv)); | |
4818 parent = gtk_widget_get_parent(gtkconv->send); | |
4819 | |
4820 gtkconv->send = | |
4821 gaim_gtk_change_text(_("Send"), | |
4822 gtkconv->send, GAIM_STOCK_SEND, type); | |
4823 gtkconv->u.chat->invite = | |
4824 gaim_gtk_change_text(_("Invite"), | |
4825 gtkconv->u.chat->invite, | |
4826 GAIM_STOCK_INVITE, type); | |
4827 | |
4828 gtk_box_pack_end(GTK_BOX(parent), gtkconv->send, FALSE, FALSE, | |
4829 type); | |
4830 gtk_box_pack_end(GTK_BOX(parent), gtkconv->u.chat->invite, | |
4831 FALSE, FALSE, 0); | |
4832 | |
4833 g_signal_connect(G_OBJECT(gtkconv->send), "clicked", | |
4834 G_CALLBACK(send_cb), conv); | |
4835 g_signal_connect(G_OBJECT(gtkconv->u.chat->invite), "clicked", | |
4836 G_CALLBACK(invite_cb), conv); | |
4837 | |
4838 gtk_button_set_relief(GTK_BUTTON(gtkconv->send), | |
4839 GTK_RELIEF_NONE); | |
4840 gtk_button_set_relief(GTK_BUTTON(gtkconv->u.chat->invite), | |
4841 GTK_RELIEF_NONE); | |
4842 | |
4843 gaim_gtkconv_update_buttons_by_protocol(conv); | |
4844 } | |
4845 } | |
4846 } | |
4847 | |
4848 void | |
4849 gaim_gtkconv_update_im_button_style() | |
4850 { | |
4851 GList *l; | |
4852 struct gaim_conversation *conv; | |
4853 struct gaim_gtk_conversation *gtkconv; | |
4854 | |
4855 for (l = gaim_get_ims(); l != NULL; l = l->next) { | |
4856 conv = (struct gaim_conversation *)l->data; | |
4857 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
4858 | |
4859 setup_im_buttons(conv, gtk_widget_get_parent(gtkconv->send)); | |
4860 } | |
4861 } | |
4862 | |
4863 void | |
4864 gaim_gtkconv_update_buttons_by_protocol(struct gaim_conversation *conv) | |
4865 { | |
4866 struct gaim_window *win; | |
4867 struct gaim_gtk_window *gtkwin = NULL; | |
4868 struct gaim_gtk_conversation *gtkconv; | |
4869 struct gaim_connection *gc; | |
4870 | |
4398
a8249a5250b6
[gaim-migrate @ 4667]
Christian Hammond <chipx86@chipx86.com>
parents:
4397
diff
changeset
|
4871 if (!GAIM_IS_GTK_CONVERSATION(conv)) |
4359 | 4872 return; |
4873 | |
4874 gc = gaim_conversation_get_gc(conv); | |
4875 win = gaim_conversation_get_window(conv); | |
4876 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
4877 | |
4878 if (win != NULL) | |
4879 gtkwin = GAIM_GTK_WINDOW(win); | |
4880 | |
4881 if (gc == NULL) { | |
4882 gtk_widget_set_sensitive(gtkconv->send, FALSE); | |
4883 | |
4365
6e96ced6fb78
[gaim-migrate @ 4631]
Christian Hammond <chipx86@chipx86.com>
parents:
4364
diff
changeset
|
4884 if (win != NULL && gaim_window_get_active_conversation(win) == conv) { |
4359 | 4885 gtk_widget_set_sensitive(gtkwin->menu.insert_link, FALSE); |
4886 } | |
4887 } | |
4364
fa56829b9587
[gaim-migrate @ 4630]
Christian Hammond <chipx86@chipx86.com>
parents:
4363
diff
changeset
|
4888 else { |
4674 | 4889 gtk_widget_set_sensitive(gtkconv->send, TRUE); |
4365
6e96ced6fb78
[gaim-migrate @ 4631]
Christian Hammond <chipx86@chipx86.com>
parents:
4364
diff
changeset
|
4890 if (win != NULL) { |
6e96ced6fb78
[gaim-migrate @ 4631]
Christian Hammond <chipx86@chipx86.com>
parents:
4364
diff
changeset
|
4891 gtk_widget_set_sensitive(gtkwin->menu.insert_link, TRUE); |
6e96ced6fb78
[gaim-migrate @ 4631]
Christian Hammond <chipx86@chipx86.com>
parents:
4364
diff
changeset
|
4892 } |
4364
fa56829b9587
[gaim-migrate @ 4630]
Christian Hammond <chipx86@chipx86.com>
parents:
4363
diff
changeset
|
4893 } |
4359 | 4894 |
4895 if (gaim_conversation_get_type(conv) == GAIM_CONV_IM) { | |
4896 if (gc == NULL) { | |
4897 gtk_widget_set_sensitive(gtkconv->info, FALSE); | |
4898 gtk_widget_set_sensitive(gtkconv->u.im->warn, FALSE); | |
4899 gtk_widget_set_sensitive(gtkconv->u.im->block, FALSE); | |
4900 gtk_widget_set_sensitive(gtkconv->u.im->add, FALSE); | |
4901 | |
4902 if (win != NULL && | |
4903 gaim_window_get_active_conversation(win) == conv) { | |
4904 | |
4905 gtk_widget_set_sensitive(gtkwin->menu.insert_image, FALSE); | |
4906 } | |
4907 | |
4908 return; | |
4909 } | |
4910 | |
4911 gtk_widget_set_sensitive(gtkconv->info, | |
4912 (gc->prpl->get_info != NULL)); | |
4913 | |
4914 gtk_widget_set_sensitive(gtkconv->toolbar.image, | |
4915 (gc->prpl->options & OPT_PROTO_IM_IMAGE)); | |
4916 | |
4917 if (win != NULL && gaim_window_get_active_conversation(win) == conv) { | |
4918 gtk_widget_set_sensitive(gtkwin->menu.insert_image, | |
4919 (gc->prpl->options & OPT_PROTO_IM_IMAGE)); | |
4920 } | |
4921 | |
4922 gtk_widget_set_sensitive(gtkconv->u.im->warn, | |
4923 (gc->prpl->warn != NULL)); | |
4924 | |
4925 gtk_widget_set_sensitive(gtkconv->u.im->block, | |
4926 (gc->prpl->add_permit != NULL)); | |
4927 | |
4928 update_convo_add_button(conv); | |
4929 } | |
4930 else if (gaim_conversation_get_type(conv) == GAIM_CONV_CHAT) { | |
4931 if (gc == NULL) { | |
4932 gtk_widget_set_sensitive(gtkconv->u.chat->whisper, FALSE); | |
4933 gtk_widget_set_sensitive(gtkconv->u.chat->invite, FALSE); | |
4934 | |
4935 return; | |
4936 } | |
4937 | |
4938 gtk_widget_set_sensitive(gtkconv->send, (gc->prpl->chat_send != NULL)); | |
4939 | |
4940 gtk_widget_set_sensitive(gtkconv->toolbar.image, FALSE); | |
4941 /* gtk_widget_set_sensitive(gtkwin->menu.insert_image, FALSE); */ | |
4942 | |
4943 gtk_widget_set_sensitive(gtkconv->u.chat->whisper, | |
4944 (gc->prpl->chat_whisper != NULL)); | |
4945 | |
4946 gtk_widget_set_sensitive(gtkconv->u.chat->invite, | |
4947 (gc->prpl->chat_invite != NULL)); | |
4948 } | |
4949 } | |
4950 | |
4951 struct gaim_window * | |
4952 gaim_gtkwin_get_at_xy(int x, int y) | |
4953 { | |
4954 struct gaim_window *win = NULL; | |
4955 struct gaim_gtk_window *gtkwin; | |
4956 GdkWindow *gdkwin; | |
4957 GList *l; | |
4958 | |
4959 gdkwin = gdk_window_at_pointer(&x, &y); | |
4960 | |
4961 if (gdkwin) | |
4962 gdkwin = gdk_window_get_toplevel(gdkwin); | |
4963 | |
4964 for (l = gaim_get_windows(); l != NULL; l = l->next) { | |
4965 win = (struct gaim_window *)l->data; | |
4966 | |
4398
a8249a5250b6
[gaim-migrate @ 4667]
Christian Hammond <chipx86@chipx86.com>
parents:
4397
diff
changeset
|
4967 if (!GAIM_IS_GTK_WINDOW(win)) |
4359 | 4968 continue; |
4969 | |
4970 gtkwin = GAIM_GTK_WINDOW(win); | |
4971 | |
4972 if (gdkwin == gtkwin->window->window) | |
4973 return win; | |
4974 } | |
4975 | |
4976 return NULL; | |
4977 } | |
4978 | |
4979 int | |
4980 gaim_gtkconv_get_tab_at_xy(struct gaim_window *win, int x, int y) | |
4981 { | |
4982 struct gaim_gtk_window *gtkwin; | |
4983 GList *l; | |
4984 gint nb_x, nb_y, x_rel, y_rel; | |
4985 GtkNotebook *notebook; | |
4986 GtkWidget *tab; | |
4987 gint i, page_num = 0; | |
4988 gboolean first_visible = TRUE; | |
4989 | |
4398
a8249a5250b6
[gaim-migrate @ 4667]
Christian Hammond <chipx86@chipx86.com>
parents:
4397
diff
changeset
|
4990 if (!GAIM_IS_GTK_WINDOW(win)) |
4359 | 4991 return -1; |
4992 | |
4993 gtkwin = GAIM_GTK_WINDOW(win); | |
4994 notebook = GTK_NOTEBOOK(gtkwin->notebook); | |
4995 | |
4996 gdk_window_get_origin(gtkwin->notebook->window, &nb_x, &nb_y); | |
4997 x_rel = x - nb_x; | |
4998 y_rel = y - nb_y; | |
4999 | |
5000 for (l = gaim_window_get_conversations(win), i = 0; | |
5001 l != NULL; | |
5002 l = l->next, i++) { | |
5003 | |
5004 struct gaim_conversation *conv = l->data; | |
5005 tab = GAIM_GTK_CONVERSATION(conv)->tab_label; | |
5006 | |
5007 if (!GTK_WIDGET_MAPPED(tab)) | |
5008 continue; | |
5009 | |
5010 if (first_visible) { | |
5011 first_visible = FALSE; | |
5012 | |
5013 if (x_rel < tab->allocation.x) x_rel = tab->allocation.x; | |
5014 if (y_rel < tab->allocation.y) y_rel = tab->allocation.y; | |
5015 } | |
5016 | |
5017 if (gtk_notebook_get_tab_pos(notebook) == GTK_POS_TOP || | |
5018 gtk_notebook_get_tab_pos(notebook) == GTK_POS_BOTTOM) { | |
5019 | |
5020 if (tab->allocation.x <= x_rel) { | |
5021 if (tab->allocation.x + tab->allocation.width <= x_rel) | |
5022 page_num = i + 1; | |
5023 else | |
5024 page_num = i; | |
5025 } | |
5026 else | |
5027 break; | |
5028 } | |
5029 else { | |
5030 if (tab->allocation.y <= y_rel) { | |
5031 if (tab->allocation.y + tab->allocation.height <= y_rel) | |
5032 page_num = i + 1; | |
5033 else | |
5034 page_num = i; | |
5035 } | |
5036 else | |
5037 break; | |
5038 } | |
5039 } | |
5040 | |
5041 if (i == gaim_window_get_conversation_count(win) + 1) | |
5042 return -1; | |
5043 | |
5044 return page_num; | |
5045 } | |
5046 | |
5047 int | |
5048 gaim_gtkconv_get_dest_tab_at_xy(struct gaim_window *win, int x, int y) | |
5049 { | |
5050 struct gaim_gtk_window *gtkwin; | |
5051 GList *l; | |
5052 gint nb_x, nb_y, x_rel, y_rel; | |
5053 GtkNotebook *notebook; | |
5054 GtkWidget *tab; | |
5055 gint i, page_num = 0; | |
5056 | |
4398
a8249a5250b6
[gaim-migrate @ 4667]
Christian Hammond <chipx86@chipx86.com>
parents:
4397
diff
changeset
|
5057 if (!GAIM_IS_GTK_WINDOW(win)) |
4359 | 5058 return -1; |
5059 | |
5060 gtkwin = GAIM_GTK_WINDOW(win); | |
5061 notebook = GTK_NOTEBOOK(gtkwin->notebook); | |
5062 | |
5063 gdk_window_get_origin(gtkwin->notebook->window, &nb_x, &nb_y); | |
5064 x_rel = x - nb_x; | |
5065 y_rel = y - nb_y; | |
5066 | |
5067 for (l = gaim_window_get_conversations(win), i = 0; | |
5068 l != NULL; | |
5069 l = l->next, i++) { | |
5070 | |
5071 struct gaim_conversation *conv = l->data; | |
5072 tab = GAIM_GTK_CONVERSATION(conv)->tab_label; | |
5073 | |
5074 if (!GTK_WIDGET_MAPPED(tab)) | |
5075 continue; | |
5076 | |
5077 if (gtk_notebook_get_tab_pos(notebook) == GTK_POS_TOP || | |
5078 gtk_notebook_get_tab_pos(notebook) == GTK_POS_BOTTOM) { | |
5079 | |
5080 if (tab->allocation.x <= x_rel) { | |
5081 if (tab->allocation.x + (tab->allocation.width / 2) <= x_rel) | |
5082 page_num = i + 1; | |
5083 else | |
5084 page_num = i; | |
5085 } | |
5086 else | |
5087 break; | |
5088 } | |
5089 else { | |
5090 if (tab->allocation.y <= y_rel) { | |
5091 if (tab->allocation.y + (tab->allocation.height / 2) <= y_rel) | |
5092 page_num = i + 1; | |
5093 else | |
5094 page_num = i; | |
5095 } | |
5096 else | |
5097 break; | |
5098 } | |
5099 } | |
5100 | |
5101 if (i == gaim_window_get_conversation_count(win) + 1) | |
5102 return -1; | |
5103 | |
5104 return page_num; | |
5105 } |