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 <libmissioncontrol/mission-control.h>
35 #include <libempathy/gossip-utils.h>
36 #include <libempathy/gossip-debug.h>
37 #include <libempathy/empathy-marshal.h>
39 #include "gossip-ui-utils.h"
40 #include "empathy-images.h"
41 #include "gossip-presence-chooser.h"
42 #include "gossip-status-presets.h"
44 #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GOSSIP_TYPE_PRESENCE_CHOOSER, GossipPresenceChooserPriv))
46 #define DEBUG_DOMAIN "PresenceChooser"
48 /* Flashing delay for icons (milliseconds). */
49 #define FLASH_TIMEOUT 500
59 McPresence last_state;
61 McPresence flash_state_1;
62 McPresence flash_state_2;
63 guint flash_timeout_id;
65 /* The handle the kind of unnessecary scroll support. */
66 guint scroll_timeout_id;
67 McPresence scroll_state;
69 } GossipPresenceChooserPriv;
76 /* States to be listed in the menu */
77 static McPresence states[] = {MC_PRESENCE_AVAILABLE,
78 MC_PRESENCE_DO_NOT_DISTURB,
81 static void gossip_presence_chooser_class_init (GossipPresenceChooserClass *klass);
82 static void gossip_presence_chooser_init (GossipPresenceChooser *chooser);
83 static void presence_chooser_finalize (GObject *object);
84 static void presence_chooser_presence_changed_cb (MissionControl *mc,
86 GossipPresenceChooser *chooser);
87 static void presence_chooser_reset_scroll_timeout (GossipPresenceChooser *chooser);
88 static gboolean presence_chooser_scroll_timeout_cb (GossipPresenceChooser *chooser);
89 static gboolean presence_chooser_scroll_event_cb (GossipPresenceChooser *chooser,
90 GdkEventScroll *event,
92 static GList * presence_chooser_get_presets (GossipPresenceChooser *chooser);
93 static StateAndStatus *presence_chooser_state_and_status_new (McPresence state,
95 static gboolean presence_chooser_flash_timeout_cb (GossipPresenceChooser *chooser);
96 void gossip_presence_chooser_flash_start (GossipPresenceChooser *chooser,
99 void gossip_presence_chooser_flash_stop (GossipPresenceChooser *chooser,
101 gboolean gossip_presence_chooser_is_flashing (GossipPresenceChooser *chooser);
102 static gboolean presence_chooser_button_press_event_cb (GtkWidget *chooser,
103 GdkEventButton *event,
105 static void presence_chooser_toggled_cb (GtkWidget *chooser,
107 static void presence_chooser_menu_popup (GossipPresenceChooser *chooser);
108 static void presence_chooser_menu_popdown (GossipPresenceChooser *chooser);
109 static void presence_chooser_menu_selection_done_cb (GtkMenuShell *menushell,
110 GossipPresenceChooser *chooser);
111 static void presence_chooser_menu_destroy_cb (GtkWidget *menu,
112 GossipPresenceChooser *chooser);
113 static void presence_chooser_menu_detach (GtkWidget *attach_widget,
115 static void presence_chooser_menu_align_func (GtkMenu *menu,
120 static void presence_chooser_menu_add_item (GtkWidget *menu,
124 static void presence_chooser_clear_activate_cb (GtkWidget *item,
126 static void presence_chooser_clear_response_cb (GtkWidget *widget,
129 static void presence_chooser_noncustom_activate_cb (GtkWidget *item,
131 static void presence_chooser_set_state (McPresence state,
134 static void presence_chooser_custom_activate_cb (GtkWidget *item,
136 static void presence_chooser_show_dialog (McPresence state);
137 static void presence_chooser_dialog_response_cb (GtkWidget *dialog,
141 G_DEFINE_TYPE (GossipPresenceChooser, gossip_presence_chooser, GTK_TYPE_TOGGLE_BUTTON);
144 gossip_presence_chooser_class_init (GossipPresenceChooserClass *klass)
146 GObjectClass *object_class = G_OBJECT_CLASS (klass);
148 object_class->finalize = presence_chooser_finalize;
150 g_type_class_add_private (object_class, sizeof (GossipPresenceChooserPriv));
154 gossip_presence_chooser_init (GossipPresenceChooser *chooser)
156 GossipPresenceChooserPriv *priv;
158 GtkWidget *alignment;
161 priv = GET_PRIV (chooser);
163 gtk_button_set_relief (GTK_BUTTON (chooser), GTK_RELIEF_NONE);
164 gtk_button_set_focus_on_click (GTK_BUTTON (chooser), FALSE);
166 alignment = gtk_alignment_new (0.5, 0.5, 1, 1);
167 gtk_widget_show (alignment);
168 gtk_container_add (GTK_CONTAINER (chooser), alignment);
169 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 1, 0);
171 priv->hbox = gtk_hbox_new (FALSE, 1);
172 gtk_widget_show (priv->hbox);
173 gtk_container_add (GTK_CONTAINER (alignment), priv->hbox);
175 priv->image = gtk_image_new ();
176 gtk_widget_show (priv->image);
177 gtk_box_pack_start (GTK_BOX (priv->hbox), priv->image, FALSE, TRUE, 0);
179 priv->label = gtk_label_new (NULL);
180 gtk_widget_show (priv->label);
181 gtk_box_pack_start (GTK_BOX (priv->hbox), priv->label, TRUE, TRUE, 0);
182 gtk_label_set_ellipsize (GTK_LABEL (priv->label), PANGO_ELLIPSIZE_END);
183 gtk_misc_set_alignment (GTK_MISC (priv->label), 0, 0.5);
184 gtk_misc_set_padding (GTK_MISC (priv->label), 4, 1);
186 alignment = gtk_alignment_new (0.5, 0.5, 1, 1);
187 gtk_widget_show (alignment);
188 gtk_box_pack_start (GTK_BOX (priv->hbox), alignment, FALSE, FALSE, 0);
190 arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT);
191 gtk_widget_show (arrow);
192 gtk_container_add (GTK_CONTAINER (alignment), arrow);
194 g_signal_connect (chooser, "toggled",
195 G_CALLBACK (presence_chooser_toggled_cb),
197 g_signal_connect (chooser, "button-press-event",
198 G_CALLBACK (presence_chooser_button_press_event_cb),
200 g_signal_connect (chooser, "scroll-event",
201 G_CALLBACK (presence_chooser_scroll_event_cb),
204 priv->mc = gossip_mission_control_new ();
205 state = mission_control_get_presence_actual (priv->mc, NULL);
206 presence_chooser_presence_changed_cb (priv->mc, state, chooser);
207 dbus_g_proxy_connect_signal (DBUS_G_PROXY (priv->mc),
208 "PresenceStatusActual",
209 G_CALLBACK (presence_chooser_presence_changed_cb),
214 presence_chooser_finalize (GObject *object)
216 GossipPresenceChooserPriv *priv;
218 priv = GET_PRIV (object);
220 if (priv->flash_timeout_id) {
221 g_source_remove (priv->flash_timeout_id);
224 if (priv->scroll_timeout_id) {
225 g_source_remove (priv->scroll_timeout_id);
228 dbus_g_proxy_disconnect_signal (DBUS_G_PROXY (priv->mc),
229 "PresenceStatusActual",
230 G_CALLBACK (presence_chooser_presence_changed_cb),
232 g_object_unref (priv->mc);
234 G_OBJECT_CLASS (gossip_presence_chooser_parent_class)->finalize (object);
238 gossip_presence_chooser_new (void)
242 chooser = g_object_new (GOSSIP_TYPE_PRESENCE_CHOOSER, NULL);
248 presence_chooser_presence_changed_cb (MissionControl *mc,
250 GossipPresenceChooser *chooser)
252 GossipPresenceChooserPriv *priv;
255 priv = GET_PRIV (chooser);
257 status = mission_control_get_presence_message_actual (priv->mc, NULL);
258 if (G_STR_EMPTY (status)) {
260 status = g_strdup (gossip_presence_state_get_default_status (state));
263 gossip_debug (DEBUG_DOMAIN, "Presence changed to %s (%d)",
266 presence_chooser_reset_scroll_timeout (chooser);
267 gossip_presence_chooser_flash_stop (chooser, state);
268 gtk_label_set_text (GTK_LABEL (priv->label), status);
274 presence_chooser_reset_scroll_timeout (GossipPresenceChooser *chooser)
276 GossipPresenceChooserPriv *priv;
278 priv = GET_PRIV (chooser);
280 if (priv->scroll_timeout_id) {
281 g_source_remove (priv->scroll_timeout_id);
282 priv->scroll_timeout_id = 0;
285 g_free (priv->scroll_status);
286 priv->scroll_status = NULL;
290 presence_chooser_scroll_timeout_cb (GossipPresenceChooser *chooser)
292 GossipPresenceChooserPriv *priv;
294 priv = GET_PRIV (chooser);
296 priv->scroll_timeout_id = 0;
298 gossip_debug (DEBUG_DOMAIN, "Setting presence to %s (%d)",
299 priv->scroll_status, priv->scroll_state);
301 mission_control_set_presence (priv->mc,
306 g_free (priv->scroll_status);
307 priv->scroll_status = NULL;
313 presence_chooser_scroll_event_cb (GossipPresenceChooser *chooser,
314 GdkEventScroll *event,
317 GossipPresenceChooserPriv *priv;
319 const gchar *current_status;
323 priv = GET_PRIV (chooser);
325 switch (event->direction) {
328 case GDK_SCROLL_DOWN:
334 current_status = gtk_label_get_text (GTK_LABEL (priv->label));
336 /* Get the list of presets, which in this context means all the items
337 * without a trailing "...".
339 list = presence_chooser_get_presets (chooser);
342 for (l = list; l; l = l->next) {
345 if (sas->state == priv->last_state &&
346 strcmp (sas->status, current_status) == 0) {
349 if (event->direction == GDK_SCROLL_UP) {
354 else if (event->direction == GDK_SCROLL_DOWN) {
366 presence_chooser_reset_scroll_timeout (chooser);
368 priv->scroll_status = g_strdup (sas->status);
369 priv->scroll_state = sas->state;
371 priv->scroll_timeout_id =
373 (GSourceFunc) presence_chooser_scroll_timeout_cb,
376 gossip_presence_chooser_flash_stop (chooser, sas->state);
377 gtk_label_set_text (GTK_LABEL (priv->label), sas->status);
381 /* If we didn't get any match at all, it means the last state
382 * was a custom one. Just switch to the first one.
384 status = gossip_presence_state_get_default_status (states[0]);
386 gossip_debug (DEBUG_DOMAIN, "Setting presence to %s (%d)",
389 presence_chooser_reset_scroll_timeout (chooser);
390 mission_control_set_presence (priv->mc,
396 g_list_foreach (list, (GFunc) g_free, NULL);
403 presence_chooser_get_presets (GossipPresenceChooser *chooser)
408 for (i = 0; i < G_N_ELEMENTS (states); i++) {
413 status = gossip_presence_state_get_default_status (states[i]);
414 sas = presence_chooser_state_and_status_new (states[i], status);
415 list = g_list_append (list, sas);
417 presets = gossip_status_presets_get (states[i], 5);
418 for (p = presets; p; p = p->next) {
419 sas = presence_chooser_state_and_status_new (states[i], p->data);
420 list = g_list_append (list, sas);
422 g_list_free (presets);
428 static StateAndStatus *
429 presence_chooser_state_and_status_new (McPresence state,
434 sas = g_new0 (StateAndStatus, 1);
437 sas->status = status;
443 presence_chooser_flash_timeout_cb (GossipPresenceChooser *chooser)
445 GossipPresenceChooserPriv *priv;
447 static gboolean on = FALSE;
449 priv = GET_PRIV (chooser);
452 state = priv->flash_state_1;
454 state = priv->flash_state_2;
457 gtk_image_set_from_icon_name (GTK_IMAGE (priv->image),
458 gossip_icon_name_for_presence_state (state),
467 gossip_presence_chooser_flash_start (GossipPresenceChooser *chooser,
471 GossipPresenceChooserPriv *priv;
473 g_return_if_fail (GOSSIP_IS_PRESENCE_CHOOSER (chooser));
475 priv = GET_PRIV (chooser);
477 if (priv->flash_timeout_id != 0) {
481 priv->flash_state_1 = state_1;
482 priv->flash_state_2 = state_2;
484 priv->flash_timeout_id = g_timeout_add (FLASH_TIMEOUT,
485 (GSourceFunc) presence_chooser_flash_timeout_cb,
490 gossip_presence_chooser_flash_stop (GossipPresenceChooser *chooser,
493 GossipPresenceChooserPriv *priv;
495 g_return_if_fail (GOSSIP_IS_PRESENCE_CHOOSER (chooser));
497 priv = GET_PRIV (chooser);
499 if (priv->flash_timeout_id) {
500 g_source_remove (priv->flash_timeout_id);
501 priv->flash_timeout_id = 0;
504 gtk_image_set_from_icon_name (GTK_IMAGE (priv->image),
505 gossip_icon_name_for_presence_state (state),
508 priv->last_state = state;
512 gossip_presence_chooser_is_flashing (GossipPresenceChooser *chooser)
514 GossipPresenceChooserPriv *priv;
516 g_return_val_if_fail (GOSSIP_IS_PRESENCE_CHOOSER (chooser), FALSE);
518 priv = GET_PRIV (chooser);
520 if (priv->flash_timeout_id) {
528 presence_chooser_button_press_event_cb (GtkWidget *chooser,
529 GdkEventButton *event,
532 if (event->button != 1 || event->type != GDK_BUTTON_PRESS) {
536 if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (chooser))) {
537 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (chooser), TRUE);
545 presence_chooser_toggled_cb (GtkWidget *chooser,
548 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (chooser))) {
549 presence_chooser_menu_popup (GOSSIP_PRESENCE_CHOOSER (chooser));
551 presence_chooser_menu_popdown (GOSSIP_PRESENCE_CHOOSER (chooser));
556 presence_chooser_menu_popup (GossipPresenceChooser *chooser)
558 GossipPresenceChooserPriv *priv;
561 priv = GET_PRIV (chooser);
567 menu = gossip_presence_chooser_create_menu ();
569 g_signal_connect_after (menu, "selection-done",
570 G_CALLBACK (presence_chooser_menu_selection_done_cb),
573 g_signal_connect (menu, "destroy",
574 G_CALLBACK (presence_chooser_menu_destroy_cb),
577 gtk_menu_attach_to_widget (GTK_MENU (menu),
578 GTK_WIDGET (chooser),
579 presence_chooser_menu_detach);
581 gtk_menu_popup (GTK_MENU (menu),
583 (GtkMenuPositionFunc) presence_chooser_menu_align_func,
586 gtk_get_current_event_time ());
592 presence_chooser_menu_popdown (GossipPresenceChooser *chooser)
594 GossipPresenceChooserPriv *priv;
596 priv = GET_PRIV (chooser);
599 gtk_widget_destroy (priv->menu);
604 presence_chooser_menu_selection_done_cb (GtkMenuShell *menushell,
605 GossipPresenceChooser *chooser)
607 gtk_widget_destroy (GTK_WIDGET (menushell));
609 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (chooser), FALSE);
613 presence_chooser_menu_destroy_cb (GtkWidget *menu,
614 GossipPresenceChooser *chooser)
616 GossipPresenceChooserPriv *priv;
618 priv = GET_PRIV (chooser);
624 presence_chooser_menu_detach (GtkWidget *attach_widget,
627 /* We don't need to do anything, but attaching the menu means
628 * we don't own the ref count and it is cleaned up properly.
633 presence_chooser_menu_align_func (GtkMenu *menu,
643 gtk_widget_size_request (GTK_WIDGET (menu), &req);
645 gdk_window_get_origin (widget->window, x, y);
647 *x += widget->allocation.x + 1;
648 *y += widget->allocation.y;
650 screen = gtk_widget_get_screen (GTK_WIDGET (menu));
651 screen_height = gdk_screen_get_height (screen);
653 if (req.height > screen_height) {
654 /* Too big for screen height anyway. */
659 if ((*y + req.height + widget->allocation.height) > screen_height) {
660 /* Can't put it below the button. */
664 /* Put menu below button. */
665 *y += widget->allocation.height;
673 gossip_presence_chooser_create_menu (void)
681 menu = gtk_menu_new ();
683 for (i = 0; i < G_N_ELEMENTS (states); i++) {
686 status = gossip_presence_state_get_default_status (states[i]);
687 presence_chooser_menu_add_item (menu,
692 list = gossip_status_presets_get (states[i], 5);
693 for (l = list; l; l = l->next) {
694 presence_chooser_menu_add_item (menu,
701 presence_chooser_menu_add_item (menu,
702 _("Custom message..."),
707 item = gtk_menu_item_new ();
708 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
709 gtk_widget_show (item);
712 /* Offline to disconnect */
713 status = gossip_presence_state_get_default_status (MC_PRESENCE_OFFLINE);
714 presence_chooser_menu_add_item (menu,
719 item = gtk_menu_item_new ();
720 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
721 gtk_widget_show (item);
724 item = gtk_image_menu_item_new_with_label (_("Clear List..."));
725 image = gtk_image_new_from_stock (GTK_STOCK_CLEAR, GTK_ICON_SIZE_MENU);
726 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
727 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
728 gtk_widget_show (image);
729 gtk_widget_show (item);
731 g_signal_connect (item,
733 G_CALLBACK (presence_chooser_clear_activate_cb),
740 presence_chooser_menu_add_item (GtkWidget *menu,
747 const gchar *icon_name;
749 item = gtk_image_menu_item_new_with_label (str);
750 icon_name = gossip_icon_name_for_presence_state (state);
753 g_signal_connect (item, "activate",
754 G_CALLBACK (presence_chooser_custom_activate_cb),
757 g_signal_connect (item, "activate",
758 G_CALLBACK (presence_chooser_noncustom_activate_cb),
762 image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
763 gtk_widget_show (image);
765 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
766 gtk_widget_show (item);
768 g_object_set_data_full (G_OBJECT (item),
769 "status", g_strdup (str),
770 (GDestroyNotify) g_free);
772 g_object_set_data (G_OBJECT (item), "state", GINT_TO_POINTER (state));
774 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
778 presence_chooser_clear_activate_cb (GtkWidget *item,
783 GtkWindow *parent = NULL;
785 toplevel = gtk_widget_get_toplevel (item);
786 if (GTK_WIDGET_TOPLEVEL (toplevel) &&
787 GTK_IS_WINDOW (toplevel)) {
791 window = GTK_WINDOW (toplevel);
792 visible = gossip_window_get_is_visible (window);
799 dialog = gtk_message_dialog_new (GTK_WINDOW (parent),
801 GTK_MESSAGE_QUESTION,
803 _("Are you sure you want to clear the list?"));
805 gtk_message_dialog_format_secondary_text (
806 GTK_MESSAGE_DIALOG (dialog),
807 _("This will remove any custom messages you have "
808 "added to the list of preset status messages."));
810 gtk_dialog_add_buttons (GTK_DIALOG (dialog),
811 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
812 _("Clear List"), GTK_RESPONSE_OK,
815 gtk_window_set_skip_taskbar_hint (GTK_WINDOW (dialog), FALSE);
817 g_signal_connect (dialog, "response",
818 G_CALLBACK (presence_chooser_clear_response_cb),
821 gtk_widget_show (dialog);
825 presence_chooser_clear_response_cb (GtkWidget *widget,
829 if (response == GTK_RESPONSE_OK) {
830 gossip_status_presets_reset ();
833 gtk_widget_destroy (widget);
837 presence_chooser_noncustom_activate_cb (GtkWidget *item,
843 status = g_object_get_data (G_OBJECT (item), "status");
844 state = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (item), "state"));
846 presence_chooser_set_state (state, status, FALSE);
850 presence_chooser_set_state (McPresence state,
854 const gchar *default_status;
857 default_status = gossip_presence_state_get_default_status (state);
859 if (G_STR_EMPTY (status)) {
860 status = default_status;
862 /* Only store the value if it differs from the default ones. */
863 if (save && strcmp (status, default_status) != 0) {
864 gossip_status_presets_set_last (state, status);
868 gossip_debug (DEBUG_DOMAIN, "Setting presence to %s (%d)",
871 mc = gossip_mission_control_new ();
872 mission_control_set_presence (mc, state, status, NULL, NULL);
877 presence_chooser_custom_activate_cb (GtkWidget *item,
882 state = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (item), "state"));
884 presence_chooser_show_dialog (state);
888 presence_chooser_show_dialog (McPresence state)
890 static GtkWidget *dialog = NULL;
891 static GtkListStore *store[LAST_MC_PRESENCE];
896 GtkWidget *checkbutton;
897 const gchar *default_status;
900 gtk_widget_destroy (dialog);
905 for (i = 0; i < LAST_MC_PRESENCE; i++) {
910 glade = gossip_glade_get_file ("gossip-presence-chooser.glade",
911 "status_message_dialog",
913 "status_message_dialog", &dialog,
914 "comboentry_status", &combo,
915 "image_status", &image,
916 "checkbutton_add", &checkbutton,
919 g_object_unref (glade);
921 g_signal_connect (dialog, "destroy",
922 G_CALLBACK (gtk_widget_destroyed),
924 g_signal_connect (dialog, "response",
925 G_CALLBACK (presence_chooser_dialog_response_cb),
928 gtk_image_set_from_icon_name (GTK_IMAGE (image),
929 gossip_icon_name_for_presence_state (state),
936 store[state] = gtk_list_store_new (1, G_TYPE_STRING);
938 presets = gossip_status_presets_get (state, -1);
939 for (l = presets; l; l = l->next) {
940 gtk_list_store_append (store[state], &iter);
941 gtk_list_store_set (store[state], &iter, 0, l->data, -1);
944 g_list_free (presets);
947 default_status = gossip_presence_state_get_default_status (state);
949 entry = GTK_BIN (combo)->child;
950 gtk_entry_set_text (GTK_ENTRY (entry), default_status);
951 gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
952 gtk_entry_set_width_chars (GTK_ENTRY (entry), 25);
954 gtk_combo_box_set_model (GTK_COMBO_BOX (combo), GTK_TREE_MODEL (store[state]));
955 gtk_combo_box_entry_set_text_column (GTK_COMBO_BOX_ENTRY (combo), 0);
957 /* FIXME: Set transian for a window ? */
959 g_object_set_data (G_OBJECT (dialog), "store", store[state]);
960 g_object_set_data (G_OBJECT (dialog), "entry", entry);
961 g_object_set_data (G_OBJECT (dialog), "checkbutton", checkbutton);
962 g_object_set_data (G_OBJECT (dialog), "state", GINT_TO_POINTER (state));
964 gtk_widget_show_all (dialog);
968 presence_chooser_dialog_response_cb (GtkWidget *dialog,
972 if (response == GTK_RESPONSE_OK) {
974 GtkWidget *checkbutton;
981 gboolean duplicate = FALSE;
984 entry = g_object_get_data (G_OBJECT (dialog), "entry");
985 status = gtk_entry_get_text (GTK_ENTRY (entry));
986 store = g_object_get_data (G_OBJECT (dialog), "store");
987 model = GTK_TREE_MODEL (store);
989 has_next = gtk_tree_model_get_iter_first (model, &iter);
993 gtk_tree_model_get (model, &iter,
997 if (strcmp (status, str) == 0) {
1005 has_next = gtk_tree_model_iter_next (model, &iter);
1009 gtk_list_store_append (store, &iter);
1010 gtk_list_store_set (store, &iter, 0, status, -1);
1013 checkbutton = g_object_get_data (G_OBJECT (dialog), "checkbutton");
1014 save = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton));
1015 state = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (dialog), "state"));
1017 presence_chooser_set_state (state, status, save);
1020 gtk_widget_destroy (dialog);