1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Copyright (C) 2005-2007 Imendio AB
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public
16 * License along with this program; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
20 * Authors: Richard Hult <richard@imendio.com>
21 * Martyn Russell <martyn@imendio.com>
29 #include <glib/gi18n.h>
31 #include <glade/glade.h>
33 #include <libtelepathy/tp-helpers.h>
34 #include <libmissioncontrol/mission-control.h>
36 #include <libempathy/gossip-utils.h>
37 #include <libempathy/gossip-debug.h>
38 #include <libempathy/empathy-marshal.h>
40 #include "gossip-ui-utils.h"
41 #include "empathy-images.h"
42 #include "gossip-presence-chooser.h"
43 #include "gossip-status-presets.h"
45 #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GOSSIP_TYPE_PRESENCE_CHOOSER, GossipPresenceChooserPriv))
47 #define DEBUG_DOMAIN "PresenceChooser"
49 /* Flashing delay for icons (milliseconds). */
50 #define FLASH_TIMEOUT 500
60 McPresence last_state;
62 McPresence flash_state_1;
63 McPresence flash_state_2;
64 guint flash_timeout_id;
66 /* The handle the kind of unnessecary scroll support. */
67 guint scroll_timeout_id;
68 McPresence scroll_state;
70 } GossipPresenceChooserPriv;
77 /* States to be listed in the menu */
78 static McPresence states[] = {MC_PRESENCE_AVAILABLE,
79 MC_PRESENCE_DO_NOT_DISTURB,
82 static void gossip_presence_chooser_class_init (GossipPresenceChooserClass *klass);
83 static void gossip_presence_chooser_init (GossipPresenceChooser *chooser);
84 static void presence_chooser_finalize (GObject *object);
85 static void presence_chooser_presence_changed_cb (MissionControl *mc,
87 GossipPresenceChooser *chooser);
88 static void presence_chooser_reset_scroll_timeout (GossipPresenceChooser *chooser);
89 static gboolean presence_chooser_scroll_timeout_cb (GossipPresenceChooser *chooser);
90 static gboolean presence_chooser_scroll_event_cb (GossipPresenceChooser *chooser,
91 GdkEventScroll *event,
93 static GList * presence_chooser_get_presets (GossipPresenceChooser *chooser);
94 static StateAndStatus *presence_chooser_state_and_status_new (McPresence state,
96 static gboolean presence_chooser_flash_timeout_cb (GossipPresenceChooser *chooser);
97 void gossip_presence_chooser_flash_start (GossipPresenceChooser *chooser,
100 void gossip_presence_chooser_flash_stop (GossipPresenceChooser *chooser,
102 gboolean gossip_presence_chooser_is_flashing (GossipPresenceChooser *chooser);
103 static gboolean presence_chooser_button_press_event_cb (GtkWidget *chooser,
104 GdkEventButton *event,
106 static void presence_chooser_toggled_cb (GtkWidget *chooser,
108 static void presence_chooser_menu_popup (GossipPresenceChooser *chooser);
109 static void presence_chooser_menu_popdown (GossipPresenceChooser *chooser);
110 static void presence_chooser_menu_selection_done_cb (GtkMenuShell *menushell,
111 GossipPresenceChooser *chooser);
112 static void presence_chooser_menu_destroy_cb (GtkWidget *menu,
113 GossipPresenceChooser *chooser);
114 static void presence_chooser_menu_detach (GtkWidget *attach_widget,
116 static void presence_chooser_menu_align_func (GtkMenu *menu,
121 static void presence_chooser_menu_add_item (GtkWidget *menu,
125 static void presence_chooser_clear_activate_cb (GtkWidget *item,
127 static void presence_chooser_clear_response_cb (GtkWidget *widget,
130 static void presence_chooser_noncustom_activate_cb (GtkWidget *item,
132 static void presence_chooser_set_state (McPresence state,
135 static void presence_chooser_custom_activate_cb (GtkWidget *item,
137 static void presence_chooser_show_dialog (McPresence state);
138 static void presence_chooser_dialog_response_cb (GtkWidget *dialog,
142 G_DEFINE_TYPE (GossipPresenceChooser, gossip_presence_chooser, GTK_TYPE_TOGGLE_BUTTON);
145 gossip_presence_chooser_class_init (GossipPresenceChooserClass *klass)
147 GObjectClass *object_class = G_OBJECT_CLASS (klass);
149 object_class->finalize = presence_chooser_finalize;
151 g_type_class_add_private (object_class, sizeof (GossipPresenceChooserPriv));
155 gossip_presence_chooser_init (GossipPresenceChooser *chooser)
157 GossipPresenceChooserPriv *priv;
159 GtkWidget *alignment;
162 priv = GET_PRIV (chooser);
164 gtk_button_set_relief (GTK_BUTTON (chooser), GTK_RELIEF_NONE);
165 gtk_button_set_focus_on_click (GTK_BUTTON (chooser), FALSE);
167 alignment = gtk_alignment_new (0.5, 0.5, 1, 1);
168 gtk_widget_show (alignment);
169 gtk_container_add (GTK_CONTAINER (chooser), alignment);
170 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 1, 0);
172 priv->hbox = gtk_hbox_new (FALSE, 1);
173 gtk_widget_show (priv->hbox);
174 gtk_container_add (GTK_CONTAINER (alignment), priv->hbox);
176 priv->image = gtk_image_new ();
177 gtk_widget_show (priv->image);
178 gtk_box_pack_start (GTK_BOX (priv->hbox), priv->image, FALSE, TRUE, 0);
180 priv->label = gtk_label_new (NULL);
181 gtk_widget_show (priv->label);
182 gtk_box_pack_start (GTK_BOX (priv->hbox), priv->label, TRUE, TRUE, 0);
183 gtk_label_set_ellipsize (GTK_LABEL (priv->label), PANGO_ELLIPSIZE_END);
184 gtk_misc_set_alignment (GTK_MISC (priv->label), 0, 0.5);
185 gtk_misc_set_padding (GTK_MISC (priv->label), 4, 1);
187 alignment = gtk_alignment_new (0.5, 0.5, 1, 1);
188 gtk_widget_show (alignment);
189 gtk_box_pack_start (GTK_BOX (priv->hbox), alignment, FALSE, FALSE, 0);
191 arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT);
192 gtk_widget_show (arrow);
193 gtk_container_add (GTK_CONTAINER (alignment), arrow);
195 g_signal_connect (chooser, "toggled",
196 G_CALLBACK (presence_chooser_toggled_cb),
198 g_signal_connect (chooser, "button-press-event",
199 G_CALLBACK (presence_chooser_button_press_event_cb),
201 g_signal_connect (chooser, "scroll-event",
202 G_CALLBACK (presence_chooser_scroll_event_cb),
205 priv->mc = mission_control_new (tp_get_bus ());
206 state = mission_control_get_presence_actual (priv->mc, NULL);
207 presence_chooser_presence_changed_cb (priv->mc, state, chooser);
208 dbus_g_proxy_connect_signal (DBUS_G_PROXY (priv->mc),
209 "PresenceStatusActual",
210 G_CALLBACK (presence_chooser_presence_changed_cb),
215 presence_chooser_finalize (GObject *object)
217 GossipPresenceChooserPriv *priv;
219 priv = GET_PRIV (object);
221 if (priv->flash_timeout_id) {
222 g_source_remove (priv->flash_timeout_id);
225 if (priv->scroll_timeout_id) {
226 g_source_remove (priv->scroll_timeout_id);
229 dbus_g_proxy_disconnect_signal (DBUS_G_PROXY (priv->mc),
230 "PresenceStatusActual",
231 G_CALLBACK (presence_chooser_presence_changed_cb),
233 g_object_unref (priv->mc);
235 G_OBJECT_CLASS (gossip_presence_chooser_parent_class)->finalize (object);
239 gossip_presence_chooser_new (void)
243 chooser = g_object_new (GOSSIP_TYPE_PRESENCE_CHOOSER, NULL);
249 presence_chooser_presence_changed_cb (MissionControl *mc,
251 GossipPresenceChooser *chooser)
253 GossipPresenceChooserPriv *priv;
256 priv = GET_PRIV (chooser);
258 status = mission_control_get_presence_message_actual (priv->mc, NULL);
259 if (G_STR_EMPTY (status)) {
261 status = g_strdup (gossip_presence_state_get_default_status (state));
264 gossip_debug (DEBUG_DOMAIN, "Presence changed to %s (%d)",
267 presence_chooser_reset_scroll_timeout (chooser);
268 gossip_presence_chooser_flash_stop (chooser, state);
269 gtk_label_set_text (GTK_LABEL (priv->label), status);
275 presence_chooser_reset_scroll_timeout (GossipPresenceChooser *chooser)
277 GossipPresenceChooserPriv *priv;
279 priv = GET_PRIV (chooser);
281 if (priv->scroll_timeout_id) {
282 g_source_remove (priv->scroll_timeout_id);
283 priv->scroll_timeout_id = 0;
286 g_free (priv->scroll_status);
287 priv->scroll_status = NULL;
291 presence_chooser_scroll_timeout_cb (GossipPresenceChooser *chooser)
293 GossipPresenceChooserPriv *priv;
295 priv = GET_PRIV (chooser);
297 priv->scroll_timeout_id = 0;
299 gossip_debug (DEBUG_DOMAIN, "Setting presence to %s (%d)",
300 priv->scroll_status, priv->scroll_state);
302 mission_control_set_presence (priv->mc,
307 g_free (priv->scroll_status);
308 priv->scroll_status = NULL;
314 presence_chooser_scroll_event_cb (GossipPresenceChooser *chooser,
315 GdkEventScroll *event,
318 GossipPresenceChooserPriv *priv;
320 const gchar *current_status;
324 priv = GET_PRIV (chooser);
326 switch (event->direction) {
329 case GDK_SCROLL_DOWN:
335 current_status = gtk_label_get_text (GTK_LABEL (priv->label));
337 /* Get the list of presets, which in this context means all the items
338 * without a trailing "...".
340 list = presence_chooser_get_presets (chooser);
343 for (l = list; l; l = l->next) {
346 if (sas->state == priv->last_state &&
347 strcmp (sas->status, current_status) == 0) {
350 if (event->direction == GDK_SCROLL_UP) {
355 else if (event->direction == GDK_SCROLL_DOWN) {
367 presence_chooser_reset_scroll_timeout (chooser);
369 priv->scroll_status = g_strdup (sas->status);
370 priv->scroll_state = sas->state;
372 priv->scroll_timeout_id =
374 (GSourceFunc) presence_chooser_scroll_timeout_cb,
377 gossip_presence_chooser_flash_stop (chooser, sas->state);
378 gtk_label_set_text (GTK_LABEL (priv->label), sas->status);
382 /* If we didn't get any match at all, it means the last state
383 * was a custom one. Just switch to the first one.
385 status = gossip_presence_state_get_default_status (states[0]);
387 gossip_debug (DEBUG_DOMAIN, "Setting presence to %s (%d)",
390 presence_chooser_reset_scroll_timeout (chooser);
391 mission_control_set_presence (priv->mc,
397 g_list_foreach (list, (GFunc) g_free, NULL);
404 presence_chooser_get_presets (GossipPresenceChooser *chooser)
409 for (i = 0; i < G_N_ELEMENTS (states); i++) {
414 status = gossip_presence_state_get_default_status (states[i]);
415 sas = presence_chooser_state_and_status_new (states[i], status);
416 list = g_list_append (list, sas);
418 presets = gossip_status_presets_get (states[i], 5);
419 for (p = presets; p; p = p->next) {
420 sas = presence_chooser_state_and_status_new (states[i], p->data);
421 list = g_list_append (list, sas);
423 g_list_free (presets);
429 static StateAndStatus *
430 presence_chooser_state_and_status_new (McPresence state,
435 sas = g_new0 (StateAndStatus, 1);
438 sas->status = status;
444 presence_chooser_flash_timeout_cb (GossipPresenceChooser *chooser)
446 GossipPresenceChooserPriv *priv;
448 static gboolean on = FALSE;
450 priv = GET_PRIV (chooser);
453 state = priv->flash_state_1;
455 state = priv->flash_state_2;
458 gtk_image_set_from_icon_name (GTK_IMAGE (priv->image),
459 gossip_icon_name_for_presence_state (state),
468 gossip_presence_chooser_flash_start (GossipPresenceChooser *chooser,
472 GossipPresenceChooserPriv *priv;
474 g_return_if_fail (GOSSIP_IS_PRESENCE_CHOOSER (chooser));
476 priv = GET_PRIV (chooser);
478 if (priv->flash_timeout_id != 0) {
482 priv->flash_state_1 = state_1;
483 priv->flash_state_2 = state_2;
485 priv->flash_timeout_id = g_timeout_add (FLASH_TIMEOUT,
486 (GSourceFunc) presence_chooser_flash_timeout_cb,
491 gossip_presence_chooser_flash_stop (GossipPresenceChooser *chooser,
494 GossipPresenceChooserPriv *priv;
496 g_return_if_fail (GOSSIP_IS_PRESENCE_CHOOSER (chooser));
498 priv = GET_PRIV (chooser);
500 if (priv->flash_timeout_id) {
501 g_source_remove (priv->flash_timeout_id);
502 priv->flash_timeout_id = 0;
505 gtk_image_set_from_icon_name (GTK_IMAGE (priv->image),
506 gossip_icon_name_for_presence_state (state),
509 priv->last_state = state;
513 gossip_presence_chooser_is_flashing (GossipPresenceChooser *chooser)
515 GossipPresenceChooserPriv *priv;
517 g_return_val_if_fail (GOSSIP_IS_PRESENCE_CHOOSER (chooser), FALSE);
519 priv = GET_PRIV (chooser);
521 if (priv->flash_timeout_id) {
529 presence_chooser_button_press_event_cb (GtkWidget *chooser,
530 GdkEventButton *event,
533 if (event->button != 1 || event->type != GDK_BUTTON_PRESS) {
537 if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (chooser))) {
538 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (chooser), TRUE);
546 presence_chooser_toggled_cb (GtkWidget *chooser,
549 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (chooser))) {
550 presence_chooser_menu_popup (GOSSIP_PRESENCE_CHOOSER (chooser));
552 presence_chooser_menu_popdown (GOSSIP_PRESENCE_CHOOSER (chooser));
557 presence_chooser_menu_popup (GossipPresenceChooser *chooser)
559 GossipPresenceChooserPriv *priv;
562 priv = GET_PRIV (chooser);
568 menu = gossip_presence_chooser_create_menu ();
570 g_signal_connect_after (menu, "selection-done",
571 G_CALLBACK (presence_chooser_menu_selection_done_cb),
574 g_signal_connect (menu, "destroy",
575 G_CALLBACK (presence_chooser_menu_destroy_cb),
578 gtk_menu_attach_to_widget (GTK_MENU (menu),
579 GTK_WIDGET (chooser),
580 presence_chooser_menu_detach);
582 gtk_menu_popup (GTK_MENU (menu),
584 (GtkMenuPositionFunc) presence_chooser_menu_align_func,
587 gtk_get_current_event_time ());
593 presence_chooser_menu_popdown (GossipPresenceChooser *chooser)
595 GossipPresenceChooserPriv *priv;
597 priv = GET_PRIV (chooser);
600 gtk_widget_destroy (priv->menu);
605 presence_chooser_menu_selection_done_cb (GtkMenuShell *menushell,
606 GossipPresenceChooser *chooser)
608 gtk_widget_destroy (GTK_WIDGET (menushell));
610 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (chooser), FALSE);
614 presence_chooser_menu_destroy_cb (GtkWidget *menu,
615 GossipPresenceChooser *chooser)
617 GossipPresenceChooserPriv *priv;
619 priv = GET_PRIV (chooser);
625 presence_chooser_menu_detach (GtkWidget *attach_widget,
628 /* We don't need to do anything, but attaching the menu means
629 * we don't own the ref count and it is cleaned up properly.
634 presence_chooser_menu_align_func (GtkMenu *menu,
644 gtk_widget_size_request (GTK_WIDGET (menu), &req);
646 gdk_window_get_origin (widget->window, x, y);
648 *x += widget->allocation.x + 1;
649 *y += widget->allocation.y;
651 screen = gtk_widget_get_screen (GTK_WIDGET (menu));
652 screen_height = gdk_screen_get_height (screen);
654 if (req.height > screen_height) {
655 /* Too big for screen height anyway. */
660 if ((*y + req.height + widget->allocation.height) > screen_height) {
661 /* Can't put it below the button. */
665 /* Put menu below button. */
666 *y += widget->allocation.height;
674 gossip_presence_chooser_create_menu (void)
682 menu = gtk_menu_new ();
684 for (i = 0; i < G_N_ELEMENTS (states); i++) {
687 status = gossip_presence_state_get_default_status (states[i]);
688 presence_chooser_menu_add_item (menu,
693 list = gossip_status_presets_get (states[i], 5);
694 for (l = list; l; l = l->next) {
695 presence_chooser_menu_add_item (menu,
702 presence_chooser_menu_add_item (menu,
703 _("Custom message..."),
708 item = gtk_menu_item_new ();
709 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
710 gtk_widget_show (item);
713 /* Offline to disconnect */
714 status = gossip_presence_state_get_default_status (MC_PRESENCE_OFFLINE);
715 presence_chooser_menu_add_item (menu,
720 item = gtk_menu_item_new ();
721 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
722 gtk_widget_show (item);
725 item = gtk_image_menu_item_new_with_label (_("Clear List..."));
726 image = gtk_image_new_from_stock (GTK_STOCK_CLEAR, GTK_ICON_SIZE_MENU);
727 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
728 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
729 gtk_widget_show (image);
730 gtk_widget_show (item);
732 g_signal_connect (item,
734 G_CALLBACK (presence_chooser_clear_activate_cb),
741 presence_chooser_menu_add_item (GtkWidget *menu,
748 const gchar *icon_name;
750 item = gtk_image_menu_item_new_with_label (str);
751 icon_name = gossip_icon_name_for_presence_state (state);
754 g_signal_connect (item, "activate",
755 G_CALLBACK (presence_chooser_custom_activate_cb),
758 g_signal_connect (item, "activate",
759 G_CALLBACK (presence_chooser_noncustom_activate_cb),
763 image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
764 gtk_widget_show (image);
766 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
767 gtk_widget_show (item);
769 g_object_set_data_full (G_OBJECT (item),
770 "status", g_strdup (str),
771 (GDestroyNotify) g_free);
773 g_object_set_data (G_OBJECT (item), "state", GINT_TO_POINTER (state));
775 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
779 presence_chooser_clear_activate_cb (GtkWidget *item,
784 GtkWindow *parent = NULL;
786 toplevel = gtk_widget_get_toplevel (item);
787 if (GTK_WIDGET_TOPLEVEL (toplevel) &&
788 GTK_IS_WINDOW (toplevel)) {
792 window = GTK_WINDOW (toplevel);
793 visible = gossip_window_get_is_visible (window);
800 dialog = gtk_message_dialog_new (GTK_WINDOW (parent),
802 GTK_MESSAGE_QUESTION,
804 _("Are you sure you want to clear the list?"));
806 gtk_message_dialog_format_secondary_text (
807 GTK_MESSAGE_DIALOG (dialog),
808 _("This will remove any custom messages you have "
809 "added to the list of preset status messages."));
811 gtk_dialog_add_buttons (GTK_DIALOG (dialog),
812 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
813 _("Clear List"), GTK_RESPONSE_OK,
816 gtk_window_set_skip_taskbar_hint (GTK_WINDOW (dialog), FALSE);
818 g_signal_connect (dialog, "response",
819 G_CALLBACK (presence_chooser_clear_response_cb),
822 gtk_widget_show (dialog);
826 presence_chooser_clear_response_cb (GtkWidget *widget,
830 if (response == GTK_RESPONSE_OK) {
831 gossip_status_presets_reset ();
834 gtk_widget_destroy (widget);
838 presence_chooser_noncustom_activate_cb (GtkWidget *item,
844 status = g_object_get_data (G_OBJECT (item), "status");
845 state = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (item), "state"));
847 presence_chooser_set_state (state, status, FALSE);
851 presence_chooser_set_state (McPresence state,
855 const gchar *default_status;
858 default_status = gossip_presence_state_get_default_status (state);
860 if (G_STR_EMPTY (status)) {
861 status = default_status;
863 /* Only store the value if it differs from the default ones. */
864 if (save && strcmp (status, default_status) != 0) {
865 gossip_status_presets_set_last (state, status);
869 gossip_debug (DEBUG_DOMAIN, "Setting presence to %s (%d)",
872 mc = mission_control_new (tp_get_bus ());
873 mission_control_set_presence (mc, state, status, NULL, NULL);
878 presence_chooser_custom_activate_cb (GtkWidget *item,
883 state = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (item), "state"));
885 presence_chooser_show_dialog (state);
889 presence_chooser_show_dialog (McPresence state)
891 static GtkWidget *dialog = NULL;
892 static GtkListStore *store[LAST_MC_PRESENCE];
897 GtkWidget *checkbutton;
898 const gchar *default_status;
901 gtk_widget_destroy (dialog);
906 for (i = 0; i < LAST_MC_PRESENCE; i++) {
911 glade = gossip_glade_get_file ("gossip-presence-chooser.glade",
912 "status_message_dialog",
914 "status_message_dialog", &dialog,
915 "comboentry_status", &combo,
916 "image_status", &image,
917 "checkbutton_add", &checkbutton,
920 g_object_unref (glade);
922 g_signal_connect (dialog, "destroy",
923 G_CALLBACK (gtk_widget_destroyed),
925 g_signal_connect (dialog, "response",
926 G_CALLBACK (presence_chooser_dialog_response_cb),
929 gtk_image_set_from_icon_name (GTK_IMAGE (image),
930 gossip_icon_name_for_presence_state (state),
937 store[state] = gtk_list_store_new (1, G_TYPE_STRING);
939 presets = gossip_status_presets_get (state, -1);
940 for (l = presets; l; l = l->next) {
941 gtk_list_store_append (store[state], &iter);
942 gtk_list_store_set (store[state], &iter, 0, l->data, -1);
945 g_list_free (presets);
948 default_status = gossip_presence_state_get_default_status (state);
950 entry = GTK_BIN (combo)->child;
951 gtk_entry_set_text (GTK_ENTRY (entry), default_status);
952 gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
953 gtk_entry_set_width_chars (GTK_ENTRY (entry), 25);
955 gtk_combo_box_set_model (GTK_COMBO_BOX (combo), GTK_TREE_MODEL (store[state]));
956 gtk_combo_box_entry_set_text_column (GTK_COMBO_BOX_ENTRY (combo), 0);
958 /* FIXME: Set transian for a window ? */
960 g_object_set_data (G_OBJECT (dialog), "store", store[state]);
961 g_object_set_data (G_OBJECT (dialog), "entry", entry);
962 g_object_set_data (G_OBJECT (dialog), "checkbutton", checkbutton);
963 g_object_set_data (G_OBJECT (dialog), "state", GINT_TO_POINTER (state));
965 gtk_widget_show_all (dialog);
969 presence_chooser_dialog_response_cb (GtkWidget *dialog,
973 if (response == GTK_RESPONSE_OK) {
975 GtkWidget *checkbutton;
982 gboolean duplicate = FALSE;
985 entry = g_object_get_data (G_OBJECT (dialog), "entry");
986 status = gtk_entry_get_text (GTK_ENTRY (entry));
987 store = g_object_get_data (G_OBJECT (dialog), "store");
988 model = GTK_TREE_MODEL (store);
990 has_next = gtk_tree_model_get_iter_first (model, &iter);
994 gtk_tree_model_get (model, &iter,
998 if (strcmp (status, str) == 0) {
1006 has_next = gtk_tree_model_iter_next (model, &iter);
1010 gtk_list_store_append (store, &iter);
1011 gtk_list_store_set (store, &iter, 0, status, -1);
1014 checkbutton = g_object_get_data (G_OBJECT (dialog), "checkbutton");
1015 save = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton));
1016 state = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (dialog), "state"));
1018 presence_chooser_set_state (state, status, save);
1021 gtk_widget_destroy (dialog);