예제 #1
0
static void
idle_get_property (GObject    *object,
		   guint       param_id,
		   GValue     *value,
		   GParamSpec *pspec)
{
	EmpathyIdlePriv *priv;
	EmpathyIdle     *idle;

	priv = GET_PRIV (object);
	idle = EMPATHY_IDLE (object);

	switch (param_id) {
	case PROP_STATE:
		g_value_set_enum (value, empathy_idle_get_state (idle));
		break;
	case PROP_STATUS:
		g_value_set_string (value, empathy_idle_get_status (idle));
		break;
	case PROP_FLASH_STATE:
		g_value_set_enum (value, empathy_idle_get_flash_state (idle));
		break;
	case PROP_AUTO_AWAY:
		g_value_set_boolean (value, empathy_idle_get_auto_away (idle));
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
		break;
	};
}
예제 #2
0
static gboolean
presence_chooser_is_preset (EmpathyPresenceChooser *self)
{
	EmpathyPresenceChooserPriv *priv = GET_PRIV (self);
	TpConnectionPresenceType state;
	const char *status;
	GList *presets, *l;
	gboolean match = FALSE;

	state = empathy_idle_get_state (priv->idle);
	status = empathy_idle_get_status (priv->idle);

	presets = empathy_status_presets_get (state, -1);
	for (l = presets; l; l = l->next) {
		char *preset = (char *) l->data;

		if (!strcmp (status, preset)) {
			match = TRUE;
			break;
		}
	}

	g_list_free (presets);

	DEBUG ("is_preset(%i, %s) = %i\n", state, status, match);

	return match;
}
예제 #3
0
static void
account_manager_ready_cb (GObject *source_object,
    GAsyncResult *result,
    gpointer user_data)
{
  TpAccountManager *manager = TP_ACCOUNT_MANAGER (source_object);
  GError *error = NULL;
  EmpathyIdle *idle;
  EmpathyConnectivity *connectivity;
  gboolean autoconnect = TRUE;

  if (!tp_account_manager_prepare_finish (manager, result, &error))
    {
      DEBUG ("Failed to prepare account manager: %s", error->message);
      g_error_free (error);
      return;
    }

  /* Autoconnect */
  idle = empathy_idle_dup_singleton ();
  connectivity = empathy_connectivity_dup_singleton ();

  empathy_conf_get_bool (empathy_conf_get (),
      EMPATHY_PREFS_AUTOCONNECT, &autoconnect);
  if (autoconnect && !no_connect &&
      tp_connection_presence_type_cmp_availability
          (empathy_idle_get_state (idle), TP_CONNECTION_PRESENCE_TYPE_OFFLINE)
            <= 0)
      /* if current state is Offline, then put it online */
      empathy_idle_set_state (idle, TP_CONNECTION_PRESENCE_TYPE_AVAILABLE);

  if (should_create_salut_account (manager)
      || !empathy_import_mc4_has_imported ())
    {
      EmpathyConnectionManagers *managers;
      managers = empathy_connection_managers_dup_singleton ();

      if (!check_connection_managers_ready (managers))
        {
          g_signal_connect (managers, "notify::ready",
            G_CALLBACK (connection_managers_ready_cb), NULL);
        }
    }
  else if (!start_hidden)
    {
      maybe_show_account_assistant ();
    }

  g_object_unref (idle);
  g_object_unref (connectivity);
}
static void
status_icon_update_icon (EmpathyStatusIcon *icon)
{
    EmpathyStatusIconPriv *priv = GET_PRIV (icon);
    const gchar           *icon_name;

    if (priv->event && priv->showing_event_icon) {
        icon_name = priv->event->icon_name;
    } else {
        McPresence state;

        state = empathy_idle_get_state (priv->idle);
        icon_name = empathy_icon_name_for_presence (state);
    }

    gtk_status_icon_set_from_icon_name (priv->icon, icon_name);
}
static void
idle_state_change_cb (EmpathyIdle *idle,
    GParamSpec *spec,
    EmpathyAccountWidget *self)
{
  EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
  TpConnectionPresenceType state;

  state = empathy_idle_get_state (priv->idle);

  if (state > TP_CONNECTION_PRESENCE_TYPE_OFFLINE)
    {
      g_object_set (priv->apply_button, "label", GTK_STOCK_CONNECT, NULL);
    }
  else
    {
      g_object_set (priv->apply_button, "label", GTK_STOCK_APPLY, NULL);
    }
}
예제 #6
0
static void
presence_chooser_presence_changed_cb (EmpathyPresenceChooser *chooser)
{
	EmpathyPresenceChooserPriv *priv;
	McPresence                 state;
	McPresence                 flash_state;
	const gchar               *status;

	priv = GET_PRIV (chooser);

	state = empathy_idle_get_state (priv->idle);
	status = empathy_idle_get_status (priv->idle);
	flash_state = empathy_idle_get_flash_state (priv->idle);

	presence_chooser_reset_scroll_timeout (chooser);
	gtk_label_set_text (GTK_LABEL (priv->label), status);

	if (flash_state != MC_PRESENCE_UNSET) {
		presence_chooser_flash_start (chooser, state, flash_state);
	} else {
		presence_chooser_flash_stop (chooser, state);
	}
}
예제 #7
0
static void
presence_chooser_entry_icon_release_cb (EmpathyPresenceChooser *self,
                                        GtkEntryIconPosition    icon_pos,
                                        GdkEvent               *event,
					GtkEntry               *entry)
{
	EmpathyPresenceChooserPriv *priv = GET_PRIV (self);

	if (priv->editing_status) {
		presence_chooser_set_status_editing (self, FALSE);
		mc_set_custom_state (self);
	}
	else {
		PresenceChooserEntryType type;
		TpConnectionPresenceType state;
		const char *status;

		type = presence_chooser_get_entry_type (self);
		state = empathy_idle_get_state (priv->idle);
		status = empathy_idle_get_status (priv->idle);

		if (presence_chooser_is_preset (self)) {
			/* remove the entry */
			DEBUG ("REMOVING PRESET (%i, %s)\n", state, status);
			empathy_status_presets_remove (state, status);
		}
		else {
			/* save the entry */
			DEBUG ("SAVING PRESET (%i, %s)\n", state, status);
			empathy_status_presets_set_last (state, status);
		}

		/* update the icon */
		presence_chooser_set_favorite_icon (self);
	}
}
예제 #8
0
파일: empathy.c 프로젝트: Elleo/empathy
int
main (int argc, char *argv[])
{
	guint32            startup_timestamp;
	EmpathyStatusIcon *icon;
	EmpathyDispatcher *dispatcher;
	EmpathyChatroomManager *chatroom_manager;
	EmpathyCallFactory *call_factory;
	GtkWidget         *window;
	MissionControl    *mc;
	EmpathyIdle       *idle;
	gboolean           autoconnect = TRUE;
	gboolean           no_connect = FALSE; 
	gboolean           hide_contact_list = FALSE;
	gboolean           accounts_dialog = FALSE;
	GError            *error = NULL;
	GOptionEntry       options[] = {
		{ "no-connect", 'n',
		  0, G_OPTION_ARG_NONE, &no_connect,
		  N_("Don't connect on startup"),
		  NULL },
		{ "hide-contact-list", 'h',
		  0, G_OPTION_ARG_NONE, &hide_contact_list,
		  N_("Don't show the contact list on startup"),
		  NULL },
		{ "accounts", 'a',
		  0, G_OPTION_ARG_NONE, &accounts_dialog,
		  N_("Show the accounts dialog"),
		  NULL },
		{ "version", 'v',
		  G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, show_version_cb, NULL, NULL },
		{ NULL }
	};

	/* Init */
	g_thread_init (NULL);
	empathy_init ();

	if (!gtk_init_with_args (&argc, &argv,
				 N_("- Empathy Instant Messenger"),
				 options, GETTEXT_PACKAGE, &error)) {
		g_warning ("Error in empathy init: %s", error->message);
		return EXIT_FAILURE;
	}

	empathy_gtk_init ();
	g_set_application_name (_(PACKAGE_NAME));

	gst_init (&argc, &argv);

	gtk_window_set_default_icon_name ("empathy");
	textdomain (GETTEXT_PACKAGE);

        /* Setting up the bacon connection */
	startup_timestamp = get_startup_timestamp ();
	connection = bacon_message_connection_new ("empathy");
	if (connection != NULL) {
		if (!bacon_message_connection_get_is_server (connection)) {
			gchar *message;

			if (accounts_dialog) {
				DEBUG ("Showing accounts dialog from existing Empathy instance");

				message = g_strdup ("accounts");

			} else {

				DEBUG ("Activating existing instance");

				message = g_strdup_printf ("%" G_GUINT32_FORMAT,
							   startup_timestamp);
			}

			bacon_message_connection_send (connection, message);

			/* We never popup a window, so tell startup-notification
			 * that we are done. */
			gdk_notify_startup_complete ();

			g_free (message);
			bacon_message_connection_free (connection);

			return EXIT_SUCCESS;
		}
	} else {
		g_warning ("Cannot create the 'empathy' bacon connection.");
	}

	/* Setting up MC */
	mc = empathy_mission_control_dup_singleton ();
	g_signal_connect (mc, "ServiceEnded",
			  G_CALLBACK (service_ended_cb),
			  NULL);
	g_signal_connect (mc, "Error",
			  G_CALLBACK (operation_error_cb),
			  NULL);

	if (accounts_dialog) {
		GtkWidget *dialog;

		dialog = empathy_accounts_dialog_show (NULL, NULL);
		g_signal_connect (dialog, "destroy",
				  G_CALLBACK (gtk_main_quit),
				  NULL);

		gtk_main ();
		return 0;
	}

	/* Setting up Idle */
	idle = empathy_idle_dup_singleton ();
	empathy_idle_set_auto_away (idle, TRUE);
	use_nm_notify_cb (empathy_conf_get (), EMPATHY_PREFS_USE_NM, idle);
	empathy_conf_notify_add (empathy_conf_get (), EMPATHY_PREFS_USE_NM,
				 use_nm_notify_cb, idle);

	/* Autoconnect */
	empathy_conf_get_bool (empathy_conf_get(),
			       EMPATHY_PREFS_AUTOCONNECT,
			       &autoconnect);
	if (autoconnect && ! no_connect &&
	    empathy_idle_get_state (idle) <= MC_PRESENCE_OFFLINE) {
		empathy_idle_set_state (idle, MC_PRESENCE_AVAILABLE);
	}
	
	create_salut_account ();

	/* Setting up UI */
	window = empathy_main_window_show ();
	icon = empathy_status_icon_new (GTK_WINDOW (window), hide_contact_list);

	if (connection) {
		/* We se the callback here because we need window */
		bacon_message_connection_set_callback (connection,
						       on_bacon_message_received,
						       window);
	}

	/* Handle channels */
	dispatcher = empathy_dispatcher_dup_singleton ();
	g_signal_connect (dispatcher, "dispatch", G_CALLBACK (dispatch_cb), NULL);

	chatroom_manager = empathy_chatroom_manager_dup_singleton (NULL);
	empathy_chatroom_manager_observe (chatroom_manager, dispatcher);

	notify_init (_(PACKAGE_NAME));
	/* Create the call factory */
	call_factory = empathy_call_factory_initialise ();
	g_signal_connect (G_OBJECT (call_factory), "new-call-handler",
		G_CALLBACK (new_call_handler_cb), NULL);

	gtk_main ();

	empathy_idle_set_state (idle, MC_PRESENCE_OFFLINE);

	g_object_unref (mc);
	g_object_unref (idle);
	g_object_unref (icon);
	g_object_unref (dispatcher);
	g_object_unref (chatroom_manager);

	notify_uninit ();

	return EXIT_SUCCESS;
}
static void
do_constructed (GObject *obj)
{
  EmpathyAccountWidget *self = EMPATHY_ACCOUNT_WIDGET (obj);
  EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
  TpAccount *account;
  const gchar *protocol, *cm_name;
  guint i = 0;
  struct {
    const gchar *cm_name;
    const gchar *protocol;
    const char *file;
    void (*func)(EmpathyAccountWidget *self, const gchar *filename);
  } widgets [] = {
    { "salut", "local-xmpp", "empathy-account-widget-local-xmpp.ui",
        account_widget_build_salut },
    WIDGET (gabble, jabber),
    WIDGET (butterfly, msn),
    WIDGET (haze, icq),
    WIDGET (haze, aim),
    WIDGET (haze, yahoo),
    WIDGET (haze, groupwise),
    WIDGET (idle, irc),
    WIDGET (sofiasip, sip),
  };

  cm_name = empathy_account_settings_get_cm (priv->settings);
  protocol = empathy_account_settings_get_protocol (priv->settings);

  for (i = 0 ; i < G_N_ELEMENTS (widgets); i++)
    {
      if (!tp_strdiff (widgets[i].cm_name, cm_name) &&
          !tp_strdiff (widgets[i].protocol, protocol))
        {
          gchar *filename;

          filename = empathy_file_lookup (widgets[i].file,
              "libempathy-gtk");
          widgets[i].func (self, filename);
          g_free (filename);

          break;
        }
    }

  if (i == G_N_ELEMENTS (widgets))
    {
      gchar *filename = empathy_file_lookup (
          "empathy-account-widget-generic.ui", "libempathy-gtk");
      account_widget_build_generic (self, filename);
      g_free (filename);
    }

  /* handle default focus */
  if (self->ui_details->default_focus != NULL)
    {
      GObject *default_focus_entry;

      default_focus_entry = gtk_builder_get_object
        (self->ui_details->gui, self->ui_details->default_focus);
      g_signal_connect (default_focus_entry, "realize",
          G_CALLBACK (gtk_widget_grab_focus),
          NULL);
    }

  /* handle forget button */
  if (self->ui_details->add_forget)
    {
      const gchar *password = NULL;

      priv->button_forget = GTK_WIDGET (gtk_builder_get_object
          (self->ui_details->gui, "button_forget"));
      priv->entry_password = GTK_WIDGET (gtk_builder_get_object
          (self->ui_details->gui, "entry_password"));

      password = empathy_account_settings_get_string (priv->settings,
          "password");
      gtk_widget_set_sensitive (priv->button_forget,
          !EMP_STR_EMPTY (password));

      g_signal_connect (priv->button_forget, "clicked",
          G_CALLBACK (account_widget_forget_clicked_cb),
          self);
      g_signal_connect (priv->entry_password, "changed",
          G_CALLBACK (account_widget_password_changed_cb),
          self);
    }

  /* handle apply and cancel button */
  if (!priv->simple)
    {
      GtkWidget *hbox = gtk_hbox_new (TRUE, 3);

      priv->cancel_button = gtk_button_new_from_stock (GTK_STOCK_CANCEL);

      if (priv->creating_account)
        {
          TpConnectionPresenceType state;
          priv->idle = empathy_idle_dup_singleton ();

          empathy_signal_connect_weak (priv->idle, "notify::state",
              G_CALLBACK (idle_state_change_cb), obj);

          state = empathy_idle_get_state (priv->idle);

          if (state > TP_CONNECTION_PRESENCE_TYPE_OFFLINE)
            {
              /* We are online, display a Login button */
              GtkWidget *image;

              priv->apply_button = gtk_button_new_with_mnemonic (_("L_og in"));
              image = gtk_image_new_from_stock (GTK_STOCK_CONNECT,
                  GTK_ICON_SIZE_BUTTON);
              gtk_button_set_image (GTK_BUTTON (priv->apply_button), image);
            }
          else
            {
              /* We are offline, display a Save button */
              priv->apply_button = gtk_button_new_from_stock (GTK_STOCK_SAVE);
            }
        }
      else
        {
          /* We are editing an existing account, display an Apply button */
          priv->apply_button = gtk_button_new_from_stock (GTK_STOCK_APPLY);
        }

      gtk_box_pack_end (GTK_BOX (hbox), priv->apply_button, TRUE,
          TRUE, 3);
      gtk_box_pack_end (GTK_BOX (hbox), priv->cancel_button, TRUE,
          TRUE, 3);

      gtk_box_pack_end (GTK_BOX (self->ui_details->widget), hbox, FALSE,
          FALSE, 3);

      g_signal_connect (priv->cancel_button, "clicked",
          G_CALLBACK (account_widget_cancel_clicked_cb),
          self);
      g_signal_connect (priv->apply_button, "clicked",
          G_CALLBACK (account_widget_apply_clicked_cb),
          self);
      gtk_widget_show_all (hbox);

      if (priv->creating_account)
        /* When creating an account, the user might have nothing to enter.
         * That means that no control interaction might occur,
         * so we update the control button sensitivity manually.
         */
        account_widget_handle_control_buttons_sensitivity (self);
      else
        account_widget_set_control_buttons_sensitivity (self, FALSE);
    }

  account = empathy_account_settings_get_account (priv->settings);

  if (account != NULL)
    {
      g_signal_connect (account, "notify::enabled",
          G_CALLBACK (empathy_account_widget_enabled_cb), self);
    }

  /* handle the "Enabled" checkbox. We only add it when modifying an account */
  if (!priv->creating_account && priv->table_common_settings != NULL)
    {
#ifdef HAVE_MOBLIN
      GtkWidget *w;
#endif
      guint nb_rows, nb_columns;
      gboolean is_enabled;

      is_enabled = tp_account_is_enabled (account);

#ifndef HAVE_MOBLIN
      priv->enabled_checkbox =
          gtk_check_button_new_with_label (_("Enabled"));

      gtk_toggle_button_set_active (
          GTK_TOGGLE_BUTTON (priv->enabled_checkbox), is_enabled);
#else
      /* Translators: this is used only when built on a moblin platform */
      w = gtk_label_new (_("Account:"));
      gtk_misc_set_alignment (GTK_MISC (w), 0, 0.5);

      priv->enabled_checkbox = nbtk_gtk_light_switch_new ();

      nbtk_gtk_light_switch_set_active (
          NBTK_GTK_LIGHT_SWITCH (priv->enabled_checkbox), is_enabled);

      gtk_widget_show (w);
#endif /* HAVE_MOBLIN */

      g_object_get (priv->table_common_settings, "n-rows", &nb_rows,
          "n-columns", &nb_columns, NULL);

      gtk_table_resize (GTK_TABLE (priv->table_common_settings), ++nb_rows,
          nb_columns);

#ifndef HAVE_MOBLIN
      gtk_table_attach (GTK_TABLE (priv->table_common_settings),
          priv->enabled_checkbox,
          0, nb_columns, nb_rows - 1, nb_rows,
          GTK_EXPAND | GTK_FILL, 0, 0, 0);
#else
      gtk_table_attach (GTK_TABLE (priv->table_common_settings),
          w,
          0, 1, nb_rows - 1, nb_rows,
          GTK_FILL, 0, 0, 0);
      gtk_table_attach (GTK_TABLE (priv->table_common_settings),
          priv->enabled_checkbox,
          1, nb_columns, nb_rows - 1, nb_rows,
          GTK_EXPAND | GTK_FILL, 0, 0, 0);
#endif /* HAVE_MOBLIN */

      gtk_widget_show (priv->enabled_checkbox);

#ifndef HAVE_MOBLIN
      g_signal_connect (G_OBJECT (priv->enabled_checkbox), "released",
          G_CALLBACK (account_widget_enabled_released_cb), self);
#else
      g_signal_connect (G_OBJECT (priv->enabled_checkbox), "switch-flipped",
          G_CALLBACK (account_widget_switch_flipped_cb), self);
#endif /* HAVE_MOBLIN */
    }

  /* hook up to widget destruction to unref ourselves */
  g_signal_connect (self->ui_details->widget, "destroy",
      G_CALLBACK (account_widget_destroy_cb), self);

  empathy_builder_unref_and_keep_widget (self->ui_details->gui,
      self->ui_details->widget);
  self->ui_details->gui = NULL;
}
예제 #10
0
파일: empathy.c 프로젝트: gcorvala/gsoc2008
int
main (int argc, char *argv[])
{
	guint32            startup_timestamp;
	EmpathyStatusIcon *icon;
	EmpathyDispatcher *dispatcher;
	GtkWidget         *window;
	MissionControl    *mc;
	EmpathyIdle       *idle;
	gboolean           autoconnect = TRUE;
	gboolean           no_connect = FALSE; 
	gboolean           hide_contact_list = FALSE;
	GError            *error = NULL;
	GOptionEntry       options[] = {
		{ "no-connect", 'n',
		  0, G_OPTION_ARG_NONE, &no_connect,
		  N_("Don't connect on startup"),
		  NULL },
		{ "hide-contact-list", 'h',
		  0, G_OPTION_ARG_NONE, &hide_contact_list,
		  N_("Don't show the contact list on startup"),
		  NULL },
		{ NULL }
	};

	bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
	textdomain (GETTEXT_PACKAGE);

	startup_timestamp = get_startup_timestamp ();

	if (!gtk_init_with_args (&argc, &argv,
				 _("- Empathy Instant Messenger"),
				 options, GETTEXT_PACKAGE, &error)) {
		g_warning ("Error in gtk init: %s", error->message);
		return EXIT_FAILURE;
	}

	if (g_getenv ("EMPATHY_TIMING") != NULL) {
		g_log_set_default_handler (tp_debug_timestamped_log_handler, NULL);
	}
	empathy_debug_set_flags (g_getenv ("EMPATHY_DEBUG"));
	tp_debug_divert_messages (g_getenv ("EMPATHY_LOGFILE"));

	g_set_application_name (PACKAGE_NAME);

	gtk_window_set_default_icon_name ("empathy");
	gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (),
					   PKGDATADIR G_DIR_SEPARATOR_S "icons");

        /* Setting up the bacon connection */
	connection = bacon_message_connection_new ("empathy");
	if (connection != NULL) {
		if (!bacon_message_connection_get_is_server (connection)) {
			gchar *message;

			DEBUG ("Activating existing instance");

			message = g_strdup_printf ("%" G_GUINT32_FORMAT,
						   startup_timestamp);
			bacon_message_connection_send (connection, message);

			/* We never popup a window, so tell startup-notification
			 * that we are done. */
			gdk_notify_startup_complete ();

			g_free (message);
			bacon_message_connection_free (connection);

			return EXIT_SUCCESS;
		}
	} else {
		g_warning ("Cannot create the 'empathy' bacon connection.");
	}

	/* Setting up MC */
	mc = empathy_mission_control_new ();
	g_signal_connect (mc, "ServiceEnded",
			  G_CALLBACK (service_ended_cb),
			  NULL);
	g_signal_connect (mc, "Error",
			  G_CALLBACK (operation_error_cb),
			  NULL);

	/* Setting up Idle */
	idle = empathy_idle_new ();
	empathy_idle_set_auto_away (idle, TRUE);
	use_nm_notify_cb (empathy_conf_get (), EMPATHY_PREFS_USE_NM, idle);
	empathy_conf_notify_add (empathy_conf_get (), EMPATHY_PREFS_USE_NM,
				 use_nm_notify_cb, idle);

	/* Autoconnect */
	empathy_conf_get_bool (empathy_conf_get(),
			       EMPATHY_PREFS_AUTOCONNECT,
			       &autoconnect);
	if (autoconnect && ! no_connect &&
	    empathy_idle_get_state (idle) <= MC_PRESENCE_OFFLINE) {
		empathy_idle_set_state (idle, MC_PRESENCE_AVAILABLE);
	}
	
	create_salut_account ();

	/* Setting up UI */
	window = empathy_main_window_show ();
	icon = empathy_status_icon_new (GTK_WINDOW (window), hide_contact_list);

	if (connection) {
		/* We se the callback here because we need window */
		bacon_message_connection_set_callback (connection,
						       on_bacon_message_received,
						       window);
	}

	/* Handle channels */
	dispatcher = empathy_dispatcher_new ();
	g_signal_connect (dispatcher, "dispatch-channel",
			  G_CALLBACK (dispatch_channel_cb),
			  NULL);

	gtk_main ();

	empathy_idle_set_state (idle, MC_PRESENCE_OFFLINE);

	g_object_unref (mc);
	g_object_unref (idle);
	g_object_unref (icon);
	g_object_unref (dispatcher);

	return EXIT_SUCCESS;
}
예제 #11
0
static void
presence_chooser_presence_changed_cb (EmpathyPresenceChooser *chooser)
{
	EmpathyPresenceChooserPriv *priv;
	TpConnectionPresenceType    state;
	TpConnectionPresenceType    flash_state;
	const gchar                *status;
	GtkTreeModel               *model;
	GtkTreeIter                 iter;
	gboolean valid, match_state = FALSE, match = FALSE;

	priv = GET_PRIV (chooser);

	if (priv->editing_status) {
		return;
	}

	priv->state = state = empathy_idle_get_state (priv->idle);
	status = empathy_idle_get_status (priv->idle);
	flash_state = empathy_idle_get_flash_state (priv->idle);

	/* look through the model and attempt to find a matching state */
	model = gtk_combo_box_get_model (GTK_COMBO_BOX (chooser));
	for (valid = gtk_tree_model_get_iter_first (model, &iter);
	     valid;
	     valid = gtk_tree_model_iter_next (model, &iter)) {
		int m_type;
		TpConnectionPresenceType m_state;
		char *m_status;

		gtk_tree_model_get (model, &iter,
				COL_STATE, &m_state,
				COL_TYPE, &m_type,
				-1);

		if (m_type == ENTRY_TYPE_CUSTOM ||
		    m_type == ENTRY_TYPE_SEPARATOR ||
		    m_type == ENTRY_TYPE_EDIT_CUSTOM) {
			continue;
		}
		else if (!match_state && state == m_state) {
			/* we are now in the section that can contain our
			 * match */
			match_state = TRUE;
		}
		else if (match_state && state != m_state) {
			/* we have passed the section that can contain our
			 * match */
			break;
		}

		gtk_tree_model_get (model, &iter,
				COL_STATUS_TEXT, &m_status,
				-1);

		match = !tp_strdiff (status, m_status);

		g_free (m_status);

		if (match) break;

	}

	if (match) {
		priv->block_changed++;
		gtk_combo_box_set_active_iter (GTK_COMBO_BOX (chooser), &iter);
		presence_chooser_set_favorite_icon (chooser);
		priv->block_changed--;
	}
	else {
		ui_set_custom_state (chooser, state, status);
	}

	if (flash_state != TP_CONNECTION_PRESENCE_TYPE_UNSET) {
		presence_chooser_flash_start (chooser, state, flash_state);
	}
	else {
		presence_chooser_flash_stop (chooser, state);
	}
}