4 * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net>
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.
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.
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
33 #include "gtkimhtml.h"
34 #include "pixmaps/join.xpm"
36 GtkWidget
*imaway
= NULL
;
38 GtkWidget
*awaymenu
= NULL
;
39 GtkWidget
*clistqueue
= NULL
;
40 GtkWidget
*clistqueuesw
;
42 struct away_message
*awaymessage
= NULL
;
43 struct away_message
*default_away
;
46 static void destroy_im_away()
49 gtk_widget_destroy(imaway
);
56 void purge_away_queue(GSList
*queue
)
58 struct conversation
*cnv
;
60 gtk_clist_freeze(GTK_CLIST(clistqueue
));
61 gtk_clist_clear(GTK_CLIST(clistqueue
));
64 struct queued_message
*qm
= queue
->data
;
66 cnv
= find_conversation(qm
->name
);
68 cnv
= new_conversation(qm
->name
);
69 if (g_slist_index(connections
, qm
->gc
) >= 0)
70 set_convo_gc(cnv
, qm
->gc
);
71 write_to_conv(cnv
, qm
->message
, qm
->flags
, NULL
, qm
->tm
, qm
->len
);
73 queue
= g_slist_remove(queue
, qm
);
79 gtk_clist_thaw(GTK_CLIST(clistqueue
));
82 void dequeue_by_buddy(GtkWidget
*clist
, gint row
, gint column
, GdkEventButton
*event
, gpointer data
) {
86 struct conversation
*cnv
;
88 if(!(event
->type
== GDK_2BUTTON_PRESS
&& event
->button
== 1))
89 return; /* Double clicking on the clist will unqueue that users messages. */
91 gtk_clist_get_text(GTK_CLIST(clist
), row
, 0, &temp
);
92 name
= g_strdup(temp
);
96 debug_printf("Unqueueing messages from %s.\n", name
);
97 templist
= message_queue
;
99 struct queued_message
*qm
= templist
->data
;
100 if (templist
->data
) {
101 if (!g_strcasecmp(qm
->name
, name
)) {
102 cnv
= find_conversation(name
);
104 cnv
= new_conversation(qm
->name
);
105 if (g_slist_index(connections
, qm
->gc
) >= 0)
106 set_convo_gc(cnv
, qm
->gc
);
108 write_to_conv(cnv
, qm
->message
, qm
->flags
, NULL
, qm
->tm
, qm
->len
);
111 templist
= message_queue
= g_slist_remove(message_queue
, qm
);
114 templist
= templist
->next
;
119 gtk_clist_remove(GTK_CLIST(clist
), row
);
126 void toggle_away_queue()
128 if (!clistqueue
|| !clistqueuesw
)
131 if (away_options
& OPT_AWAY_QUEUE
) {
132 gtk_widget_show(clistqueue
);
133 gtk_widget_show(clistqueuesw
);
135 gtk_widget_hide(clistqueue
);
136 gtk_widget_hide(clistqueuesw
);
137 purge_away_queue(message_queue
);
141 void do_im_back(GtkWidget
*w
, GtkWidget
*x
)
144 GtkWidget
*tmp
= imaway
;
146 purge_away_queue(message_queue
);
149 gtk_widget_destroy(tmp
);
154 while (away_time_queue
) {
155 struct queued_away_response
*qar
= away_time_queue
->data
;
156 away_time_queue
= g_slist_remove(away_time_queue
, qar
);
163 serv_set_away_all(NULL
);
167 void do_away_message(GtkWidget
*w
, struct away_message
*a
)
184 gtk_window_set_wmclass(GTK_WINDOW(imaway
), "imaway", "Gaim");
186 gtk_window_set_title(GTK_WINDOW(imaway
), a
->name
);
188 gtk_window_set_title(GTK_WINDOW(imaway
), _("Gaim - Away!"));
189 gtk_signal_connect(GTK_OBJECT(imaway
), "destroy", GTK_SIGNAL_FUNC(do_im_back
), imaway
);
190 gtk_widget_realize(imaway
);
192 vbox
= gtk_vbox_new(FALSE
, 5);
193 gtk_container_add(GTK_CONTAINER(imaway
), vbox
);
194 gtk_container_set_border_width(GTK_CONTAINER(vbox
), 5);
195 gtk_widget_show(vbox
);
197 sw
= gtk_scrolled_window_new(NULL
, NULL
);
198 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw
), GTK_POLICY_NEVER
,
200 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw
), GTK_SHADOW_IN
);
201 gtk_widget_set_usize(sw
, 245, 120);
202 gtk_box_pack_start(GTK_BOX(vbox
), sw
, TRUE
, TRUE
, 0);
205 awaytext
= gtk_imhtml_new(NULL
, NULL
);
206 gtk_container_add(GTK_CONTAINER(sw
), awaytext
);
207 gaim_setup_imhtml(awaytext
);
208 gtk_widget_show(awaytext
);
209 buf
= stylize(a
->message
, BUF_LONG
);
210 gtk_imhtml_append_text(GTK_IMHTML(awaytext
), buf
, -1, GTK_IMHTML_NO_TITLE
|
211 GTK_IMHTML_NO_COMMENTS
| GTK_IMHTML_NO_SCROLL
);
213 gtk_imhtml_append_text(GTK_IMHTML(awaytext
), "<BR>", -1, GTK_IMHTML_NO_TITLE
|
214 GTK_IMHTML_NO_COMMENTS
| GTK_IMHTML_NO_SCROLL
);
216 clistqueuesw
= gtk_scrolled_window_new(NULL
, NULL
);
217 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(clistqueuesw
), GTK_POLICY_NEVER
,
218 GTK_POLICY_AUTOMATIC
);
219 gtk_box_pack_start(GTK_BOX(vbox
), clistqueuesw
, TRUE
, TRUE
, 0);
221 clistqueue
= gtk_clist_new(2);
222 gtk_clist_set_column_width(GTK_CLIST(clistqueue
), 0, 100);
223 gtk_widget_set_usize(GTK_WIDGET(clistqueue
), -1, 50);
224 gtk_container_add(GTK_CONTAINER(clistqueuesw
), clistqueue
);
225 gtk_signal_connect(GTK_OBJECT(clistqueue
), "select_row", GTK_SIGNAL_FUNC(dequeue_by_buddy
), NULL
);
229 if (away_options
& OPT_AWAY_QUEUE
) {
230 gtk_widget_show(clistqueuesw
);
231 gtk_widget_show(clistqueue
);
234 back
= picture_button(imaway
, _("I'm Back!"), join_xpm
);
235 gtk_box_pack_start(GTK_BOX(vbox
), back
, FALSE
, FALSE
, 0);
236 gtk_signal_connect(GTK_OBJECT(back
), "clicked", GTK_SIGNAL_FUNC(do_im_back
), imaway
);
237 gtk_window_set_focus(GTK_WINDOW(imaway
), back
);
242 /* Register window widget with wgaim systray module */
243 wgaim_created_backwin(imaway
);
248 do_away_message(w
, a
);
252 /* New away message... Clear out the old sent_aways */
253 while (away_time_queue
) {
254 struct queued_away_response
*qar
= away_time_queue
->data
;
255 away_time_queue
= g_slist_remove(away_time_queue
, qar
);
259 gtk_widget_show(imaway
);
260 buf2
= g_malloc(strlen(awaymessage
->message
) * 4 + 1);
261 strncpy_withhtml(buf2
, awaymessage
->message
, strlen(awaymessage
->message
) * 4 + 1);
262 serv_set_away_all(buf2
);
266 void rem_away_mess(GtkWidget
*w
, struct away_message
*a
)
269 default_index
= g_slist_index(away_messages
, default_away
);
270 if (default_index
== -1) {
271 if (away_messages
!= NULL
)
272 default_away
= away_messages
->data
;
276 away_messages
= g_slist_remove(away_messages
, a
);
282 static void set_gc_away(GtkObject
*obj
, struct gaim_connection
*gc
)
284 struct away_message
*awy
= gtk_object_get_user_data(obj
);
287 serv_set_away(gc
, GAIM_AWAY_CUSTOM
, awy
->message
);
289 serv_set_away(gc
, GAIM_AWAY_CUSTOM
, NULL
);
292 static void set_gc_state(GtkObject
*obj
, struct gaim_connection
*gc
)
294 char *awy
= gtk_object_get_user_data(obj
);
296 serv_set_away(gc
, awy
, NULL
);
303 GtkWidget
*submenu
, *submenu2
;
308 GtkWidget
*list_item
;
309 GSList
*awy
= away_messages
;
310 struct away_message
*a
;
311 GSList
*con
= connections
;
312 struct gaim_connection
*gc
= NULL
;
315 if (prefs_away_list
!= NULL
) {
317 gtk_list_clear_items(GTK_LIST(prefs_away_list
), 0, -1);
319 a
= (struct away_message
*)awy
->data
;
320 list_item
= gtk_list_item_new();
321 gtk_container_add(GTK_CONTAINER(prefs_away_list
), list_item
);
322 gtk_signal_connect(GTK_OBJECT(list_item
), "select",
323 GTK_SIGNAL_FUNC(away_list_clicked
), a
);
324 gtk_object_set_user_data(GTK_OBJECT(list_item
), a
);
325 gtk_widget_show(list_item
);
327 hbox
= gtk_hbox_new(FALSE
, 5);
328 gtk_container_add(GTK_CONTAINER(list_item
), hbox
);
329 gtk_widget_show(hbox
);
331 label
= gtk_label_new(a
->name
);
332 gtk_box_pack_start(GTK_BOX(hbox
), label
, FALSE
, FALSE
, 5);
333 gtk_widget_show(label
);
335 awy
= g_slist_next(awy
);
337 if (away_messages
!= NULL
)
338 gtk_list_select_item(GTK_LIST(prefs_away_list
), 0);
342 l
= gtk_container_children(GTK_CONTAINER(awaymenu
));
345 gtk_container_remove(GTK_CONTAINER(awaymenu
), GTK_WIDGET(l
->data
));
350 remmenu
= gtk_menu_new();
352 menuitem
= gtk_menu_item_new_with_label(_("New Away Message"));
353 gtk_menu_append(GTK_MENU(awaymenu
), menuitem
);
354 gtk_widget_show(menuitem
);
355 gtk_signal_connect(GTK_OBJECT(menuitem
), "activate", GTK_SIGNAL_FUNC(create_away_mess
),
360 a
= (struct away_message
*)awy
->data
;
362 remitem
= gtk_menu_item_new_with_label(a
->name
);
363 gtk_menu_append(GTK_MENU(remmenu
), remitem
);
364 gtk_widget_show(remitem
);
365 gtk_signal_connect(GTK_OBJECT(remitem
), "activate",
366 GTK_SIGNAL_FUNC(rem_away_mess
), a
);
368 awy
= g_slist_next(awy
);
372 menuitem
= gtk_menu_item_new_with_label(_("Remove Away Message"));
373 gtk_menu_append(GTK_MENU(awaymenu
), menuitem
);
374 gtk_widget_show(menuitem
);
375 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem
), remmenu
);
376 gtk_widget_show(remmenu
);
378 sep
= gtk_hseparator_new();
379 menuitem
= gtk_menu_item_new();
380 gtk_menu_append(GTK_MENU(awaymenu
), menuitem
);
381 gtk_container_add(GTK_CONTAINER(menuitem
), sep
);
382 gtk_widget_set_sensitive(menuitem
, FALSE
);
383 gtk_widget_show(menuitem
);
384 gtk_widget_show(sep
);
388 if (gc
->prpl
->away_states
&&gc
->prpl
->set_away
)
390 con
= g_slist_next(con
);
395 } else if (count
== 1) {
399 if (gc
->prpl
->away_states
&&gc
->prpl
->set_away
)
401 con
= g_slist_next(con
);
404 tmp
= msgs
= gc
->prpl
->away_states(gc
);
406 if ((g_list_length(msgs
) == 1) && !strcmp(msgs
->data
, GAIM_AWAY_CUSTOM
)) {
410 a
= (struct away_message
*)awy
->data
;
412 menuitem
= gtk_menu_item_new_with_label(a
->name
);
413 gtk_object_set_user_data(GTK_OBJECT(menuitem
), a
);
414 gtk_menu_append(GTK_MENU(awaymenu
), menuitem
);
415 gtk_widget_show(menuitem
);
416 gtk_signal_connect(GTK_OBJECT(menuitem
), "activate",
417 GTK_SIGNAL_FUNC(do_away_message
), a
);
419 awy
= g_slist_next(awy
);
425 menuitem
= gtk_menu_item_new_with_label(msgs
->data
);
426 gtk_object_set_user_data(GTK_OBJECT(menuitem
), msgs
->data
);
427 gtk_menu_append(GTK_MENU(awaymenu
), menuitem
);
428 gtk_widget_show(menuitem
);
430 if (strcmp(msgs
->data
, GAIM_AWAY_CUSTOM
)) {
431 gtk_signal_connect(GTK_OBJECT(menuitem
), "activate",
432 GTK_SIGNAL_FUNC(set_gc_state
), gc
);
434 submenu
= gtk_menu_new();
435 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem
),
437 gtk_widget_show(submenu
);
440 a
= (struct away_message
*)awy
->data
;
442 menuitem
= gtk_menu_item_new_with_label(a
->name
);
443 gtk_object_set_user_data(GTK_OBJECT(menuitem
),
445 gtk_menu_append(GTK_MENU(submenu
), menuitem
);
446 gtk_widget_show(menuitem
);
447 gtk_signal_connect(GTK_OBJECT(menuitem
),
450 (do_away_message
), a
);
452 awy
= g_slist_next(awy
);
455 msgs
= g_list_next(msgs
);
465 if (!gc
->prpl
->away_states
||!gc
->prpl
->set_away
) {
470 g_snprintf(buf
, sizeof(buf
), "%s (%s)",
471 gc
->username
, gc
->prpl
->name
);
472 menuitem
= gtk_menu_item_new_with_label(buf
);
473 gtk_menu_append(GTK_MENU(awaymenu
), menuitem
);
474 gtk_widget_show(menuitem
);
476 submenu
= gtk_menu_new();
477 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem
), submenu
);
478 gtk_widget_show(submenu
);
480 tmp
= msgs
= gc
->prpl
->away_states(gc
);
482 if ((g_list_length(msgs
) == 1) &&
483 (!strcmp(msgs
->data
, GAIM_AWAY_CUSTOM
))) {
484 menuitem
= gtk_menu_item_new_with_label(_("Back"));
485 gtk_menu_append(GTK_MENU(submenu
), menuitem
);
486 gtk_widget_show(menuitem
);
487 gtk_signal_connect(GTK_OBJECT(menuitem
), "activate",
488 GTK_SIGNAL_FUNC(set_gc_away
), gc
);
490 sep
= gtk_hseparator_new();
491 menuitem
= gtk_menu_item_new();
492 gtk_menu_append(GTK_MENU(submenu
), menuitem
);
493 gtk_container_add(GTK_CONTAINER(menuitem
), sep
);
494 gtk_widget_set_sensitive(menuitem
, FALSE
);
495 gtk_widget_show(menuitem
);
496 gtk_widget_show(sep
);
501 a
= (struct away_message
*)awy
->data
;
503 menuitem
= gtk_menu_item_new_with_label(a
->name
);
504 gtk_object_set_user_data(GTK_OBJECT(menuitem
), a
);
505 gtk_menu_append(GTK_MENU(submenu
), menuitem
);
506 gtk_widget_show(menuitem
);
507 gtk_signal_connect(GTK_OBJECT(menuitem
), "activate",
508 GTK_SIGNAL_FUNC(set_gc_away
), gc
);
510 awy
= g_slist_next(awy
);
516 menuitem
= gtk_menu_item_new_with_label(msgs
->data
);
517 gtk_object_set_user_data(GTK_OBJECT(menuitem
),
519 gtk_menu_append(GTK_MENU(submenu
), menuitem
);
520 gtk_widget_show(menuitem
);
522 if (strcmp(msgs
->data
, GAIM_AWAY_CUSTOM
)) {
523 gtk_signal_connect(GTK_OBJECT(menuitem
),
525 GTK_SIGNAL_FUNC(set_gc_state
),
528 submenu2
= gtk_menu_new();
529 gtk_menu_item_set_submenu(GTK_MENU_ITEM
530 (menuitem
), submenu2
);
531 gtk_widget_show(submenu2
);
534 a
= (struct away_message
*)awy
->data
;
537 gtk_menu_item_new_with_label(a
->
539 gtk_object_set_user_data(GTK_OBJECT
541 gtk_menu_append(GTK_MENU(submenu2
),
543 gtk_widget_show(menuitem
);
544 gtk_signal_connect(GTK_OBJECT(menuitem
),
549 awy
= g_slist_next(awy
);
552 msgs
= g_list_next(msgs
);
557 con
= g_slist_next(con
);
560 menuitem
= gtk_menu_item_new_with_label(_("Set All Away"));
561 gtk_menu_append(GTK_MENU(awaymenu
), menuitem
);
562 gtk_widget_show(menuitem
);
564 submenu
= gtk_menu_new();
565 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem
), submenu
);
566 gtk_widget_show(submenu
);
571 a
= (struct away_message
*)awy
->data
;
573 menuitem
= gtk_menu_item_new_with_label(a
->name
);
574 gtk_object_set_user_data(GTK_OBJECT(menuitem
), a
);
575 gtk_menu_append(GTK_MENU(submenu
), menuitem
);
576 gtk_widget_show(menuitem
);
577 gtk_signal_connect(GTK_OBJECT(menuitem
), "activate",
578 GTK_SIGNAL_FUNC(do_away_message
), a
);
580 awy
= g_slist_next(awy
);
584 if (prefs_away_menu
) {
585 l
= gtk_container_children(GTK_CONTAINER(prefs_away_menu
));
587 gtk_widget_destroy(GTK_WIDGET(l
->data
));
590 gtk_widget_hide(GTK_WIDGET(prefs_away_menu
));
591 default_away_menu_init(GTK_WIDGET(prefs_away_menu
));
592 gtk_widget_show(prefs_away_menu
);