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
27 #include <applet-widget.h>
29 #endif /* USE_APPLET */
38 #include "gtkimhtml.h"
39 #include "pixmaps/join.xpm"
41 GtkWidget
*imaway
= NULL
;
43 GtkWidget
*awaymenu
= NULL
;
44 GtkWidget
*clistqueue
= NULL
;
45 GtkWidget
*clistqueuesw
;
47 struct away_message
*awaymessage
= NULL
;
48 struct away_message
*default_away
;
51 static void destroy_im_away()
54 gtk_widget_destroy(imaway
);
61 void purge_away_queue()
63 struct conversation
*cnv
;
65 gtk_clist_freeze(GTK_CLIST(clistqueue
));
66 gtk_clist_clear(GTK_CLIST(clistqueue
));
68 while (message_queue
) {
69 struct queued_message
*qm
= message_queue
->data
;
71 cnv
= find_conversation(qm
->name
);
73 cnv
= new_conversation(qm
->name
);
74 if (g_slist_index(connections
, qm
->gc
) >= 0)
75 set_convo_gc(cnv
, qm
->gc
);
77 write_to_conv(cnv
, qm
->message
, qm
->flags
, NULL
, qm
->tm
, qm
->len
);
79 message_queue
= g_slist_remove(message_queue
, qm
);
85 gtk_clist_thaw(GTK_CLIST(clistqueue
));
88 void dequeue_by_buddy(GtkWidget
*clist
, gint row
, gint column
, GdkEventButton
*event
, gpointer data
) {
92 struct conversation
*cnv
;
94 if(!(event
->type
== GDK_2BUTTON_PRESS
&& event
->button
== 1))
95 return; /* Double clicking on the clist will unqueue that users messages. */
97 gtk_clist_get_text(GTK_CLIST(clist
), row
, 0, &temp
);
98 name
= g_strdup(temp
);
102 debug_printf("Unqueueing messages from %s.\n", name
);
103 templist
= message_queue
;
105 struct queued_message
*qm
= templist
->data
;
106 if (templist
->data
) {
107 if (!g_strcasecmp(qm
->name
, name
)) {
108 cnv
= find_conversation(name
);
110 cnv
= new_conversation(qm
->name
);
111 if (g_slist_index(connections
, qm
->gc
) >= 0)
112 set_convo_gc(cnv
, qm
->gc
);
114 write_to_conv(cnv
, qm
->message
, qm
->flags
, NULL
, qm
->tm
, qm
->len
);
117 templist
= message_queue
= g_slist_remove(message_queue
, qm
);
120 templist
= templist
->next
;
125 gtk_clist_remove(GTK_CLIST(clist
), row
);
128 set_user_state(away
);
136 void toggle_away_queue()
138 if (!clistqueue
|| !clistqueuesw
)
141 if (away_options
& OPT_AWAY_QUEUE
) {
142 gtk_widget_show(clistqueue
);
143 gtk_widget_show(clistqueuesw
);
145 gtk_widget_hide(clistqueue
);
146 gtk_widget_hide(clistqueuesw
);
151 void do_im_back(GtkWidget
*w
, GtkWidget
*x
)
154 GtkWidget
*tmp
= imaway
;
159 gtk_widget_destroy(tmp
);
164 while (away_time_queue
) {
165 struct queued_away_response
*qar
= away_time_queue
->data
;
166 away_time_queue
= g_slist_remove(away_time_queue
, qar
);
170 serv_set_away_all(NULL
);
175 applet_widget_unregister_callback(APPLET_WIDGET(applet
), "away");
176 set_user_state(online
);
177 insert_applet_away();
178 #endif /* USE_APPLET */
182 void do_away_message(GtkWidget
*w
, struct away_message
*a
)
199 gtk_window_set_wmclass(GTK_WINDOW(imaway
), "imaway", "Gaim");
201 gtk_window_set_title(GTK_WINDOW(imaway
), a
->name
);
203 gtk_window_set_title(GTK_WINDOW(imaway
), _("Gaim - Away!"));
204 gtk_signal_connect(GTK_OBJECT(imaway
), "destroy", GTK_SIGNAL_FUNC(do_im_back
), imaway
);
205 gtk_widget_realize(imaway
);
206 aol_icon(imaway
->window
);
208 vbox
= gtk_vbox_new(FALSE
, 5);
209 gtk_container_add(GTK_CONTAINER(imaway
), vbox
);
210 gtk_container_set_border_width(GTK_CONTAINER(vbox
), 5);
211 gtk_widget_show(vbox
);
213 sw
= gtk_scrolled_window_new(NULL
, NULL
);
214 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw
), GTK_POLICY_NEVER
,
216 gtk_widget_set_usize(sw
, 245, 120);
217 gtk_box_pack_start(GTK_BOX(vbox
), sw
, TRUE
, TRUE
, 0);
220 awaytext
= gtk_imhtml_new(NULL
, NULL
);
221 gtk_container_add(GTK_CONTAINER(sw
), awaytext
);
222 GTK_LAYOUT(awaytext
)->hadjustment
->step_increment
= 10.0;
223 GTK_LAYOUT(awaytext
)->vadjustment
->step_increment
= 10.0;
224 gaim_setup_imhtml(awaytext
);
225 gtk_widget_show(awaytext
);
226 buf
= stylize(a
->message
, BUF_LONG
);
227 gtk_imhtml_append_text(GTK_IMHTML(awaytext
), buf
, -1, GTK_IMHTML_NO_TITLE
|
228 GTK_IMHTML_NO_COMMENTS
| GTK_IMHTML_NO_SCROLL
);
230 gtk_imhtml_append_text(GTK_IMHTML(awaytext
), "<BR>", -1, GTK_IMHTML_NO_TITLE
|
231 GTK_IMHTML_NO_COMMENTS
| GTK_IMHTML_NO_SCROLL
);
233 clistqueuesw
= gtk_scrolled_window_new(NULL
, NULL
);
234 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(clistqueuesw
), GTK_POLICY_NEVER
,
235 GTK_POLICY_AUTOMATIC
);
236 gtk_box_pack_start(GTK_BOX(vbox
), clistqueuesw
, TRUE
, TRUE
, 0);
238 clistqueue
= gtk_clist_new(2);
239 gtk_clist_set_column_width(GTK_CLIST(clistqueue
), 0, 100);
240 gtk_widget_set_usize(GTK_WIDGET(clistqueue
), -1, 50);
241 gtk_container_add(GTK_CONTAINER(clistqueuesw
), clistqueue
);
242 gtk_signal_connect(GTK_OBJECT(clistqueue
), "select_row", GTK_SIGNAL_FUNC(dequeue_by_buddy
), NULL
);
246 if (away_options
& OPT_AWAY_QUEUE
) {
247 gtk_widget_show(clistqueuesw
);
248 gtk_widget_show(clistqueue
);
251 back
= picture_button(imaway
, _("I'm Back!"), join_xpm
);
252 gtk_box_pack_start(GTK_BOX(vbox
), back
, FALSE
, FALSE
, 0);
253 gtk_signal_connect(GTK_OBJECT(back
), "clicked", GTK_SIGNAL_FUNC(do_im_back
), imaway
);
254 gtk_window_set_focus(GTK_WINDOW(imaway
), back
);
260 do_away_message(w
, a
);
265 remove_applet_away();
266 applet_widget_register_callback(APPLET_WIDGET(applet
),
267 "away", _("Back"), (AppletCallbackFunc
)do_im_back
, NULL
);
268 set_user_state(away
);
271 /* New away message... Clear out the old sent_aways */
272 while (away_time_queue
) {
273 struct queued_away_response
*qar
= away_time_queue
->data
;
274 away_time_queue
= g_slist_remove(away_time_queue
, qar
);
278 gtk_widget_show(imaway
);
279 buf2
= g_malloc(strlen(awaymessage
->message
) * 4 + 1);
280 strncpy_withhtml(buf2
, awaymessage
->message
, strlen(awaymessage
->message
) * 4 + 1);
281 serv_set_away_all(buf2
);
285 void rem_away_mess(GtkWidget
*w
, struct away_message
*a
)
290 awayname
= g_malloc(sizeof(*awayname
) * (6 + strlen(a
->name
)));
292 strcat(awayname
, "away/");
293 strcat(awayname
, a
->name
);
294 applet_widget_unregister_callback(APPLET_WIDGET(applet
), awayname
);
297 default_index
= g_slist_index(away_messages
, default_away
);
298 if (default_index
== -1) {
299 if (away_messages
!= NULL
)
300 default_away
= away_messages
->data
;
304 away_messages
= g_slist_remove(away_messages
, a
);
310 static void set_gc_away(GtkObject
*obj
, struct gaim_connection
*gc
)
312 struct away_message
*awy
= gtk_object_get_user_data(obj
);
315 serv_set_away(gc
, GAIM_AWAY_CUSTOM
, awy
->message
);
317 serv_set_away(gc
, GAIM_AWAY_CUSTOM
, NULL
);
320 static void set_gc_state(GtkObject
*obj
, struct gaim_connection
*gc
)
322 char *awy
= gtk_object_get_user_data(obj
);
324 serv_set_away(gc
, awy
, NULL
);
331 GtkWidget
*submenu
, *submenu2
;
336 GtkWidget
*list_item
;
337 GSList
*awy
= away_messages
;
338 struct away_message
*a
;
339 GSList
*con
= connections
;
340 struct gaim_connection
*gc
= NULL
;
344 remove_applet_away();
345 if (imaway
&& applet
)
346 applet_widget_register_callback(APPLET_WIDGET(applet
),
347 "away", _("Back"), (AppletCallbackFunc
)do_im_back
, NULL
);
348 else if (applet
&& !imaway
)
349 insert_applet_away();
352 if (prefs_away_list
!= NULL
) {
354 gtk_list_clear_items(GTK_LIST(prefs_away_list
), 0, -1);
356 a
= (struct away_message
*)awy
->data
;
357 list_item
= gtk_list_item_new();
358 gtk_container_add(GTK_CONTAINER(prefs_away_list
), list_item
);
359 gtk_signal_connect(GTK_OBJECT(list_item
), "select",
360 GTK_SIGNAL_FUNC(away_list_clicked
), a
);
361 gtk_object_set_user_data(GTK_OBJECT(list_item
), a
);
362 gtk_widget_show(list_item
);
364 hbox
= gtk_hbox_new(FALSE
, 5);
365 gtk_container_add(GTK_CONTAINER(list_item
), hbox
);
366 gtk_widget_show(hbox
);
368 label
= gtk_label_new(a
->name
);
369 gtk_box_pack_start(GTK_BOX(hbox
), label
, FALSE
, FALSE
, 5);
370 gtk_widget_show(label
);
372 awy
= g_slist_next(awy
);
374 if (away_messages
!= NULL
)
375 gtk_list_select_item(GTK_LIST(prefs_away_list
), 0);
379 l
= gtk_container_children(GTK_CONTAINER(awaymenu
));
382 gtk_container_remove(GTK_CONTAINER(awaymenu
), GTK_WIDGET(l
->data
));
387 remmenu
= gtk_menu_new();
389 menuitem
= gtk_menu_item_new_with_label(_("New Away Message"));
390 gtk_menu_append(GTK_MENU(awaymenu
), menuitem
);
391 gtk_widget_show(menuitem
);
392 gtk_signal_connect(GTK_OBJECT(menuitem
), "activate", GTK_SIGNAL_FUNC(create_away_mess
),
397 a
= (struct away_message
*)awy
->data
;
399 remitem
= gtk_menu_item_new_with_label(a
->name
);
400 gtk_menu_append(GTK_MENU(remmenu
), remitem
);
401 gtk_widget_show(remitem
);
402 gtk_signal_connect(GTK_OBJECT(remitem
), "activate",
403 GTK_SIGNAL_FUNC(rem_away_mess
), a
);
405 awy
= g_slist_next(awy
);
409 menuitem
= gtk_menu_item_new_with_label(_("Remove Away Message"));
410 gtk_menu_append(GTK_MENU(awaymenu
), menuitem
);
411 gtk_widget_show(menuitem
);
412 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem
), remmenu
);
413 gtk_widget_show(remmenu
);
415 sep
= gtk_hseparator_new();
416 menuitem
= gtk_menu_item_new();
417 gtk_menu_append(GTK_MENU(awaymenu
), menuitem
);
418 gtk_container_add(GTK_CONTAINER(menuitem
), sep
);
419 gtk_widget_set_sensitive(menuitem
, FALSE
);
420 gtk_widget_show(menuitem
);
421 gtk_widget_show(sep
);
425 if (gc
->prpl
->away_states
&&gc
->prpl
->set_away
)
427 con
= g_slist_next(con
);
432 } else if (count
== 1) {
436 if (gc
->prpl
->away_states
&&gc
->prpl
->set_away
)
438 con
= g_slist_next(con
);
441 tmp
= msgs
= gc
->prpl
->away_states(gc
);
443 if ((g_list_length(msgs
) == 1) && !strcmp(msgs
->data
, GAIM_AWAY_CUSTOM
)) {
447 a
= (struct away_message
*)awy
->data
;
449 menuitem
= gtk_menu_item_new_with_label(a
->name
);
450 gtk_object_set_user_data(GTK_OBJECT(menuitem
), a
);
451 gtk_menu_append(GTK_MENU(awaymenu
), menuitem
);
452 gtk_widget_show(menuitem
);
453 gtk_signal_connect(GTK_OBJECT(menuitem
), "activate",
454 GTK_SIGNAL_FUNC(do_away_message
), a
);
456 awy
= g_slist_next(awy
);
462 menuitem
= gtk_menu_item_new_with_label(msgs
->data
);
463 gtk_object_set_user_data(GTK_OBJECT(menuitem
), msgs
->data
);
464 gtk_menu_append(GTK_MENU(awaymenu
), menuitem
);
465 gtk_widget_show(menuitem
);
467 if (strcmp(msgs
->data
, GAIM_AWAY_CUSTOM
)) {
468 gtk_signal_connect(GTK_OBJECT(menuitem
), "activate",
469 GTK_SIGNAL_FUNC(set_gc_state
), gc
);
471 submenu
= gtk_menu_new();
472 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem
),
474 gtk_widget_show(submenu
);
477 a
= (struct away_message
*)awy
->data
;
479 menuitem
= gtk_menu_item_new_with_label(a
->name
);
480 gtk_object_set_user_data(GTK_OBJECT(menuitem
),
482 gtk_menu_append(GTK_MENU(submenu
), menuitem
);
483 gtk_widget_show(menuitem
);
484 gtk_signal_connect(GTK_OBJECT(menuitem
),
487 (do_away_message
), a
);
489 awy
= g_slist_next(awy
);
492 msgs
= g_list_next(msgs
);
502 if (!gc
->prpl
->away_states
||!gc
->prpl
->set_away
) {
507 g_snprintf(buf
, sizeof(buf
), "%s (%s)",
508 gc
->username
, gc
->prpl
->name());
509 menuitem
= gtk_menu_item_new_with_label(buf
);
510 gtk_menu_append(GTK_MENU(awaymenu
), menuitem
);
511 gtk_widget_show(menuitem
);
513 submenu
= gtk_menu_new();
514 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem
), submenu
);
515 gtk_widget_show(submenu
);
517 tmp
= msgs
= gc
->prpl
->away_states(gc
);
519 if ((g_list_length(msgs
) == 1) &&
520 (!strcmp(msgs
->data
, GAIM_AWAY_CUSTOM
))) {
521 menuitem
= gtk_menu_item_new_with_label(_("Back"));
522 gtk_menu_append(GTK_MENU(submenu
), menuitem
);
523 gtk_widget_show(menuitem
);
524 gtk_signal_connect(GTK_OBJECT(menuitem
), "activate",
525 GTK_SIGNAL_FUNC(set_gc_away
), gc
);
527 sep
= gtk_hseparator_new();
528 menuitem
= gtk_menu_item_new();
529 gtk_menu_append(GTK_MENU(submenu
), menuitem
);
530 gtk_container_add(GTK_CONTAINER(menuitem
), sep
);
531 gtk_widget_set_sensitive(menuitem
, FALSE
);
532 gtk_widget_show(menuitem
);
533 gtk_widget_show(sep
);
538 a
= (struct away_message
*)awy
->data
;
540 menuitem
= gtk_menu_item_new_with_label(a
->name
);
541 gtk_object_set_user_data(GTK_OBJECT(menuitem
), a
);
542 gtk_menu_append(GTK_MENU(submenu
), menuitem
);
543 gtk_widget_show(menuitem
);
544 gtk_signal_connect(GTK_OBJECT(menuitem
), "activate",
545 GTK_SIGNAL_FUNC(set_gc_away
), gc
);
547 awy
= g_slist_next(awy
);
553 menuitem
= gtk_menu_item_new_with_label(msgs
->data
);
554 gtk_object_set_user_data(GTK_OBJECT(menuitem
),
556 gtk_menu_append(GTK_MENU(submenu
), menuitem
);
557 gtk_widget_show(menuitem
);
559 if (strcmp(msgs
->data
, GAIM_AWAY_CUSTOM
)) {
560 gtk_signal_connect(GTK_OBJECT(menuitem
),
562 GTK_SIGNAL_FUNC(set_gc_state
),
565 submenu2
= gtk_menu_new();
566 gtk_menu_item_set_submenu(GTK_MENU_ITEM
567 (menuitem
), submenu2
);
568 gtk_widget_show(submenu2
);
571 a
= (struct away_message
*)awy
->data
;
574 gtk_menu_item_new_with_label(a
->
576 gtk_object_set_user_data(GTK_OBJECT
578 gtk_menu_append(GTK_MENU(submenu2
),
580 gtk_widget_show(menuitem
);
581 gtk_signal_connect(GTK_OBJECT(menuitem
),
586 awy
= g_slist_next(awy
);
589 msgs
= g_list_next(msgs
);
594 con
= g_slist_next(con
);
597 menuitem
= gtk_menu_item_new_with_label(_("Set All Away"));
598 gtk_menu_append(GTK_MENU(awaymenu
), menuitem
);
599 gtk_widget_show(menuitem
);
601 submenu
= gtk_menu_new();
602 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem
), submenu
);
603 gtk_widget_show(submenu
);
608 a
= (struct away_message
*)awy
->data
;
610 menuitem
= gtk_menu_item_new_with_label(a
->name
);
611 gtk_object_set_user_data(GTK_OBJECT(menuitem
), a
);
612 gtk_menu_append(GTK_MENU(submenu
), menuitem
);
613 gtk_widget_show(menuitem
);
614 gtk_signal_connect(GTK_OBJECT(menuitem
), "activate",
615 GTK_SIGNAL_FUNC(do_away_message
), a
);
617 awy
= g_slist_next(awy
);
621 if (prefs_away_menu
) {
622 l
= gtk_container_children(GTK_CONTAINER(prefs_away_menu
));
624 gtk_widget_destroy(GTK_WIDGET(l
->data
));
627 gtk_widget_hide(GTK_WIDGET(prefs_away_menu
));
628 default_away_menu_init(GTK_WIDGET(prefs_away_menu
));
629 gtk_widget_show(prefs_away_menu
);