3 * Pidgin is the legal property of its developers, whose names are too numerous
4 * to list here. Please refer to the COPYRIGHT file distributed with this
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
28 #include "conversation.h"
36 #include "gtk3compat.h"
38 #include "gtkdialogs.h"
39 #include "gtkpounce.h"
40 #include "gtknotify.h"
41 #include "pidginstock.h"
43 #include "pidginaccountchooser.h"
44 #include "pidgintalkatu.h"
46 #include <gdk/gdkkeysyms.h>
49 * These are used for the GtkTreeView when you're scrolling through
50 * all your saved pounces.
54 /* Hidden column containing the PurplePounce */
55 POUNCES_MANAGER_COLUMN_POUNCE
,
56 POUNCES_MANAGER_COLUMN_ICON
,
57 POUNCES_MANAGER_COLUMN_TARGET
,
58 POUNCES_MANAGER_COLUMN_ACCOUNT
,
59 POUNCES_MANAGER_COLUMN_RECURRING
,
60 POUNCES_MANAGER_NUM_COLUMNS
67 PurpleAccount
*account
;
73 GtkWidget
*account_menu
;
74 GtkWidget
*buddy_entry
;
79 /* Pounce When Buddy... */
83 GtkWidget
*away_return
;
85 GtkWidget
*idle_return
;
88 GtkWidget
*stop_typing
;
89 GtkWidget
*message_recv
;
94 GtkWidget
*popup_entry
;
96 GtkWidget
*send_msg_entry
;
97 GtkTextBuffer
*send_msg_buffer
;
99 GtkWidget
*exec_cmd_entry
;
100 GtkWidget
*exec_cmd_browse
;
101 GtkWidget
*play_sound
;
102 GtkWidget
*play_sound_entry
;
103 GtkWidget
*play_sound_browse
;
104 GtkWidget
*play_sound_test
;
105 GtkWidget
*play_sound_reset
;
107 GtkWidget
*save_pounce
;
110 GtkWidget
*save_button
;
112 } PidginPounceDialog
;
119 GtkWidget
*modify_button
;
120 GtkWidget
*delete_button
;
123 static PouncesManager
*pounces_manager
= NULL
;
125 /**************************************************************************
127 **************************************************************************/
129 delete_win_cb(GtkWidget
*w
, GdkEventAny
*e
, PidginPounceDialog
*dialog
)
131 gtk_widget_destroy(dialog
->window
);
138 cancel_cb(GtkWidget
*w
, PidginPounceDialog
*dialog
)
140 delete_win_cb(NULL
, NULL
, dialog
);
144 pounce_update_entry_fields(void *user_data
, const char *filename
)
146 GtkWidget
*entry
= (GtkWidget
*)user_data
;
148 gtk_entry_set_text(GTK_ENTRY(entry
), filename
);
152 filesel(GtkWidget
*widget
, gpointer data
)
157 entry
= (GtkWidget
*)data
;
158 name
= gtk_entry_get_text(GTK_ENTRY(entry
));
160 purple_request_file(entry
, _("Select a file"), name
, FALSE
,
161 G_CALLBACK(pounce_update_entry_fields
), NULL
, NULL
, entry
);
162 g_signal_connect_swapped(G_OBJECT(entry
), "destroy",
163 G_CALLBACK(purple_request_close_with_handle
), entry
);
167 pounce_test_sound(GtkWidget
*w
, GtkWidget
*entry
)
169 const char *filename
;
172 temp_mute
= purple_prefs_get_bool(PIDGIN_PREFS_ROOT
"/sound/mute");
174 if (temp_mute
) purple_prefs_set_bool(PIDGIN_PREFS_ROOT
"/sound/mute", FALSE
);
176 filename
= gtk_entry_get_text(GTK_ENTRY(entry
));
178 if (filename
!= NULL
&& *filename
!= '\0' && !purple_strequal(filename
, _("(default)")))
179 purple_sound_play_file(filename
, NULL
);
181 purple_sound_play_event(PURPLE_SOUND_POUNCE_DEFAULT
, NULL
);
183 if (temp_mute
) purple_prefs_set_bool(PIDGIN_PREFS_ROOT
"/sound/mute", TRUE
);
187 pounce_reset_sound(GtkWidget
*w
, GtkWidget
*entry
)
189 gtk_entry_set_text(GTK_ENTRY(entry
), _("(default)"));
193 add_pounce_to_treeview(GtkListStore
*model
, PurplePounce
*pounce
)
196 PurpleAccount
*account
;
202 account
= purple_pounce_get_pouncer(pounce
);
204 pixbuf
= pidgin_create_protocol_icon(account
, PIDGIN_PROTOCOL_ICON_MEDIUM
);
206 pouncer
= purple_account_get_username(account
);
207 pouncee
= purple_pounce_get_pouncee(pounce
);
208 recurring
= purple_pounce_get_save(pounce
);
210 gtk_list_store_append(model
, &iter
);
211 gtk_list_store_set(model
, &iter
,
212 POUNCES_MANAGER_COLUMN_POUNCE
, pounce
,
213 POUNCES_MANAGER_COLUMN_ICON
, pixbuf
,
214 POUNCES_MANAGER_COLUMN_TARGET
, pouncee
,
215 POUNCES_MANAGER_COLUMN_ACCOUNT
, pouncer
,
216 POUNCES_MANAGER_COLUMN_RECURRING
, recurring
,
220 g_object_unref(pixbuf
);
224 populate_pounces_list(PouncesManager
*dialog
)
228 gtk_list_store_clear(dialog
->model
);
230 for (pounces
= purple_pounces_get_all_for_ui(PIDGIN_UI
); pounces
!= NULL
;
231 pounces
= g_list_delete_link(pounces
, pounces
))
233 add_pounce_to_treeview(dialog
->model
, pounces
->data
);
240 /* Rebuild the pounces list if the pounces manager is open */
241 if (pounces_manager
!= NULL
)
243 populate_pounces_list(pounces_manager
);
248 signed_on_off_cb(PurpleConnection
*gc
, gpointer user_data
)
254 save_pounce_cb(GtkWidget
*w
, PidginPounceDialog
*dialog
)
257 const char *command
, *sound
, *reason
;
259 PurplePounceEvent events
= PURPLE_POUNCE_NONE
;
260 PurplePounceOption options
= PURPLE_POUNCE_OPTION_NONE
;
262 name
= gtk_entry_get_text(GTK_ENTRY(dialog
->buddy_entry
));
266 purple_notify_error(NULL
, NULL
, _("Please enter a buddy to "
267 "pounce."), NULL
, NULL
);
272 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog
->on_away
)))
273 options
|= PURPLE_POUNCE_OPTION_AWAY
;
276 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog
->signon
)))
277 events
|= PURPLE_POUNCE_SIGNON
;
279 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog
->signoff
)))
280 events
|= PURPLE_POUNCE_SIGNOFF
;
282 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog
->away
)))
283 events
|= PURPLE_POUNCE_AWAY
;
285 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog
->away_return
)))
286 events
|= PURPLE_POUNCE_AWAY_RETURN
;
288 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog
->idle
)))
289 events
|= PURPLE_POUNCE_IDLE
;
291 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog
->idle_return
)))
292 events
|= PURPLE_POUNCE_IDLE_RETURN
;
294 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog
->typing
)))
295 events
|= PURPLE_POUNCE_TYPING
;
297 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog
->typed
)))
298 events
|= PURPLE_POUNCE_TYPED
;
300 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog
->stop_typing
)))
301 events
|= PURPLE_POUNCE_TYPING_STOPPED
;
303 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog
->message_recv
)))
304 events
|= PURPLE_POUNCE_MESSAGE_RECEIVED
;
307 message
= talkatu_markup_get_html(dialog
->send_msg_buffer
, NULL
);
308 command
= gtk_entry_get_text(GTK_ENTRY(dialog
->exec_cmd_entry
));
309 sound
= gtk_entry_get_text(GTK_ENTRY(dialog
->play_sound_entry
));
310 reason
= gtk_entry_get_text(GTK_ENTRY(dialog
->popup_entry
));
312 if (*reason
== '\0') reason
= NULL
;
313 if (*message
== '\0') {
317 if (*command
== '\0') command
= NULL
;
318 if (*sound
== '\0' || purple_strequal(sound
, _("(default)"))) sound
= NULL
;
320 /* If the pounce has already been triggered, let's pretend it is a new one */
321 if (dialog
->pounce
!= NULL
322 && g_list_find(purple_pounces_get_all(), dialog
->pounce
) == NULL
) {
323 purple_debug_info("gtkpounce", "Saving pounce that no longer exists; creating new pounce.\n");
324 dialog
->pounce
= NULL
;
327 if (dialog
->pounce
== NULL
)
329 dialog
->pounce
= purple_pounce_new(PIDGIN_UI
, dialog
->account
,
330 name
, events
, options
);
333 purple_pounce_set_events(dialog
->pounce
, events
);
334 purple_pounce_set_options(dialog
->pounce
, options
);
335 purple_pounce_set_pouncer(dialog
->pounce
, dialog
->account
);
336 purple_pounce_set_pouncee(dialog
->pounce
, name
);
340 purple_pounce_action_set_enabled(dialog
->pounce
, "open-window",
341 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog
->open_win
)));
342 purple_pounce_action_set_enabled(dialog
->pounce
, "popup-notify",
343 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog
->popup
)));
344 purple_pounce_action_set_enabled(dialog
->pounce
, "send-message",
345 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog
->send_msg
)));
346 purple_pounce_action_set_enabled(dialog
->pounce
, "execute-command",
347 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog
->exec_cmd
)));
348 purple_pounce_action_set_enabled(dialog
->pounce
, "play-sound",
349 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog
->play_sound
)));
351 purple_pounce_action_set_attribute(dialog
->pounce
, "send-message",
353 purple_pounce_action_set_attribute(dialog
->pounce
, "execute-command",
355 purple_pounce_action_set_attribute(dialog
->pounce
, "play-sound",
357 purple_pounce_action_set_attribute(dialog
->pounce
, "popup-notify",
360 /* Set the defaults for next time. */
361 purple_prefs_set_bool(PIDGIN_PREFS_ROOT
"/pounces/default_actions/open-window",
362 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog
->open_win
)));
363 purple_prefs_set_bool(PIDGIN_PREFS_ROOT
"/pounces/default_actions/popup-notify",
364 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog
->popup
)));
365 purple_prefs_set_bool(PIDGIN_PREFS_ROOT
"/pounces/default_actions/send-message",
366 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog
->send_msg
)));
367 purple_prefs_set_bool(PIDGIN_PREFS_ROOT
"/pounces/default_actions/execute-command",
368 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog
->exec_cmd
)));
369 purple_prefs_set_bool(PIDGIN_PREFS_ROOT
"/pounces/default_actions/play-sound",
370 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog
->play_sound
)));
372 purple_pounce_set_save(dialog
->pounce
,
373 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog
->save_pounce
)));
378 delete_win_cb(NULL
, NULL
, dialog
);
382 entry_key_press_cb(GtkWidget
*widget
, GdkEventKey
*event
,
383 PidginPounceDialog
*dialog
)
385 if ((event
->keyval
== GDK_KEY_Return
)
386 || (event
->keyval
== GDK_KEY_KP_Enter
)) {
387 save_pounce_cb(widget
, dialog
);
395 pounce_choose_cb(GtkWidget
*chooser
, PidginPounceDialog
*dialog
)
397 dialog
->account
= pidgin_account_chooser_get_selected(chooser
);
401 buddy_changed_cb(GtkEntry
*entry
, PidginPounceDialog
*dialog
)
403 if (dialog
->save_button
== NULL
)
406 gtk_widget_set_sensitive(dialog
->save_button
,
407 *gtk_entry_get_text(entry
) != '\0');
411 message_recv_toggle(GtkButton
*message_recv
, GtkWidget
*send_msg
)
413 gboolean active
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(message_recv
));
415 gtk_widget_set_sensitive(send_msg
, !active
);
417 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(send_msg
), FALSE
);
421 pounce_dnd_recv(GtkWidget
*widget
, GdkDragContext
*dc
, gint x
, gint y
,
422 GtkSelectionData
*sd
, guint info
, guint t
, gpointer data
)
424 PidginPounceDialog
*dialog
;
425 GdkAtom target
= gtk_selection_data_get_target(sd
);
426 const guchar
*sd_data
= gtk_selection_data_get_data(sd
);
428 if (target
== gdk_atom_intern("PURPLE_BLIST_NODE", FALSE
))
430 PurpleBlistNode
*node
= NULL
;
433 memcpy(&node
, sd_data
, sizeof(node
));
435 if (PURPLE_IS_CONTACT(node
))
436 buddy
= purple_contact_get_priority_buddy((PurpleContact
*)node
);
437 else if (PURPLE_IS_BUDDY(node
))
438 buddy
= (PurpleBuddy
*)node
;
442 dialog
= (PidginPounceDialog
*)data
;
444 gtk_entry_set_text(GTK_ENTRY(dialog
->buddy_entry
), purple_buddy_get_name(buddy
));
445 dialog
->account
= purple_buddy_get_account(buddy
);
446 pidgin_account_chooser_set_selected(
447 dialog
->account_menu
, purple_buddy_get_account(buddy
));
449 gtk_drag_finish(dc
, TRUE
, (gdk_drag_context_get_actions(dc
) == GDK_ACTION_MOVE
), t
);
451 else if (target
== gdk_atom_intern("application/x-im-contact", FALSE
))
453 char *protocol
= NULL
;
454 char *username
= NULL
;
455 PurpleAccount
*account
;
457 if (pidgin_parse_x_im_contact((const char *)sd_data
, FALSE
, &account
,
458 &protocol
, &username
, NULL
))
462 purple_notify_error(NULL
, NULL
,
463 _("You are not currently signed on with an account that "
464 "can add that buddy."), NULL
, NULL
);
468 dialog
= (PidginPounceDialog
*)data
;
470 gtk_entry_set_text(GTK_ENTRY(dialog
->buddy_entry
), username
);
471 dialog
->account
= account
;
472 pidgin_account_chooser_set_selected(
473 dialog
->account_menu
, account
);
480 gtk_drag_finish(dc
, TRUE
, (gdk_drag_context_get_actions(dc
) == GDK_ACTION_MOVE
), t
);
484 static const GtkTargetEntry dnd_targets
[] =
486 {"PURPLE_BLIST_NODE", GTK_TARGET_SAME_APP
, 0},
487 {"application/x-im-contact", 0, 1}
491 reset_send_msg_entry(PidginPounceDialog
*dialog
, GtkWidget
*dontcare
)
493 PurpleAccount
*account
=
494 pidgin_account_chooser_get_selected(dialog
->account_menu
);
496 if(GTK_IS_TEXT_BUFFER(dialog
->send_msg_buffer
)) {
497 g_object_unref(dialog
->send_msg_buffer
);
500 dialog
->send_msg_buffer
= NULL
;
503 PurpleConnection
*pc
= purple_account_get_connection(account
);
506 dialog
->send_msg_buffer
= pidgin_talkatu_buffer_new_for_connection(pc
);
510 if(dialog
->send_msg_buffer
== NULL
) {
511 dialog
->send_msg_buffer
= talkatu_buffer_new(NULL
);
514 gtk_text_view_set_buffer(GTK_TEXT_VIEW(dialog
->send_msg_entry
), dialog
->send_msg_buffer
);
518 pidgin_pounce_editor_show(PurpleAccount
*account
, const char *name
,
519 PurplePounce
*cur_pounce
)
521 PidginPounceDialog
*dialog
;
524 GtkWidget
*vbox1
, *vbox2
;
532 g_return_if_fail((cur_pounce
!= NULL
) ||
534 (purple_accounts_get_all() != NULL
));
536 dialog
= g_new0(PidginPounceDialog
, 1);
538 if (cur_pounce
!= NULL
)
540 dialog
->pounce
= cur_pounce
;
541 dialog
->account
= purple_pounce_get_pouncer(cur_pounce
);
543 else if (account
!= NULL
)
545 dialog
->pounce
= NULL
;
546 dialog
->account
= account
;
550 GList
*connections
= purple_connections_get_all();
551 PurpleConnection
*gc
;
553 if (connections
!= NULL
)
555 gc
= (PurpleConnection
*)connections
->data
;
556 dialog
->account
= purple_connection_get_account(gc
);
559 dialog
->account
= purple_accounts_get_all()->data
;
561 dialog
->pounce
= NULL
;
564 sg
= gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL
);
566 /* Create the window. */
567 dialog
->window
= window
= gtk_dialog_new();
568 gtk_window_set_title(GTK_WINDOW(window
), (cur_pounce
== NULL
? _("Add Buddy Pounce") : _("Modify Buddy Pounce")));
569 gtk_window_set_role(GTK_WINDOW(window
), "buddy_pounce");
571 g_signal_connect(G_OBJECT(window
), "delete_event",
572 G_CALLBACK(delete_win_cb
), dialog
);
574 /* Get the parent vbox for everything. */
575 vbox1
= gtk_dialog_get_content_area(GTK_DIALOG(window
));
577 /* Create the vbox that will contain all the prefs stuff. */
578 vbox2
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, PIDGIN_HIG_BOX_SPACE
);
579 gtk_box_pack_start(GTK_BOX(vbox1
), vbox2
, TRUE
, TRUE
, 0);
581 /* Create the "Pounce on Whom" frame. */
582 frame
= pidgin_make_frame(vbox2
, _("Pounce on Whom"));
585 hbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, PIDGIN_HIG_BOX_SPACE
);
586 gtk_box_pack_start(GTK_BOX(frame
), hbox
, FALSE
, FALSE
, 0);
587 gtk_widget_show(hbox
);
589 label
= gtk_label_new_with_mnemonic(_("_Account:"));
590 gtk_label_set_xalign(GTK_LABEL(label
), 0);
591 gtk_box_pack_start(GTK_BOX(hbox
), label
, FALSE
, FALSE
, 0);
592 gtk_widget_show(label
);
593 gtk_size_group_add_widget(sg
, label
);
595 dialog
->account_menu
=
596 pidgin_account_chooser_new(dialog
->account
, TRUE
);
597 g_signal_connect(dialog
->account_menu
, "changed",
598 G_CALLBACK(pounce_choose_cb
), dialog
);
600 gtk_box_pack_start(GTK_BOX(hbox
), dialog
->account_menu
, FALSE
, FALSE
, 0);
601 gtk_widget_show(dialog
->account_menu
);
602 pidgin_set_accessible_label(dialog
->account_menu
, GTK_LABEL(label
));
605 hbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, PIDGIN_HIG_BOX_SPACE
);
606 gtk_box_pack_start(GTK_BOX(frame
), hbox
, FALSE
, FALSE
, 0);
607 gtk_widget_show(hbox
);
609 label
= gtk_label_new_with_mnemonic(_("_Buddy name:"));
610 gtk_label_set_xalign(GTK_LABEL(label
), 0);
611 gtk_box_pack_start(GTK_BOX(hbox
), label
, FALSE
, FALSE
, 0);
612 gtk_widget_show(label
);
613 gtk_size_group_add_widget(sg
, label
);
615 dialog
->buddy_entry
= gtk_entry_new();
617 pidgin_setup_screenname_autocomplete(dialog
->buddy_entry
, dialog
->account_menu
, pidgin_screenname_autocomplete_default_filter
, GINT_TO_POINTER(FALSE
));
619 gtk_box_pack_start(GTK_BOX(hbox
), dialog
->buddy_entry
, TRUE
, TRUE
, 0);
620 gtk_widget_show(dialog
->buddy_entry
);
622 g_signal_connect(G_OBJECT(dialog
->buddy_entry
), "changed",
623 G_CALLBACK(buddy_changed_cb
), dialog
);
624 pidgin_set_accessible_label(dialog
->buddy_entry
, GTK_LABEL(label
));
626 if (cur_pounce
!= NULL
) {
627 gtk_entry_set_text(GTK_ENTRY(dialog
->buddy_entry
),
628 purple_pounce_get_pouncee(cur_pounce
));
630 else if (name
!= NULL
) {
631 gtk_entry_set_text(GTK_ENTRY(dialog
->buddy_entry
), name
);
634 /* Create the "Pounce When Buddy..." frame. */
635 frame
= pidgin_make_frame(vbox2
, _("Pounce When Buddy..."));
637 grid
= gtk_grid_new();
638 gtk_container_add(GTK_CONTAINER(frame
), grid
);
639 gtk_grid_set_column_spacing(GTK_GRID(grid
), PIDGIN_HIG_BORDER
);
640 gtk_widget_show(grid
);
643 gtk_check_button_new_with_mnemonic(_("Si_gns on"));
645 gtk_check_button_new_with_mnemonic(_("Signs o_ff"));
647 gtk_check_button_new_with_mnemonic(_("Goes a_way"));
648 dialog
->away_return
=
649 gtk_check_button_new_with_mnemonic(_("Ret_urns from away"));
651 gtk_check_button_new_with_mnemonic(_("Becomes _idle"));
652 dialog
->idle_return
=
653 gtk_check_button_new_with_mnemonic(_("Is no longer i_dle"));
655 gtk_check_button_new_with_mnemonic(_("Starts _typing"));
657 gtk_check_button_new_with_mnemonic(_("P_auses while typing"));
658 dialog
->stop_typing
=
659 gtk_check_button_new_with_mnemonic(_("Stops t_yping"));
660 dialog
->message_recv
=
661 gtk_check_button_new_with_mnemonic(_("Sends a _message"));
663 gtk_widget_set_valign(dialog
->message_recv
, GTK_ALIGN_CENTER
);
664 gtk_widget_set_valign(dialog
->signon
, GTK_ALIGN_CENTER
);
665 gtk_widget_set_valign(dialog
->signoff
, GTK_ALIGN_CENTER
);
666 gtk_widget_set_valign(dialog
->away
, GTK_ALIGN_CENTER
);
667 gtk_widget_set_valign(dialog
->away_return
, GTK_ALIGN_CENTER
);
668 gtk_widget_set_valign(dialog
->idle
, GTK_ALIGN_CENTER
);
669 gtk_widget_set_valign(dialog
->idle_return
, GTK_ALIGN_CENTER
);
670 gtk_widget_set_valign(dialog
->typing
, GTK_ALIGN_CENTER
);
671 gtk_widget_set_valign(dialog
->typed
, GTK_ALIGN_CENTER
);
672 gtk_widget_set_valign(dialog
->stop_typing
, GTK_ALIGN_CENTER
);
674 gtk_grid_attach(GTK_GRID(grid
), dialog
->message_recv
, 0, 0, 1, 1);
675 gtk_grid_attach(GTK_GRID(grid
), dialog
->signon
, 0, 1, 1, 1);
676 gtk_grid_attach(GTK_GRID(grid
), dialog
->signoff
, 0, 2, 1, 1);
677 gtk_grid_attach(GTK_GRID(grid
), dialog
->away
, 1, 0, 1, 1);
678 gtk_grid_attach(GTK_GRID(grid
), dialog
->away_return
, 1, 1, 1, 1);
679 gtk_grid_attach(GTK_GRID(grid
), dialog
->idle
, 1, 2, 1, 1);
680 gtk_grid_attach(GTK_GRID(grid
), dialog
->idle_return
, 2, 0, 1, 1);
681 gtk_grid_attach(GTK_GRID(grid
), dialog
->typing
, 2, 1, 1, 1);
682 gtk_grid_attach(GTK_GRID(grid
), dialog
->typed
, 2, 2, 1, 1);
683 gtk_grid_attach(GTK_GRID(grid
), dialog
->stop_typing
, 3, 0, 1, 1);
685 gtk_widget_show(dialog
->signon
);
686 gtk_widget_show(dialog
->signoff
);
687 gtk_widget_show(dialog
->away
);
688 gtk_widget_show(dialog
->away_return
);
689 gtk_widget_show(dialog
->idle
);
690 gtk_widget_show(dialog
->idle_return
);
691 gtk_widget_show(dialog
->typing
);
692 gtk_widget_show(dialog
->typed
);
693 gtk_widget_show(dialog
->stop_typing
);
694 gtk_widget_show(dialog
->message_recv
);
696 /* Create the "Action" frame. */
697 frame
= pidgin_make_frame(vbox2
, _("Action"));
699 grid
= gtk_grid_new();
700 gtk_container_add(GTK_CONTAINER(frame
), grid
);
701 gtk_grid_set_column_spacing(GTK_GRID(grid
), PIDGIN_HIG_BORDER
);
702 gtk_widget_show(grid
);
705 = gtk_check_button_new_with_mnemonic(_("Ope_n an IM window"));
707 = gtk_check_button_new_with_mnemonic(_("_Pop up a notification"));
709 = gtk_check_button_new_with_mnemonic(_("Send a _message"));
711 = gtk_check_button_new_with_mnemonic(_("E_xecute a command"));
713 = gtk_check_button_new_with_mnemonic(_("P_lay a sound"));
715 editor
= talkatu_editor_new();
716 dialog
->send_msg_entry
= talkatu_editor_get_view(TALKATU_EDITOR(editor
));
717 reset_send_msg_entry(dialog
, NULL
);
719 dialog
->exec_cmd_entry
= gtk_entry_new();
720 dialog
->popup_entry
= gtk_entry_new();
721 dialog
->exec_cmd_browse
= gtk_button_new_with_mnemonic(_("Brows_e..."));
722 dialog
->play_sound_entry
= gtk_entry_new();
723 gtk_entry_set_text(GTK_ENTRY(dialog
->play_sound_entry
), _("(default)"));
724 gtk_editable_set_editable(GTK_EDITABLE(dialog
->play_sound_entry
), FALSE
);
725 dialog
->play_sound_browse
= gtk_button_new_with_mnemonic(_("Br_owse..."));
726 dialog
->play_sound_test
= gtk_button_new_with_mnemonic(_("Pre_view"));
727 dialog
->play_sound_reset
= gtk_button_new_with_mnemonic(_("Reset"));
729 gtk_widget_set_sensitive(editor
, FALSE
);
730 gtk_widget_set_sensitive(dialog
->exec_cmd_entry
, FALSE
);
731 gtk_widget_set_sensitive(dialog
->popup_entry
, FALSE
);
732 gtk_widget_set_sensitive(dialog
->exec_cmd_browse
, FALSE
);
733 gtk_widget_set_sensitive(dialog
->play_sound_entry
, FALSE
);
734 gtk_widget_set_sensitive(dialog
->play_sound_browse
, FALSE
);
735 gtk_widget_set_sensitive(dialog
->play_sound_test
, FALSE
);
736 gtk_widget_set_sensitive(dialog
->play_sound_reset
, FALSE
);
740 sg
= gtk_size_group_new(GTK_SIZE_GROUP_VERTICAL
);
741 gtk_size_group_add_widget(sg
, dialog
->open_win
);
742 gtk_size_group_add_widget(sg
, dialog
->popup
);
743 gtk_size_group_add_widget(sg
, dialog
->popup_entry
);
744 gtk_size_group_add_widget(sg
, dialog
->exec_cmd
);
745 gtk_size_group_add_widget(sg
, dialog
->exec_cmd_entry
);
746 gtk_size_group_add_widget(sg
, dialog
->exec_cmd_browse
);
747 gtk_size_group_add_widget(sg
, dialog
->play_sound
);
748 gtk_size_group_add_widget(sg
, dialog
->play_sound_entry
);
749 gtk_size_group_add_widget(sg
, dialog
->play_sound_browse
);
750 gtk_size_group_add_widget(sg
, dialog
->play_sound_test
);
751 gtk_size_group_add_widget(sg
, dialog
->play_sound_reset
);
756 gtk_widget_set_valign(dialog
->open_win
, GTK_ALIGN_CENTER
);
757 gtk_widget_set_valign(dialog
->popup
, GTK_ALIGN_CENTER
);
758 gtk_widget_set_valign(dialog
->popup_entry
, GTK_ALIGN_CENTER
);
759 gtk_widget_set_valign(dialog
->send_msg
, GTK_ALIGN_CENTER
);
760 gtk_widget_set_valign(editor
, GTK_ALIGN_CENTER
);
761 gtk_widget_set_valign(dialog
->exec_cmd
, GTK_ALIGN_CENTER
);
762 gtk_widget_set_valign(dialog
->exec_cmd_entry
, GTK_ALIGN_CENTER
);
763 gtk_widget_set_hexpand(dialog
->exec_cmd_browse
, TRUE
);
764 gtk_widget_set_valign(dialog
->exec_cmd_browse
, GTK_ALIGN_CENTER
);
765 gtk_widget_set_valign(dialog
->play_sound
, GTK_ALIGN_CENTER
);
766 gtk_widget_set_valign(dialog
->play_sound_entry
, GTK_ALIGN_CENTER
);
767 gtk_widget_set_hexpand(dialog
->play_sound_browse
, TRUE
);
768 gtk_widget_set_valign(dialog
->play_sound_browse
, GTK_ALIGN_CENTER
);
769 gtk_widget_set_hexpand(dialog
->play_sound_test
, TRUE
);
770 gtk_widget_set_valign(dialog
->play_sound_test
, GTK_ALIGN_CENTER
);
771 gtk_widget_set_hexpand(dialog
->play_sound_reset
, TRUE
);
772 gtk_widget_set_valign(dialog
->play_sound_reset
, GTK_ALIGN_CENTER
);
774 gtk_grid_attach(GTK_GRID(grid
), dialog
->open_win
, 0, 0, 1, 1);
775 gtk_grid_attach(GTK_GRID(grid
), dialog
->popup
, 0, 1, 1, 1);
776 gtk_grid_attach(GTK_GRID(grid
), dialog
->popup_entry
, 1, 1, 4, 1);
777 gtk_grid_attach(GTK_GRID(grid
), dialog
->send_msg
, 0, 2, 5, 1);
778 gtk_grid_attach(GTK_GRID(grid
), editor
, 0, 3, 5, 1);
779 gtk_grid_attach(GTK_GRID(grid
), dialog
->exec_cmd
, 0, 4, 1, 1);
780 gtk_grid_attach(GTK_GRID(grid
), dialog
->exec_cmd_entry
, 1, 4, 1, 1);
781 gtk_grid_attach(GTK_GRID(grid
), dialog
->exec_cmd_browse
, 2, 4, 1, 1);
782 gtk_grid_attach(GTK_GRID(grid
), dialog
->play_sound
, 0, 5, 1, 1);
783 gtk_grid_attach(GTK_GRID(grid
), dialog
->play_sound_entry
, 1, 5, 1, 1);
784 gtk_grid_attach(GTK_GRID(grid
), dialog
->play_sound_browse
,2, 5, 1, 1);
785 gtk_grid_attach(GTK_GRID(grid
), dialog
->play_sound_test
, 3, 5, 1, 1);
786 gtk_grid_attach(GTK_GRID(grid
), dialog
->play_sound_reset
, 4, 5, 1, 1);
788 gtk_grid_set_row_spacing(GTK_GRID(grid
), PIDGIN_HIG_BOX_SPACE
/ 2);
790 gtk_widget_show(dialog
->open_win
);
791 gtk_widget_show(dialog
->popup
);
792 gtk_widget_show(dialog
->popup_entry
);
793 gtk_widget_show(dialog
->send_msg
);
794 gtk_widget_show(editor
);
795 gtk_widget_show(dialog
->exec_cmd
);
796 gtk_widget_show(dialog
->exec_cmd_entry
);
797 gtk_widget_show(dialog
->exec_cmd_browse
);
798 gtk_widget_show(dialog
->play_sound
);
799 gtk_widget_show(dialog
->play_sound_entry
);
800 gtk_widget_show(dialog
->play_sound_browse
);
801 gtk_widget_show(dialog
->play_sound_test
);
802 gtk_widget_show(dialog
->play_sound_reset
);
804 g_signal_connect(G_OBJECT(dialog
->message_recv
), "clicked",
805 G_CALLBACK(message_recv_toggle
),
808 g_object_bind_property(dialog
->send_msg
, "active",
812 g_object_bind_property(dialog
->popup
, "active",
813 dialog
->popup_entry
, "sensitive",
816 g_object_bind_property(dialog
->exec_cmd
, "active",
817 dialog
->exec_cmd_entry
, "sensitive",
819 g_object_bind_property(dialog
->exec_cmd
, "active",
820 dialog
->exec_cmd_browse
, "sensitive",
822 g_signal_connect(G_OBJECT(dialog
->exec_cmd_browse
), "clicked",
824 dialog
->exec_cmd_entry
);
826 g_object_bind_property(dialog
->play_sound
, "active",
827 dialog
->play_sound_entry
, "sensitive",
829 g_object_bind_property(dialog
->play_sound
, "active",
830 dialog
->play_sound_browse
, "sensitive",
832 g_object_bind_property(dialog
->play_sound
, "active",
833 dialog
->play_sound_test
, "sensitive",
835 g_object_bind_property(dialog
->play_sound
, "active",
836 dialog
->play_sound_reset
, "sensitive",
839 g_signal_connect(G_OBJECT(dialog
->play_sound_browse
), "clicked",
841 dialog
->play_sound_entry
);
842 g_signal_connect(G_OBJECT(dialog
->play_sound_test
), "clicked",
843 G_CALLBACK(pounce_test_sound
),
844 dialog
->play_sound_entry
);
845 g_signal_connect(G_OBJECT(dialog
->play_sound_reset
), "clicked",
846 G_CALLBACK(pounce_reset_sound
),
847 dialog
->play_sound_entry
);
849 g_signal_connect_swapped(G_OBJECT(dialog
->send_msg_entry
), "format-cleared",
850 G_CALLBACK(reset_send_msg_entry
), dialog
);
851 g_signal_connect_swapped(G_OBJECT(dialog
->account_menu
), "changed",
852 G_CALLBACK(reset_send_msg_entry
), dialog
);
854 g_signal_connect(G_OBJECT(dialog
->send_msg_entry
), "key-press-event",
855 G_CALLBACK(entry_key_press_cb
), dialog
);
856 g_signal_connect(G_OBJECT(dialog
->popup_entry
), "activate",
857 G_CALLBACK(save_pounce_cb
), dialog
);
858 g_signal_connect(G_OBJECT(dialog
->exec_cmd_entry
), "activate",
859 G_CALLBACK(save_pounce_cb
), dialog
);
861 /* Create the "Options" frame. */
862 frame
= pidgin_make_frame(vbox2
, _("Options"));
864 grid
= gtk_grid_new();
865 gtk_container_add(GTK_CONTAINER(frame
), grid
);
866 gtk_grid_set_column_spacing(GTK_GRID(grid
), PIDGIN_HIG_BORDER
);
867 gtk_widget_show(grid
);
870 gtk_check_button_new_with_mnemonic(_("P_ounce only when my status is not Available"));
871 gtk_widget_set_valign(dialog
->on_away
, GTK_ALIGN_CENTER
);
872 gtk_grid_attach(GTK_GRID(grid
), dialog
->on_away
, 0, 0, 1, 1);
874 dialog
->save_pounce
= gtk_check_button_new_with_mnemonic(
876 gtk_widget_set_valign(dialog
->save_pounce
, GTK_ALIGN_CENTER
);
877 gtk_grid_attach(GTK_GRID(grid
), dialog
->save_pounce
, 0, 1, 1, 1);
879 gtk_widget_show(dialog
->on_away
);
880 gtk_widget_show(dialog
->save_pounce
);
883 button
= gtk_dialog_add_button(GTK_DIALOG(window
), GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
);
884 g_signal_connect(G_OBJECT(button
), "clicked",
885 G_CALLBACK(cancel_cb
), dialog
);
887 /* Save/Add button */
888 dialog
->save_button
= button
= gtk_dialog_add_button(GTK_DIALOG(window
),
889 (cur_pounce
== NULL
? GTK_STOCK_ADD
: GTK_STOCK_SAVE
),
891 g_signal_connect(G_OBJECT(button
), "clicked",
892 G_CALLBACK(save_pounce_cb
), dialog
);
894 if (*gtk_entry_get_text(GTK_ENTRY(dialog
->buddy_entry
)) == '\0')
895 gtk_widget_set_sensitive(button
, FALSE
);
897 /* Setup drag-and-drop */
898 gtk_drag_dest_set(window
,
899 GTK_DEST_DEFAULT_MOTION
|
900 GTK_DEST_DEFAULT_DROP
,
902 sizeof(dnd_targets
) / sizeof(GtkTargetEntry
),
904 gtk_drag_dest_set(dialog
->buddy_entry
,
905 GTK_DEST_DEFAULT_MOTION
|
906 GTK_DEST_DEFAULT_DROP
,
908 sizeof(dnd_targets
) / sizeof(GtkTargetEntry
),
911 g_signal_connect(G_OBJECT(window
), "drag_data_received",
912 G_CALLBACK(pounce_dnd_recv
), dialog
);
913 g_signal_connect(G_OBJECT(dialog
->buddy_entry
), "drag_data_received",
914 G_CALLBACK(pounce_dnd_recv
), dialog
);
916 /* Set the values of stuff. */
917 if (cur_pounce
!= NULL
)
919 PurplePounceEvent events
= purple_pounce_get_events(cur_pounce
);
920 PurplePounceOption options
= purple_pounce_get_options(cur_pounce
);
924 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog
->on_away
),
925 (options
& PURPLE_POUNCE_OPTION_AWAY
));
928 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog
->signon
),
929 (events
& PURPLE_POUNCE_SIGNON
));
930 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog
->signoff
),
931 (events
& PURPLE_POUNCE_SIGNOFF
));
932 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog
->away
),
933 (events
& PURPLE_POUNCE_AWAY
));
934 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog
->away_return
),
935 (events
& PURPLE_POUNCE_AWAY_RETURN
));
936 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog
->idle
),
937 (events
& PURPLE_POUNCE_IDLE
));
938 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog
->idle_return
),
939 (events
& PURPLE_POUNCE_IDLE_RETURN
));
940 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog
->typing
),
941 (events
& PURPLE_POUNCE_TYPING
));
942 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog
->typed
),
943 (events
& PURPLE_POUNCE_TYPED
));
944 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog
->stop_typing
),
945 (events
& PURPLE_POUNCE_TYPING_STOPPED
));
946 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog
->message_recv
),
947 (events
& PURPLE_POUNCE_MESSAGE_RECEIVED
));
950 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog
->open_win
),
951 purple_pounce_action_is_enabled(cur_pounce
, "open-window"));
952 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog
->popup
),
953 purple_pounce_action_is_enabled(cur_pounce
, "popup-notify"));
954 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog
->send_msg
),
955 purple_pounce_action_is_enabled(cur_pounce
, "send-message"));
956 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog
->exec_cmd
),
957 purple_pounce_action_is_enabled(cur_pounce
, "execute-command"));
958 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog
->play_sound
),
959 purple_pounce_action_is_enabled(cur_pounce
, "play-sound"));
961 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog
->save_pounce
),
962 purple_pounce_get_save(cur_pounce
));
964 if ((value
= purple_pounce_action_get_attribute(cur_pounce
,
968 talkatu_markup_set_html(TALKATU_BUFFER(dialog
->send_msg_buffer
), value
, -1);
971 if ((value
= purple_pounce_action_get_attribute(cur_pounce
,
975 gtk_entry_set_text(GTK_ENTRY(dialog
->popup_entry
), value
);
978 if ((value
= purple_pounce_action_get_attribute(cur_pounce
,
982 gtk_entry_set_text(GTK_ENTRY(dialog
->exec_cmd_entry
), value
);
985 if ((value
= purple_pounce_action_get_attribute(cur_pounce
,
987 "filename")) != NULL
)
989 gtk_entry_set_text(GTK_ENTRY(dialog
->play_sound_entry
),
990 (*value
!= '\0') ? value
: _("(default)"));
995 PurpleBuddy
*buddy
= NULL
;
998 buddy
= purple_blist_find_buddy(account
, name
);
1000 /* Set some defaults */
1003 gtk_toggle_button_set_active(
1004 GTK_TOGGLE_BUTTON(dialog
->signon
), TRUE
);
1008 if (!PURPLE_BUDDY_IS_ONLINE(buddy
))
1010 gtk_toggle_button_set_active(
1011 GTK_TOGGLE_BUTTON(dialog
->signon
), TRUE
);
1015 gboolean default_set
= FALSE
;
1016 PurplePresence
*presence
= purple_buddy_get_presence(buddy
);
1018 if (purple_presence_is_idle(presence
))
1020 gtk_toggle_button_set_active(
1021 GTK_TOGGLE_BUTTON(dialog
->idle_return
), TRUE
);
1026 if (!purple_presence_is_available(presence
))
1028 gtk_toggle_button_set_active(
1029 GTK_TOGGLE_BUTTON(dialog
->away_return
), TRUE
);
1036 gtk_toggle_button_set_active(
1037 GTK_TOGGLE_BUTTON(dialog
->signon
), TRUE
);
1042 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog
->open_win
),
1043 purple_prefs_get_bool(PIDGIN_PREFS_ROOT
"/pounces/default_actions/open-window"));
1044 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog
->popup
),
1045 purple_prefs_get_bool(PIDGIN_PREFS_ROOT
"/pounces/default_actions/popup-notify"));
1046 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog
->send_msg
),
1047 purple_prefs_get_bool(PIDGIN_PREFS_ROOT
"/pounces/default_actions/send-message"));
1048 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog
->exec_cmd
),
1049 purple_prefs_get_bool(PIDGIN_PREFS_ROOT
"/pounces/default_actions/execute-command"));
1050 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog
->play_sound
),
1051 purple_prefs_get_bool(PIDGIN_PREFS_ROOT
"/pounces/default_actions/play-sound"));
1054 gtk_widget_show(vbox2
);
1055 gtk_widget_show(window
);
1059 pounces_manager_configure_cb(GtkWidget
*widget
, GdkEventConfigure
*event
, PouncesManager
*dialog
)
1061 if (gtk_widget_get_visible(widget
)) {
1062 purple_prefs_set_int(PIDGIN_PREFS_ROOT
"/pounces/dialog/width", event
->width
);
1063 purple_prefs_set_int(PIDGIN_PREFS_ROOT
"/pounces/dialog/height", event
->height
);
1070 pounces_manager_find_pounce(GtkTreeIter
*iter
, PurplePounce
*pounce
)
1072 GtkTreeModel
*model
= GTK_TREE_MODEL(pounces_manager
->model
);
1075 if (!gtk_tree_model_get_iter_first(model
, iter
))
1078 gtk_tree_model_get(model
, iter
, POUNCES_MANAGER_COLUMN_POUNCE
, &p
, -1);
1082 while (gtk_tree_model_iter_next(model
, iter
))
1084 gtk_tree_model_get(model
, iter
, POUNCES_MANAGER_COLUMN_POUNCE
, &p
, -1);
1093 pounces_manager_destroy_cb(GtkWidget
*widget
, GdkEvent
*event
, gpointer user_data
)
1095 PouncesManager
*dialog
= user_data
;
1097 dialog
->window
= NULL
;
1098 pidgin_pounces_manager_hide();
1104 pounces_manager_connection_cb(PurpleConnection
*gc
, GtkWidget
*add_button
)
1106 gtk_widget_set_sensitive(add_button
, (purple_connections_get_all() != NULL
));
1110 pounces_manager_add_cb(GtkButton
*button
, gpointer user_data
)
1112 pidgin_pounce_editor_show(NULL
, NULL
, NULL
);
1116 pounces_manager_modify_foreach(GtkTreeModel
*model
, GtkTreePath
*path
,
1117 GtkTreeIter
*iter
, gpointer user_data
)
1119 PurplePounce
*pounce
;
1121 gtk_tree_model_get(model
, iter
, POUNCES_MANAGER_COLUMN_POUNCE
, &pounce
, -1);
1122 pidgin_pounce_editor_show(NULL
, NULL
, pounce
);
1126 pounces_manager_modify_cb(GtkButton
*button
, gpointer user_data
)
1128 PouncesManager
*dialog
= user_data
;
1129 GtkTreeSelection
*selection
;
1131 selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog
->treeview
));
1133 gtk_tree_selection_selected_foreach(selection
, pounces_manager_modify_foreach
, user_data
);
1137 pounces_manager_delete_confirm_cb(PurplePounce
*pounce
)
1141 if (pounces_manager
&& pounces_manager_find_pounce(&iter
, pounce
))
1142 gtk_list_store_remove(pounces_manager
->model
, &iter
);
1144 purple_request_close_with_handle(pounce
);
1145 purple_pounce_destroy(pounce
);
1149 pounces_manager_delete_foreach(GtkTreeModel
*model
, GtkTreePath
*path
,
1150 GtkTreeIter
*iter
, gpointer user_data
)
1152 PurplePounce
*pounce
;
1153 PurpleAccount
*account
;
1154 const char *pouncer
, *pouncee
;
1157 gtk_tree_model_get(model
, iter
, POUNCES_MANAGER_COLUMN_POUNCE
, &pounce
, -1);
1158 account
= purple_pounce_get_pouncer(pounce
);
1159 pouncer
= purple_account_get_username(account
);
1160 pouncee
= purple_pounce_get_pouncee(pounce
);
1162 buf
= g_strdup_printf(_("Are you sure you want to delete the pounce on %s for %s?"), pouncee
, pouncer
);
1163 purple_request_action(pounce
, NULL
, buf
, NULL
, 0,
1164 purple_request_cpar_from_account(account
),
1165 pounce
, 2, _("Delete"), pounces_manager_delete_confirm_cb
,
1171 pounces_manager_delete_cb(GtkButton
*button
, gpointer user_data
)
1173 PouncesManager
*dialog
= user_data
;
1174 GtkTreeSelection
*selection
;
1176 selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog
->treeview
));
1178 gtk_tree_selection_selected_foreach(selection
, pounces_manager_delete_foreach
, user_data
);
1182 pounces_manager_close_cb(GtkButton
*button
, gpointer user_data
)
1184 pidgin_pounces_manager_hide();
1188 pounce_selected_cb(GtkTreeSelection
*sel
, gpointer user_data
)
1190 PouncesManager
*dialog
= user_data
;
1191 int num_selected
= 0;
1193 num_selected
= gtk_tree_selection_count_selected_rows(sel
);
1195 gtk_widget_set_sensitive(dialog
->modify_button
, (num_selected
> 0));
1196 gtk_widget_set_sensitive(dialog
->delete_button
, (num_selected
> 0));
1200 pounce_double_click_cb(GtkTreeView
*treeview
, GdkEventButton
*event
, gpointer user_data
)
1202 PouncesManager
*dialog
= user_data
;
1205 PurplePounce
*pounce
;
1207 /* Figure out which node was clicked */
1208 if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(dialog
->treeview
), event
->x
, event
->y
, &path
, NULL
, NULL
, NULL
))
1210 gtk_tree_model_get_iter(GTK_TREE_MODEL(dialog
->model
), &iter
, path
);
1211 gtk_tree_path_free(path
);
1212 gtk_tree_model_get(GTK_TREE_MODEL(dialog
->model
), &iter
, POUNCES_MANAGER_COLUMN_POUNCE
, &pounce
, -1);
1214 if ((pounce
!= NULL
) && (event
->button
== GDK_BUTTON_PRIMARY
) &&
1215 (event
->type
== GDK_2BUTTON_PRESS
))
1217 pidgin_pounce_editor_show(NULL
, NULL
, pounce
);
1225 pounces_manager_recurring_cb(GtkCellRendererToggle
*renderer
, gchar
*path_str
,
1228 PouncesManager
*dialog
= user_data
;
1229 PurplePounce
*pounce
;
1231 GtkTreeModel
*model
= GTK_TREE_MODEL(dialog
->model
);
1234 gtk_tree_model_get_iter_from_string(model
, &iter
, path_str
);
1235 gtk_tree_model_get(model
, &iter
,
1236 POUNCES_MANAGER_COLUMN_POUNCE
, &pounce
,
1237 POUNCES_MANAGER_COLUMN_RECURRING
, &recurring
,
1240 purple_pounce_set_save(pounce
, !recurring
);
1246 search_func(GtkTreeModel
*model
, gint column
, const gchar
*key
, GtkTreeIter
*iter
, gpointer search_data
)
1251 gtk_tree_model_get(model
, iter
, column
, &haystack
, -1);
1253 result
= (purple_strcasestr(haystack
, key
) == NULL
);
1261 create_pounces_list(PouncesManager
*dialog
)
1263 GtkWidget
*treeview
;
1264 GtkTreeSelection
*sel
;
1265 GtkTreeViewColumn
*column
;
1266 GtkCellRenderer
*renderer
;
1268 /* Create the list model */
1269 dialog
->model
= gtk_list_store_new(POUNCES_MANAGER_NUM_COLUMNS
,
1277 /* Create the treeview */
1278 treeview
= gtk_tree_view_new_with_model(GTK_TREE_MODEL(dialog
->model
));
1279 g_object_unref(G_OBJECT(dialog
->model
));
1280 dialog
->treeview
= treeview
;
1282 sel
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview
));
1283 gtk_tree_selection_set_mode(sel
, GTK_SELECTION_MULTIPLE
);
1284 g_signal_connect(G_OBJECT(sel
), "changed",
1285 G_CALLBACK(pounce_selected_cb
), dialog
);
1287 /* Handle double-clicking */
1288 g_signal_connect(G_OBJECT(treeview
), "button_press_event",
1289 G_CALLBACK(pounce_double_click_cb
), dialog
);
1290 gtk_widget_show(treeview
);
1292 /* Pouncee Column */
1293 column
= gtk_tree_view_column_new();
1294 gtk_tree_view_column_set_title(column
, _("Pounce Target"));
1295 gtk_tree_view_column_set_resizable(column
, TRUE
);
1296 gtk_tree_view_column_set_min_width(column
, 200);
1297 gtk_tree_view_column_set_sort_column_id(column
,
1298 POUNCES_MANAGER_COLUMN_TARGET
);
1299 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview
), column
);
1302 renderer
= gtk_cell_renderer_pixbuf_new();
1303 gtk_tree_view_column_pack_start(column
, renderer
, FALSE
);
1304 gtk_tree_view_column_add_attribute(column
, renderer
, "pixbuf",
1305 POUNCES_MANAGER_COLUMN_ICON
);
1308 renderer
= gtk_cell_renderer_text_new();
1309 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
1310 gtk_tree_view_column_add_attribute(column
, renderer
, "text",
1311 POUNCES_MANAGER_COLUMN_TARGET
);
1314 /* Account Column */
1315 column
= gtk_tree_view_column_new();
1316 gtk_tree_view_column_set_title(column
, _("Account"));
1317 gtk_tree_view_column_set_resizable(column
, TRUE
);
1318 gtk_tree_view_column_set_min_width(column
, 200);
1319 gtk_tree_view_column_set_sort_column_id(column
,
1320 POUNCES_MANAGER_COLUMN_ACCOUNT
);
1321 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview
), column
);
1322 renderer
= gtk_cell_renderer_text_new();
1323 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
1324 gtk_tree_view_column_add_attribute(column
, renderer
, "text",
1325 POUNCES_MANAGER_COLUMN_ACCOUNT
);
1327 /* Recurring Column */
1328 renderer
= gtk_cell_renderer_toggle_new();
1329 column
= gtk_tree_view_column_new_with_attributes(_("Recurring"), renderer
,
1330 "active", POUNCES_MANAGER_COLUMN_RECURRING
, NULL
);
1331 gtk_tree_view_column_set_sort_column_id(column
,
1332 POUNCES_MANAGER_COLUMN_RECURRING
);
1333 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview
), column
);
1334 g_signal_connect(G_OBJECT(renderer
), "toggled",
1335 G_CALLBACK(pounces_manager_recurring_cb
), dialog
);
1337 /* Enable CTRL+F searching */
1338 gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeview
), POUNCES_MANAGER_COLUMN_TARGET
);
1339 gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(treeview
), search_func
, NULL
, NULL
);
1341 /* Sort the pouncee column by default */
1342 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(dialog
->model
),
1343 POUNCES_MANAGER_COLUMN_TARGET
,
1344 GTK_SORT_ASCENDING
);
1347 populate_pounces_list(dialog
);
1349 return pidgin_make_scrollable(treeview
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
, GTK_SHADOW_IN
, -1, -1);
1353 pidgin_pounces_manager_show(void)
1355 PouncesManager
*dialog
;
1362 if (pounces_manager
!= NULL
) {
1363 gtk_window_present(GTK_WINDOW(pounces_manager
->window
));
1367 pounces_manager
= dialog
= g_new0(PouncesManager
, 1);
1369 width
= purple_prefs_get_int(PIDGIN_PREFS_ROOT
"/pounces/dialog/width");
1370 height
= purple_prefs_get_int(PIDGIN_PREFS_ROOT
"/pounces/dialog/height");
1372 dialog
->window
= win
= pidgin_create_dialog(_("Buddy Pounces"), 0, "pounces", TRUE
);
1374 gtk_window_set_default_size(GTK_WINDOW(win
), width
, height
);
1376 g_signal_connect(G_OBJECT(win
), "delete_event",
1377 G_CALLBACK(pounces_manager_destroy_cb
), dialog
);
1378 g_signal_connect(G_OBJECT(win
), "configure_event",
1379 G_CALLBACK(pounces_manager_configure_cb
), dialog
);
1381 /* Setup the vbox */
1382 vbox
= pidgin_dialog_get_vbox_with_properties(GTK_DIALOG(win
), FALSE
, PIDGIN_HIG_BORDER
);
1384 /* List of saved buddy pounces */
1385 list
= create_pounces_list(dialog
);
1386 gtk_box_pack_start(GTK_BOX(vbox
), list
, TRUE
, TRUE
, 0);
1389 button
= pidgin_dialog_add_button(GTK_DIALOG(win
), PIDGIN_STOCK_ADD
, G_CALLBACK(pounces_manager_add_cb
), dialog
);
1390 gtk_widget_set_sensitive(button
, (purple_accounts_get_all() != NULL
));
1392 purple_signal_connect(purple_connections_get_handle(), "signed-on",
1393 pounces_manager
, PURPLE_CALLBACK(pounces_manager_connection_cb
), button
);
1394 purple_signal_connect(purple_connections_get_handle(), "signed-off",
1395 pounces_manager
, PURPLE_CALLBACK(pounces_manager_connection_cb
), button
);
1398 button
= pidgin_dialog_add_button(GTK_DIALOG(win
), PIDGIN_STOCK_MODIFY
, G_CALLBACK(pounces_manager_modify_cb
), dialog
);
1399 gtk_widget_set_sensitive(button
, FALSE
);
1400 dialog
->modify_button
= button
;
1403 button
= pidgin_dialog_add_button(GTK_DIALOG(win
), GTK_STOCK_DELETE
, G_CALLBACK(pounces_manager_delete_cb
), dialog
);
1404 gtk_widget_set_sensitive(button
, FALSE
);
1405 dialog
->delete_button
= button
;
1408 pidgin_dialog_add_button(GTK_DIALOG(win
), GTK_STOCK_CLOSE
, G_CALLBACK(pounces_manager_close_cb
), dialog
);
1410 gtk_widget_show(win
);
1414 pidgin_pounces_manager_hide(void)
1416 if (pounces_manager
== NULL
)
1419 if (pounces_manager
->window
!= NULL
)
1420 gtk_widget_destroy(pounces_manager
->window
);
1422 purple_signals_disconnect_by_handle(pounces_manager
);
1424 g_free(pounces_manager
);
1425 pounces_manager
= NULL
;
1429 pounce_cb(PurplePounce
*pounce
, PurplePounceEvent events
, void *data
)
1431 PurpleIMConversation
*im
;
1432 PurpleAccount
*account
;
1434 const char *pouncee
;
1437 pouncee
= purple_pounce_get_pouncee(pounce
);
1438 account
= purple_pounce_get_pouncer(pounce
);
1440 buddy
= purple_blist_find_buddy(account
, pouncee
);
1443 alias
= purple_buddy_get_alias(buddy
);
1450 if (purple_pounce_action_is_enabled(pounce
, "open-window"))
1452 if (!purple_conversations_find_im_with_account(pouncee
, account
))
1453 purple_im_conversation_new(account
, pouncee
);
1456 if (purple_pounce_action_is_enabled(pounce
, "popup-notify"))
1460 reason
= purple_pounce_action_get_attribute(pounce
, "popup-notify",
1464 * Here we place the protocol name in the pounce dialog to lessen
1465 * confusion about what protocol a pounce is for.
1468 (events
& PURPLE_POUNCE_TYPING
) ?
1469 _("Started typing") :
1470 (events
& PURPLE_POUNCE_TYPED
) ?
1471 _("Paused while typing") :
1472 (events
& PURPLE_POUNCE_SIGNON
) ?
1474 (events
& PURPLE_POUNCE_IDLE_RETURN
) ?
1475 _("Returned from being idle") :
1476 (events
& PURPLE_POUNCE_AWAY_RETURN
) ?
1477 _("Returned from being away") :
1478 (events
& PURPLE_POUNCE_TYPING_STOPPED
) ?
1479 _("Stopped typing") :
1480 (events
& PURPLE_POUNCE_SIGNOFF
) ?
1482 (events
& PURPLE_POUNCE_IDLE
) ?
1484 (events
& PURPLE_POUNCE_AWAY
) ?
1486 (events
& PURPLE_POUNCE_MESSAGE_RECEIVED
) ?
1487 _("Sent a message") :
1488 _("Unknown.... Please report this!")
1491 pidgin_notify_pounce_add(account
, pounce
, alias
, tmp
, reason
,
1492 purple_date_format_full(NULL
));
1497 if (purple_pounce_action_is_enabled(pounce
, "send-message"))
1499 const char *message
;
1501 message
= purple_pounce_action_get_attribute(pounce
, "send-message",
1504 if (message
!= NULL
)
1506 PurpleMessage
*pmsg
;
1508 im
= purple_conversations_find_im_with_account(pouncee
, account
);
1511 im
= purple_im_conversation_new(account
, pouncee
);
1513 pmsg
= purple_message_new_outgoing(pouncee
, message
, 0);
1514 purple_serv_send_im(purple_account_get_connection(account
), pmsg
);
1515 purple_conversation_write_message(PURPLE_CONVERSATION(im
), pmsg
);
1519 if (purple_pounce_action_is_enabled(pounce
, "execute-command"))
1521 const char *command
;
1523 command
= purple_pounce_action_get_attribute(pounce
,
1524 "execute-command", "command");
1526 if (command
!= NULL
)
1528 GError
*error
= NULL
;
1529 if (!g_spawn_command_line_async(command
, &error
)) {
1530 purple_debug_error("gtkpounce",
1531 "pounce command could not be launched: %s\n",
1533 g_error_free(error
);
1538 if (purple_pounce_action_is_enabled(pounce
, "play-sound"))
1542 sound
= purple_pounce_action_get_attribute(pounce
,
1543 "play-sound", "filename");
1546 purple_sound_play_file(sound
, account
);
1548 purple_sound_play_event(PURPLE_SOUND_POUNCE_DEFAULT
, account
);
1553 free_pounce(PurplePounce
*pounce
)
1559 new_pounce(PurplePounce
*pounce
)
1561 purple_pounce_action_register(pounce
, "open-window");
1562 purple_pounce_action_register(pounce
, "popup-notify");
1563 purple_pounce_action_register(pounce
, "send-message");
1564 purple_pounce_action_register(pounce
, "execute-command");
1565 purple_pounce_action_register(pounce
, "play-sound");
1571 pidgin_pounces_get_handle() {
1578 pidgin_pounces_init(void)
1580 purple_pounces_register_handler(PIDGIN_UI
, pounce_cb
, new_pounce
,
1583 purple_prefs_add_none(PIDGIN_PREFS_ROOT
"/pounces");
1584 purple_prefs_add_none(PIDGIN_PREFS_ROOT
"/pounces/default_actions");
1585 purple_prefs_add_bool(PIDGIN_PREFS_ROOT
"/pounces/default_actions/open-window",
1587 purple_prefs_add_bool(PIDGIN_PREFS_ROOT
"/pounces/default_actions/popup-notify",
1589 purple_prefs_add_bool(PIDGIN_PREFS_ROOT
"/pounces/default_actions/send-message",
1591 purple_prefs_add_bool(PIDGIN_PREFS_ROOT
"/pounces/default_actions/execute-command",
1593 purple_prefs_add_bool(PIDGIN_PREFS_ROOT
"/pounces/default_actions/play-sound",
1595 purple_prefs_add_none(PIDGIN_PREFS_ROOT
"/pounces/dialog");
1596 purple_prefs_add_int(PIDGIN_PREFS_ROOT
"/pounces/dialog/width", 520);
1597 purple_prefs_add_int(PIDGIN_PREFS_ROOT
"/pounces/dialog/height", 321);
1599 purple_signal_connect(purple_connections_get_handle(), "signed-on",
1600 pidgin_pounces_get_handle(),
1601 PURPLE_CALLBACK(signed_on_off_cb
), NULL
);
1602 purple_signal_connect(purple_connections_get_handle(), "signed-off",
1603 pidgin_pounces_get_handle(),
1604 PURPLE_CALLBACK(signed_on_off_cb
), NULL
);