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