Blame src/goabackend/goatelepathyprovider.c

Packit Service c6b9b0
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
Packit Service c6b9b0
/*
Packit Service c6b9b0
 * Copyright © 2012 – 2017 Red Hat, Inc.
Packit Service c6b9b0
 * Copyright © 2013 Intel Corporation
Packit Service c6b9b0
 *
Packit Service c6b9b0
 * This library is free software; you can redistribute it and/or
Packit Service c6b9b0
 * modify it under the terms of the GNU Lesser General Public
Packit Service c6b9b0
 * License as published by the Free Software Foundation; either
Packit Service c6b9b0
 * version 2 of the License, or (at your option) any later version.
Packit Service c6b9b0
 *
Packit Service c6b9b0
 * This library is distributed in the hope that it will be useful,
Packit Service c6b9b0
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service c6b9b0
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service c6b9b0
 * Lesser General Public License for more details.
Packit Service c6b9b0
 *
Packit Service c6b9b0
 * You should have received a copy of the GNU Lesser General
Packit Service c6b9b0
 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
Packit Service c6b9b0
 */
Packit Service c6b9b0
Packit Service c6b9b0
#include "config.h"
Packit Service c6b9b0
#include <glib/gi18n-lib.h>
Packit Service c6b9b0
#include <tp-account-widgets/tpaw-account-widget.h>
Packit Service c6b9b0
#include <tp-account-widgets/tpaw-user-info.h>
Packit Service c6b9b0
#include <tp-account-widgets/tpaw-utils.h>
Packit Service c6b9b0
Packit Service c6b9b0
#include "goaprovider.h"
Packit Service c6b9b0
#include "goaprovider-priv.h"
Packit Service c6b9b0
#include "goatelepathyprovider.h"
Packit Service c6b9b0
#include "goatpaccountlinker.h"
Packit Service c6b9b0
#include "goaobjectskeletonutils.h"
Packit Service c6b9b0
#include "goautils.h"
Packit Service c6b9b0
Packit Service c6b9b0
typedef struct _GoaTelepathyProviderPrivate GoaTelepathyProviderPrivate;
Packit Service c6b9b0
Packit Service c6b9b0
struct _GoaTelepathyProviderPrivate
Packit Service c6b9b0
{
Packit Service c6b9b0
  TpawProtocol *protocol;
Packit Service c6b9b0
  gchar *protocol_name;
Packit Service c6b9b0
  gchar *provider_type;
Packit Service c6b9b0
};
Packit Service c6b9b0
Packit Service c6b9b0
enum {
Packit Service c6b9b0
  PROP_0,
Packit Service c6b9b0
  PROP_PROTOCOL,
Packit Service c6b9b0
  PROP_PROTOCOL_NAME,
Packit Service c6b9b0
  NUM_PROPERTIES
Packit Service c6b9b0
};
Packit Service c6b9b0
Packit Service c6b9b0
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
Packit Service c6b9b0
Packit Service c6b9b0
struct _GoaTelepathyProvider
Packit Service c6b9b0
{
Packit Service c6b9b0
  GoaProvider parent_instance;
Packit Service c6b9b0
  GoaTelepathyProviderPrivate *priv;
Packit Service c6b9b0
};
Packit Service c6b9b0
Packit Service c6b9b0
typedef struct _GoaTelepathyProviderClass GoaTelepathyProviderClass;
Packit Service c6b9b0
Packit Service c6b9b0
struct _GoaTelepathyProviderClass
Packit Service c6b9b0
{
Packit Service c6b9b0
  GoaProviderClass parent_class;
Packit Service c6b9b0
};
Packit Service c6b9b0
Packit Service c6b9b0
G_DEFINE_TYPE (GoaTelepathyProvider, goa_telepathy_provider, GOA_TYPE_PROVIDER);
Packit Service c6b9b0
Packit Service c6b9b0
/* ---------------------------------------------------------------------------------------------------- */
Packit Service c6b9b0
Packit Service c6b9b0
static GoaTpAccountLinker *tp_linker = NULL;
Packit Service c6b9b0
static guint name_watcher_id = 0;
Packit Service c6b9b0
Packit Service c6b9b0
/* ---------------------------------------------------------------------------------------------------- */
Packit Service c6b9b0
Packit Service c6b9b0
/* Telepathy / telepathy-account widgets utility functions. */
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
account_settings_ready_cb (TpawAccountSettings *settings,
Packit Service c6b9b0
                           GParamSpec          *pspec,
Packit Service c6b9b0
                           gpointer             user_data)
Packit Service c6b9b0
{
Packit Service c6b9b0
  GMainLoop *loop = user_data;
Packit Service c6b9b0
Packit Service c6b9b0
  g_main_loop_quit (loop);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
wait_for_account_settings_ready (TpawAccountSettings *settings,
Packit Service c6b9b0
                                 GMainLoop           *loop)
Packit Service c6b9b0
{
Packit Service c6b9b0
  if (!tpaw_account_settings_is_ready (settings))
Packit Service c6b9b0
    {
Packit Service c6b9b0
      g_signal_connect (settings, "notify::ready",
Packit Service c6b9b0
          G_CALLBACK (account_settings_ready_cb), loop);
Packit Service c6b9b0
      g_main_loop_run (loop);
Packit Service c6b9b0
    }
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
typedef struct
Packit Service c6b9b0
{
Packit Service c6b9b0
  GMainLoop *loop;
Packit Service c6b9b0
  GError *error;
Packit Service c6b9b0
  gboolean ret;
Packit Service c6b9b0
} PrepareTpProxyData;
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
proxy_prepared_cb (GObject      *object,
Packit Service c6b9b0
                   GAsyncResult *res,
Packit Service c6b9b0
                   gpointer      user_data)
Packit Service c6b9b0
{
Packit Service c6b9b0
  PrepareTpProxyData *data = user_data;
Packit Service c6b9b0
Packit Service c6b9b0
  data->ret = tp_proxy_prepare_finish (object, res, &data->error);
Packit Service c6b9b0
  g_main_loop_quit (data->loop);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static gboolean
Packit Service c6b9b0
prepare_tp_proxy (gpointer       proxy,
Packit Service c6b9b0
                  const GQuark  *features,
Packit Service c6b9b0
                  GMainLoop     *loop,
Packit Service c6b9b0
                  GError       **error)
Packit Service c6b9b0
{
Packit Service c6b9b0
  PrepareTpProxyData data = { NULL, };
Packit Service c6b9b0
Packit Service c6b9b0
  data.loop = loop;
Packit Service c6b9b0
Packit Service c6b9b0
  tp_proxy_prepare_async (proxy, features, proxy_prepared_cb, &data);
Packit Service c6b9b0
  g_main_loop_run (data.loop);
Packit Service c6b9b0
Packit Service c6b9b0
  if (data.error != NULL)
Packit Service c6b9b0
    {
Packit Service c6b9b0
      g_propagate_error (error, data.error);
Packit Service c6b9b0
      g_clear_error (&data.error);
Packit Service c6b9b0
    }
Packit Service c6b9b0
Packit Service c6b9b0
  return data.ret;
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static TpAccount *
Packit Service c6b9b0
find_tp_account (GoaObject  *goa_object,
Packit Service c6b9b0
                 GMainLoop  *loop,
Packit Service c6b9b0
                 GError    **out_error)
Packit Service c6b9b0
{
Packit Service c6b9b0
  GoaAccount *goa_account = NULL;
Packit Service c6b9b0
  const gchar *id = NULL;
Packit Service c6b9b0
  TpAccountManager *account_manager;
Packit Service c6b9b0
  GList *tp_accounts = NULL;
Packit Service c6b9b0
  GList *l = NULL;
Packit Service c6b9b0
  TpAccount *tp_account = NULL;
Packit Service c6b9b0
  GError *error = NULL;
Packit Service c6b9b0
Packit Service c6b9b0
  goa_account = goa_object_peek_account (goa_object);
Packit Service c6b9b0
  id = goa_account_get_identity (goa_account);
Packit Service c6b9b0
Packit Service c6b9b0
  account_manager = tp_account_manager_dup ();
Packit Service c6b9b0
  if (!prepare_tp_proxy (account_manager, NULL, loop, &error))
Packit Service c6b9b0
    goto out;
Packit Service c6b9b0
Packit Service c6b9b0
  tp_accounts = tp_account_manager_dup_valid_accounts (account_manager);
Packit Service c6b9b0
  for (l = tp_accounts; l != NULL; l = l->next)
Packit Service c6b9b0
    {
Packit Service c6b9b0
      if (g_strcmp0 (tp_proxy_get_object_path (l->data), id) == 0)
Packit Service c6b9b0
        {
Packit Service c6b9b0
          tp_account = g_object_ref (l->data);
Packit Service c6b9b0
          break;
Packit Service c6b9b0
        }
Packit Service c6b9b0
    }
Packit Service c6b9b0
Packit Service c6b9b0
  if (tp_account == NULL)
Packit Service c6b9b0
    {
Packit Service c6b9b0
      g_set_error (&error,
Packit Service c6b9b0
                   GOA_ERROR,
Packit Service c6b9b0
                   GOA_ERROR_FAILED,
Packit Service c6b9b0
                   _("Telepathy chat account not found"));
Packit Service c6b9b0
      goto out;
Packit Service c6b9b0
    }
Packit Service c6b9b0
Packit Service c6b9b0
out:
Packit Service c6b9b0
  if (error != NULL)
Packit Service c6b9b0
    g_propagate_error (out_error, error);
Packit Service c6b9b0
Packit Service c6b9b0
  g_clear_error (&error);
Packit Service c6b9b0
  g_clear_object (&account_manager);
Packit Service c6b9b0
  g_list_free_full (tp_accounts, g_object_unref);
Packit Service c6b9b0
Packit Service c6b9b0
  return tp_account;
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
/* ---------------------------------------------------------------------------------------------------- */
Packit Service c6b9b0
Packit Service c6b9b0
static const gchar *
Packit Service c6b9b0
get_provider_type (GoaProvider *provider)
Packit Service c6b9b0
{
Packit Service c6b9b0
  GoaTelepathyProviderPrivate *priv = GOA_TELEPATHY_PROVIDER (provider)->priv;
Packit Service c6b9b0
  return priv->provider_type;
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static gchar *
Packit Service c6b9b0
get_provider_name (GoaProvider *provider,
Packit Service c6b9b0
                   GoaObject   *object)
Packit Service c6b9b0
{
Packit Service c6b9b0
  GoaTelepathyProviderPrivate *priv = GOA_TELEPATHY_PROVIDER (provider)->priv;
Packit Service c6b9b0
Packit Service c6b9b0
  return g_strdup (tpaw_protocol_name_to_display_name (priv->protocol_name));
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static GIcon *
Packit Service c6b9b0
get_provider_icon (GoaProvider *provider,
Packit Service c6b9b0
                   GoaObject   *object)
Packit Service c6b9b0
{
Packit Service c6b9b0
  GoaTelepathyProviderPrivate *priv = GOA_TELEPATHY_PROVIDER (provider)->priv;
Packit Service c6b9b0
  const gchar *icon_names[3];
Packit Service c6b9b0
  gchar *icon_name;
Packit Service c6b9b0
  GIcon *icon;
Packit Service c6b9b0
Packit Service c6b9b0
  /* Use symbolic icons for generic protocols. Use icons for the
Packit Service c6b9b0
   * branded ones if it matches their visual identity. Otherwise do
Packit Service c6b9b0
   * not use an icon.
Packit Service c6b9b0
   */
Packit Service c6b9b0
  if (g_strcmp0 (priv->protocol_name, "irc") == 0
Packit Service c6b9b0
      || g_strcmp0 (priv->protocol_name, "jabber") == 0
Packit Service c6b9b0
      || g_strcmp0 (priv->protocol_name, "local-xmpp") == 0
Packit Service c6b9b0
      || g_strcmp0 (priv->protocol_name, "sip") == 0)
Packit Service c6b9b0
    {
Packit Service c6b9b0
      icon_name = g_strdup ("user-available-symbolic");
Packit Service c6b9b0
    }
Packit Service c6b9b0
  else if (g_strcmp0 (priv->protocol_name, "aim") == 0
Packit Service c6b9b0
           || g_strcmp0 (priv->protocol_name, "gadugadu") == 0
Packit Service c6b9b0
           || g_strcmp0 (priv->protocol_name, "silc") == 0)
Packit Service c6b9b0
    {
Packit Service c6b9b0
      icon_name = tpaw_protocol_icon_name (priv->protocol_name);
Packit Service c6b9b0
    }
Packit Service c6b9b0
  else
Packit Service c6b9b0
    {
Packit Service c6b9b0
      icon_name = g_strdup ("goa-account");
Packit Service c6b9b0
    }
Packit Service c6b9b0
Packit Service c6b9b0
  icon_names[0] = icon_name;
Packit Service c6b9b0
  /* If the icon doesn't exist, just try with the default icon. */
Packit Service c6b9b0
  icon_names[1] = "goa-account";
Packit Service c6b9b0
  icon_names[2] = NULL;
Packit Service c6b9b0
  icon = g_themed_icon_new_from_names ((gchar **) icon_names, -1);
Packit Service c6b9b0
Packit Service c6b9b0
  g_free (icon_name);
Packit Service c6b9b0
Packit Service c6b9b0
  return icon;
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static GoaProviderGroup
Packit Service c6b9b0
get_provider_group (GoaProvider *provider)
Packit Service c6b9b0
{
Packit Service c6b9b0
  return GOA_PROVIDER_GROUP_CHAT;
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static GoaProviderFeatures
Packit Service c6b9b0
get_provider_features (GoaProvider *provider)
Packit Service c6b9b0
{
Packit Service c6b9b0
  return GOA_PROVIDER_FEATURE_CHAT;
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
/* ---------------------------------------------------------------------------------------------------- */
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
on_name_acquired (GDBusConnection *connection,
Packit Service c6b9b0
                  const gchar     *name,
Packit Service c6b9b0
                  const gchar     *name_owner,
Packit Service c6b9b0
                  gpointer         user_data)
Packit Service c6b9b0
{
Packit Service c6b9b0
  tp_linker = goa_tp_account_linker_new ();
Packit Service c6b9b0
  g_bus_unwatch_name (name_watcher_id);
Packit Service c6b9b0
  name_watcher_id = 0;
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
initialize (GoaProvider *provider)
Packit Service c6b9b0
{
Packit Service c6b9b0
  static gsize once_init_value = 0;
Packit Service c6b9b0
Packit Service c6b9b0
  if (g_once_init_enter (&once_init_value))
Packit Service c6b9b0
    {
Packit Service c6b9b0
      name_watcher_id = g_bus_watch_name (G_BUS_TYPE_SESSION,
Packit Service c6b9b0
                                          "org.gnome.OnlineAccounts",
Packit Service c6b9b0
                                          G_BUS_NAME_WATCHER_FLAGS_NONE,
Packit Service c6b9b0
                                          on_name_acquired,
Packit Service c6b9b0
                                          NULL,
Packit Service c6b9b0
                                          NULL,
Packit Service c6b9b0
                                          NULL);
Packit Service c6b9b0
Packit Service c6b9b0
      g_once_init_leave (&once_init_value, 1);
Packit Service c6b9b0
    }
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
/* ---------------------------------------------------------------------------------------------------- */
Packit Service c6b9b0
Packit Service c6b9b0
typedef struct
Packit Service c6b9b0
{
Packit Service c6b9b0
  GMainLoop *loop;
Packit Service c6b9b0
  GoaObject *ret;
Packit Service c6b9b0
  GError *error;
Packit Service c6b9b0
Packit Service c6b9b0
  GoaTelepathyProvider *provider;
Packit Service c6b9b0
  GtkDialog *dialog;
Packit Service c6b9b0
  GtkBox *vbox;
Packit Service c6b9b0
  gboolean close_received;
Packit Service c6b9b0
Packit Service c6b9b0
  TpAccount *tp_account;
Packit Service c6b9b0
Packit Service c6b9b0
  GoaClient *goa_client;
Packit Service c6b9b0
  guint goa_account_added_id;
Packit Service c6b9b0
} AddAccountData;
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
quit_main_loop_if_finished (AddAccountData *data)
Packit Service c6b9b0
{
Packit Service c6b9b0
  if (data->ret != NULL && data->close_received)
Packit Service c6b9b0
    g_main_loop_quit (data->loop);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
run_main_loop_if_needed (AddAccountData *data)
Packit Service c6b9b0
{
Packit Service c6b9b0
  if (data->ret == NULL || !data->close_received)
Packit Service c6b9b0
    g_main_loop_run (data->loop);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static gboolean
Packit Service c6b9b0
check_goa_object_match (AddAccountData *data,
Packit Service c6b9b0
                        GoaObject      *goa_object)
Packit Service c6b9b0
{
Packit Service c6b9b0
  GoaTelepathyProviderPrivate *priv = data->provider->priv;
Packit Service c6b9b0
  GoaAccount *goa_account = NULL;
Packit Service c6b9b0
  const gchar *provider_type = NULL;
Packit Service c6b9b0
  const gchar *goa_id = NULL;
Packit Service c6b9b0
  const gchar *tp_id = NULL;
Packit Service c6b9b0
Packit Service c6b9b0
  if (data->tp_account == NULL)
Packit Service c6b9b0
    {
Packit Service c6b9b0
      /* Still waiting for the creation of the TpAccount */
Packit Service c6b9b0
      return FALSE;
Packit Service c6b9b0
    }
Packit Service c6b9b0
Packit Service c6b9b0
  goa_account = goa_object_peek_account (goa_object);
Packit Service c6b9b0
  provider_type = goa_account_get_provider_type (goa_account);
Packit Service c6b9b0
  if (g_strcmp0 (provider_type, priv->provider_type) != 0)
Packit Service c6b9b0
    return FALSE;
Packit Service c6b9b0
Packit Service c6b9b0
  /* The backend-specific identity is set to the object path of the
Packit Service c6b9b0
   * corresponding Telepathy account object. */
Packit Service c6b9b0
  goa_id = goa_account_get_identity (goa_account);
Packit Service c6b9b0
  tp_id = tp_proxy_get_object_path (TP_PROXY (data->tp_account));
Packit Service c6b9b0
  if (g_strcmp0 (goa_id, tp_id) == 0)
Packit Service c6b9b0
    {
Packit Service c6b9b0
      /* Found it! */
Packit Service c6b9b0
      data->ret = g_object_ref (goa_object);
Packit Service c6b9b0
      quit_main_loop_if_finished (data);
Packit Service c6b9b0
      return TRUE;
Packit Service c6b9b0
    }
Packit Service c6b9b0
Packit Service c6b9b0
  return FALSE;
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static gboolean
Packit Service c6b9b0
check_existing_goa_accounts (AddAccountData *data)
Packit Service c6b9b0
{
Packit Service c6b9b0
  GList *goa_accounts = NULL;
Packit Service c6b9b0
  GList *l = NULL;
Packit Service c6b9b0
  gboolean found = FALSE;
Packit Service c6b9b0
Packit Service c6b9b0
  if (data->tp_account == NULL)
Packit Service c6b9b0
    return FALSE;
Packit Service c6b9b0
Packit Service c6b9b0
  goa_accounts = goa_client_get_accounts (data->goa_client);
Packit Service c6b9b0
  for (l = goa_accounts; l != NULL; l = l->next)
Packit Service c6b9b0
    {
Packit Service c6b9b0
      if (check_goa_object_match (data, l->data))
Packit Service c6b9b0
        {
Packit Service c6b9b0
          found = TRUE;
Packit Service c6b9b0
          break;
Packit Service c6b9b0
        }
Packit Service c6b9b0
    }
Packit Service c6b9b0
  g_list_free_full (goa_accounts, g_object_unref);
Packit Service c6b9b0
Packit Service c6b9b0
  return found;
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
tp_account_created_cb (TpawAccountWidget *widget,
Packit Service c6b9b0
                       TpAccount         *tp_account,
Packit Service c6b9b0
                       AddAccountData    *data)
Packit Service c6b9b0
{
Packit Service c6b9b0
  g_assert (data->tp_account == NULL);
Packit Service c6b9b0
  data->tp_account = g_object_ref (tp_account);
Packit Service c6b9b0
Packit Service c6b9b0
  check_existing_goa_accounts (data);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
goa_account_added_cb (GoaClient *client,
Packit Service c6b9b0
                      GoaObject *goa_object,
Packit Service c6b9b0
                      gpointer   user_data)
Packit Service c6b9b0
{
Packit Service c6b9b0
  AddAccountData *data = user_data;
Packit Service c6b9b0
Packit Service c6b9b0
  check_goa_object_match (data, goa_object);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
account_widget_close_cb (TpawAccountWidget *widget,
Packit Service c6b9b0
                         GtkResponseType    response,
Packit Service c6b9b0
                         AddAccountData    *data)
Packit Service c6b9b0
{
Packit Service c6b9b0
  data->close_received = TRUE;
Packit Service c6b9b0
  quit_main_loop_if_finished (data);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static GoaObject *
Packit Service c6b9b0
add_account (GoaProvider  *provider,
Packit Service c6b9b0
             GoaClient    *client,
Packit Service c6b9b0
             GtkDialog    *dialog,
Packit Service c6b9b0
             GtkBox       *vbox,
Packit Service c6b9b0
             GError      **error)
Packit Service c6b9b0
{
Packit Service c6b9b0
  GoaTelepathyProviderPrivate *priv = GOA_TELEPATHY_PROVIDER (provider)->priv;
Packit Service c6b9b0
  AddAccountData data;
Packit Service c6b9b0
  TpawAccountSettings *settings = NULL;
Packit Service c6b9b0
  TpawAccountWidget *account_widget = NULL;
Packit Service c6b9b0
  gint response;
Packit Service c6b9b0
  gint width;
Packit Service c6b9b0
Packit Service c6b9b0
  settings = tpaw_protocol_create_account_settings (priv->protocol);
Packit Service c6b9b0
  if (settings == NULL)
Packit Service c6b9b0
    {
Packit Service c6b9b0
      g_set_error (&data.error,
Packit Service c6b9b0
                   GOA_ERROR,
Packit Service c6b9b0
                   GOA_ERROR_FAILED,
Packit Service c6b9b0
                   _("Failed to create a user interface for %s"),
Packit Service c6b9b0
                   priv->protocol != NULL ?
Packit Service c6b9b0
                      tpaw_protocol_get_protocol_name (priv->protocol) :
Packit Service c6b9b0
                      "(null)");
Packit Service c6b9b0
      return NULL;
Packit Service c6b9b0
    }
Packit Service c6b9b0
Packit Service c6b9b0
  memset (&data, 0, sizeof (AddAccountData));
Packit Service c6b9b0
  data.loop = g_main_loop_new (NULL, FALSE);
Packit Service c6b9b0
  data.error = NULL;
Packit Service c6b9b0
  data.provider = GOA_TELEPATHY_PROVIDER (provider);
Packit Service c6b9b0
  data.dialog = dialog;
Packit Service c6b9b0
  data.vbox = vbox;
Packit Service c6b9b0
Packit Service c6b9b0
  data.goa_client = client;
Packit Service c6b9b0
  data.goa_account_added_id = g_signal_connect (data.goa_client,
Packit Service c6b9b0
      "account-added", G_CALLBACK (goa_account_added_cb), &data);
Packit Service c6b9b0
Packit Service c6b9b0
  wait_for_account_settings_ready (settings, data.loop);
Packit Service c6b9b0
Packit Service c6b9b0
  account_widget = tpaw_account_widget_new_for_protocol (settings,
Packit Service c6b9b0
      dialog, TRUE);
Packit Service c6b9b0
  gtk_container_add (GTK_CONTAINER (vbox), GTK_WIDGET (account_widget));
Packit Service c6b9b0
  gtk_widget_show (GTK_WIDGET (account_widget));
Packit Service c6b9b0
  g_signal_connect (account_widget, "account-created",
Packit Service c6b9b0
      G_CALLBACK (tp_account_created_cb), &data);
Packit Service c6b9b0
  g_signal_connect (account_widget, "close",
Packit Service c6b9b0
      G_CALLBACK (account_widget_close_cb), &data);
Packit Service c6b9b0
Packit Service c6b9b0
  /* The dialog now contains a lot of empty space between the account widget
Packit Service c6b9b0
   * and the buttons. We force it's vertical size to be just right to fit the
Packit Service c6b9b0
   * widget. */
Packit Service c6b9b0
  gtk_window_get_size (GTK_WINDOW (dialog), &width, NULL);
Packit Service c6b9b0
  gtk_window_set_default_size (GTK_WINDOW (dialog), width, -1);
Packit Service c6b9b0
Packit Service c6b9b0
  response = gtk_dialog_run (GTK_DIALOG (dialog));
Packit Service c6b9b0
  if (response != GTK_RESPONSE_OK && response != GTK_RESPONSE_APPLY)
Packit Service c6b9b0
    {
Packit Service c6b9b0
      g_set_error (&data.error,
Packit Service c6b9b0
                   GOA_ERROR,
Packit Service c6b9b0
                   GOA_ERROR_DIALOG_DISMISSED,
Packit Service c6b9b0
                   _("Dialog was dismissed"));
Packit Service c6b9b0
      goto out;
Packit Service c6b9b0
    }
Packit Service c6b9b0
Packit Service c6b9b0
  if (data.error != NULL)
Packit Service c6b9b0
    {
Packit Service c6b9b0
      /* An error could have been set by a callback */
Packit Service c6b9b0
      goto out;
Packit Service c6b9b0
    }
Packit Service c6b9b0
Packit Service c6b9b0
  /* We wait for the account to be created */
Packit Service c6b9b0
  run_main_loop_if_needed (&data);
Packit Service c6b9b0
Packit Service c6b9b0
out:
Packit Service c6b9b0
  if (data.error != NULL)
Packit Service c6b9b0
    g_propagate_error (error, data.error);
Packit Service c6b9b0
  else
Packit Service c6b9b0
    g_assert (data.ret != NULL);
Packit Service c6b9b0
Packit Service c6b9b0
  if (data.goa_account_added_id)
Packit Service c6b9b0
    g_signal_handler_disconnect (data.goa_client, data.goa_account_added_id);
Packit Service c6b9b0
Packit Service c6b9b0
  g_clear_pointer (&data.loop, g_main_loop_unref);
Packit Service c6b9b0
  g_clear_object (&data.tp_account);
Packit Service c6b9b0
Packit Service c6b9b0
  return data.ret;
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
/* ---------------------------------------------------------------------------------------------------- */
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
account_dialog_widget_cancelled_cb (TpawAccountWidget *account_widget,
Packit Service c6b9b0
                                    gpointer           user_data)
Packit Service c6b9b0
{
Packit Service c6b9b0
  GError **error = user_data;
Packit Service c6b9b0
Packit Service c6b9b0
  g_set_error (error,
Packit Service c6b9b0
               GOA_ERROR,
Packit Service c6b9b0
               GOA_ERROR_DIALOG_DISMISSED,
Packit Service c6b9b0
               _("Dialog was dismissed"));
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static gboolean
Packit Service c6b9b0
edit_connection_parameters (GoaObject  *goa_object,
Packit Service c6b9b0
                            GtkWindow  *parent,
Packit Service c6b9b0
                            GError    **out_error)
Packit Service c6b9b0
{
Packit Service c6b9b0
  GMainLoop *loop = NULL;
Packit Service c6b9b0
  TpAccount *tp_account = NULL;
Packit Service c6b9b0
  TpawAccountSettings *settings = NULL;
Packit Service c6b9b0
  GtkWidget *dialog = NULL;
Packit Service c6b9b0
  TpawAccountWidget *account_widget = NULL;
Packit Service c6b9b0
  GtkWidget *content_area = NULL;
Packit Service c6b9b0
  gboolean ret;
Packit Service c6b9b0
  GError *error = NULL;
Packit Service c6b9b0
Packit Service c6b9b0
  loop = g_main_loop_new (NULL, FALSE);
Packit Service c6b9b0
Packit Service c6b9b0
  tp_account = find_tp_account (goa_object, loop, &error);
Packit Service c6b9b0
  if (tp_account == NULL)
Packit Service c6b9b0
    goto out;
Packit Service c6b9b0
Packit Service c6b9b0
  settings = tpaw_account_settings_new_for_account (tp_account);
Packit Service c6b9b0
  wait_for_account_settings_ready (settings, loop);
Packit Service c6b9b0
Packit Service c6b9b0
  dialog = gtk_dialog_new_with_buttons (_("Connection Settings"),
Packit Service c6b9b0
      parent,
Packit Service c6b9b0
      GTK_DIALOG_MODAL
Packit Service c6b9b0
      | GTK_DIALOG_DESTROY_WITH_PARENT
Packit Service c6b9b0
      | GTK_DIALOG_USE_HEADER_BAR,
Packit Service c6b9b0
      NULL, NULL);
Packit Service c6b9b0
  gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
Packit Service c6b9b0
Packit Service c6b9b0
  account_widget = tpaw_account_widget_new_for_protocol (settings,
Packit Service c6b9b0
      GTK_DIALOG (dialog), FALSE);
Packit Service c6b9b0
  gtk_widget_set_margin_end (GTK_WIDGET (account_widget), 6);
Packit Service c6b9b0
  gtk_widget_set_margin_start (GTK_WIDGET (account_widget), 6);
Packit Service c6b9b0
  gtk_widget_set_margin_top (GTK_WIDGET (account_widget), 6);
Packit Service c6b9b0
  g_signal_connect (account_widget, "cancelled",
Packit Service c6b9b0
      G_CALLBACK (account_dialog_widget_cancelled_cb), &error);
Packit Service c6b9b0
  g_signal_connect_swapped (account_widget, "close",
Packit Service c6b9b0
      G_CALLBACK (g_main_loop_quit), loop);
Packit Service c6b9b0
Packit Service c6b9b0
  content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
Packit Service c6b9b0
  gtk_box_pack_start (GTK_BOX (content_area), GTK_WIDGET (account_widget),
Packit Service c6b9b0
      TRUE, TRUE, 0);
Packit Service c6b9b0
Packit Service c6b9b0
  gtk_widget_show (GTK_WIDGET (account_widget));
Packit Service c6b9b0
  gtk_widget_show (dialog);
Packit Service c6b9b0
Packit Service c6b9b0
  /* Wait for the dialog to be dismissed */
Packit Service c6b9b0
  g_main_loop_run (loop);
Packit Service c6b9b0
Packit Service c6b9b0
  gtk_widget_destroy (dialog);
Packit Service c6b9b0
Packit Service c6b9b0
out:
Packit Service c6b9b0
  if (error != NULL)
Packit Service c6b9b0
    {
Packit Service c6b9b0
      g_propagate_error (out_error, error);
Packit Service c6b9b0
      ret = FALSE;
Packit Service c6b9b0
    }
Packit Service c6b9b0
  else
Packit Service c6b9b0
    {
Packit Service c6b9b0
      ret = TRUE;
Packit Service c6b9b0
    }
Packit Service c6b9b0
Packit Service c6b9b0
  g_clear_object (&settings);
Packit Service c6b9b0
  g_clear_object (&tp_account);
Packit Service c6b9b0
  g_clear_pointer (&loop, g_main_loop_unref);
Packit Service c6b9b0
Packit Service c6b9b0
  return ret;
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static gboolean
Packit Service c6b9b0
refresh_account (GoaProvider  *provider,
Packit Service c6b9b0
                 GoaClient    *client,
Packit Service c6b9b0
                 GoaObject    *object,
Packit Service c6b9b0
                 GtkWindow    *parent,
Packit Service c6b9b0
                 GError      **error)
Packit Service c6b9b0
{
Packit Service c6b9b0
  return edit_connection_parameters (object, parent, error);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
/* ---------------------------------------------------------------------------------------------------- */
Packit Service c6b9b0
Packit Service c6b9b0
typedef struct
Packit Service c6b9b0
{
Packit Service c6b9b0
  GMainLoop *loop;
Packit Service c6b9b0
  GError *error;
Packit Service c6b9b0
} EditPersonalDetailsData;
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
user_info_apply_cb (GObject      *object,
Packit Service c6b9b0
                    GAsyncResult *res,
Packit Service c6b9b0
                    gpointer      user_data)
Packit Service c6b9b0
{
Packit Service c6b9b0
  EditPersonalDetailsData *data = user_data;
Packit Service c6b9b0
Packit Service c6b9b0
  tpaw_user_info_apply_finish (TPAW_USER_INFO (object), res, &data->error);
Packit Service c6b9b0
  g_main_loop_quit (data->loop);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static gboolean
Packit Service c6b9b0
personal_details_timeout_cb (gpointer user_data)
Packit Service c6b9b0
{
Packit Service c6b9b0
  EditPersonalDetailsData *data = user_data;
Packit Service c6b9b0
Packit Service c6b9b0
  g_main_loop_quit (data->loop);
Packit Service c6b9b0
  return G_SOURCE_REMOVE;
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static gboolean
Packit Service c6b9b0
edit_personal_details (GoaObject  *goa_object,
Packit Service c6b9b0
                       GtkWindow  *parent,
Packit Service c6b9b0
                       GError    **error)
Packit Service c6b9b0
{
Packit Service c6b9b0
  EditPersonalDetailsData data;
Packit Service c6b9b0
  TpAccount *tp_account = NULL;
Packit Service c6b9b0
  GtkWidget *dialog = NULL;
Packit Service c6b9b0
  GtkWidget *user_info = NULL;
Packit Service c6b9b0
  GtkWidget *content_area = NULL;
Packit Service c6b9b0
  gint response;
Packit Service c6b9b0
  gboolean ret = FALSE;
Packit Service c6b9b0
Packit Service c6b9b0
  memset (&data, 0, sizeof (EditPersonalDetailsData));
Packit Service c6b9b0
  data.loop = g_main_loop_new (NULL, FALSE);
Packit Service c6b9b0
Packit Service c6b9b0
  tp_account = find_tp_account (goa_object, data.loop, &data.error);
Packit Service c6b9b0
  if (tp_account == NULL)
Packit Service c6b9b0
    goto out;
Packit Service c6b9b0
Packit Service c6b9b0
  dialog = gtk_dialog_new_with_buttons (_("Personal Details"),
Packit Service c6b9b0
      parent,
Packit Service c6b9b0
      GTK_DIALOG_MODAL
Packit Service c6b9b0
      | GTK_DIALOG_DESTROY_WITH_PARENT
Packit Service c6b9b0
      | GTK_DIALOG_USE_HEADER_BAR,
Packit Service c6b9b0
      _("_Cancel"), GTK_RESPONSE_CANCEL,
Packit Service c6b9b0
      _("_OK"), GTK_RESPONSE_OK,
Packit Service c6b9b0
      NULL);
Packit Service c6b9b0
  gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
Packit Service c6b9b0
Packit Service c6b9b0
  user_info = tpaw_user_info_new (tp_account);
Packit Service c6b9b0
  gtk_widget_set_margin_end (user_info, 6);
Packit Service c6b9b0
  gtk_widget_set_margin_start (user_info, 6);
Packit Service c6b9b0
  gtk_widget_set_margin_top (user_info, 6);
Packit Service c6b9b0
  gtk_widget_show (user_info);
Packit Service c6b9b0
Packit Service c6b9b0
  content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
Packit Service c6b9b0
  gtk_box_pack_start (GTK_BOX (content_area), user_info, TRUE, TRUE, 0);
Packit Service c6b9b0
Packit Service c6b9b0
  g_timeout_add (100, personal_details_timeout_cb, &data);
Packit Service c6b9b0
  g_main_loop_run (data.loop);
Packit Service c6b9b0
Packit Service c6b9b0
  response = gtk_dialog_run (GTK_DIALOG (dialog));
Packit Service c6b9b0
  if (response == GTK_RESPONSE_OK)
Packit Service c6b9b0
    {
Packit Service c6b9b0
      tpaw_user_info_apply_async (TPAW_USER_INFO (user_info),
Packit Service c6b9b0
          user_info_apply_cb, &data);
Packit Service c6b9b0
      g_main_loop_run (data.loop);
Packit Service c6b9b0
      if (data.error != NULL)
Packit Service c6b9b0
        goto out;
Packit Service c6b9b0
    }
Packit Service c6b9b0
  else
Packit Service c6b9b0
    {
Packit Service c6b9b0
      g_set_error (&data.error,
Packit Service c6b9b0
                   GOA_ERROR,
Packit Service c6b9b0
                   GOA_ERROR_DIALOG_DISMISSED,
Packit Service c6b9b0
                   _("Dialog was dismissed"));
Packit Service c6b9b0
      goto out;
Packit Service c6b9b0
    }
Packit Service c6b9b0
Packit Service c6b9b0
  ret = TRUE;
Packit Service c6b9b0
Packit Service c6b9b0
out:
Packit Service c6b9b0
  if (data.error != NULL)
Packit Service c6b9b0
    {
Packit Service c6b9b0
      g_propagate_error (error, data.error);
Packit Service c6b9b0
    }
Packit Service c6b9b0
Packit Service c6b9b0
  g_clear_pointer (&dialog, gtk_widget_destroy);
Packit Service c6b9b0
  g_clear_object (&tp_account);
Packit Service c6b9b0
  g_clear_pointer (&data.loop, g_main_loop_unref);
Packit Service c6b9b0
Packit Service c6b9b0
  return ret;
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
/* ---------------------------------------------------------------------------------------------------- */
Packit Service c6b9b0
Packit Service c6b9b0
static gboolean
Packit Service c6b9b0
build_object (GoaProvider        *provider,
Packit Service c6b9b0
              GoaObjectSkeleton  *object,
Packit Service c6b9b0
              GKeyFile           *key_file,
Packit Service c6b9b0
              const gchar        *group,
Packit Service c6b9b0
              GDBusConnection    *connection,
Packit Service c6b9b0
              gboolean            just_added,
Packit Service c6b9b0
              GError            **error)
Packit Service c6b9b0
{
Packit Service c6b9b0
  GoaAccount *account;
Packit Service c6b9b0
  gboolean chat_enabled;
Packit Service c6b9b0
  gboolean ret;
Packit Service c6b9b0
Packit Service c6b9b0
  account = NULL;
Packit Service c6b9b0
  ret = FALSE;
Packit Service c6b9b0
Packit Service c6b9b0
  /* Chain up */
Packit Service c6b9b0
  if (!GOA_PROVIDER_CLASS (goa_telepathy_provider_parent_class)->build_object (provider,
Packit Service c6b9b0
                                                                               object,
Packit Service c6b9b0
                                                                               key_file,
Packit Service c6b9b0
                                                                               group,
Packit Service c6b9b0
                                                                               connection,
Packit Service c6b9b0
                                                                               just_added,
Packit Service c6b9b0
                                                                               error))
Packit Service c6b9b0
    goto out;
Packit Service c6b9b0
Packit Service c6b9b0
  account = goa_object_get_account (GOA_OBJECT (object));
Packit Service c6b9b0
Packit Service c6b9b0
  /* Chat */
Packit Service c6b9b0
  chat_enabled = g_key_file_get_boolean (key_file, group, "ChatEnabled", NULL);
Packit Service c6b9b0
  goa_object_skeleton_attach_chat (object, chat_enabled);
Packit Service c6b9b0
Packit Service c6b9b0
  if (just_added)
Packit Service c6b9b0
    {
Packit Service c6b9b0
      goa_account_set_chat_disabled (account, !chat_enabled);
Packit Service c6b9b0
      g_signal_connect (account,
Packit Service c6b9b0
                        "notify::chat-disabled",
Packit Service c6b9b0
                        G_CALLBACK (goa_util_account_notify_property_cb),
Packit Service c6b9b0
                        (gpointer) "ChatEnabled");
Packit Service c6b9b0
    }
Packit Service c6b9b0
Packit Service c6b9b0
  ret = TRUE;
Packit Service c6b9b0
Packit Service c6b9b0
out:
Packit Service c6b9b0
  g_clear_object (&account);
Packit Service c6b9b0
  return ret;
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
/* ---------------------------------------------------------------------------------------------------- */
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
remove_account_remove_tp_account_cb (GObject       *source_object,
Packit Service c6b9b0
                                     GAsyncResult  *res,
Packit Service c6b9b0
                                     gpointer       user_data)
Packit Service c6b9b0
{
Packit Service c6b9b0
  GError *error;
Packit Service c6b9b0
  GTask *task = G_TASK (user_data);
Packit Service c6b9b0
Packit Service c6b9b0
  error = NULL;
Packit Service c6b9b0
  if (!goa_tp_account_linker_remove_tp_account_finish (tp_linker, res, &error))
Packit Service c6b9b0
    {
Packit Service c6b9b0
      g_task_return_error (task, error);
Packit Service c6b9b0
      goto out;
Packit Service c6b9b0
    }
Packit Service c6b9b0
Packit Service c6b9b0
  g_task_return_boolean (task, TRUE);
Packit Service c6b9b0
Packit Service c6b9b0
 out:
Packit Service c6b9b0
  g_object_unref (task);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
remove_account (GoaProvider          *provider,
Packit Service c6b9b0
                GoaObject            *object,
Packit Service c6b9b0
                GCancellable         *cancellable,
Packit Service c6b9b0
                GAsyncReadyCallback   callback,
Packit Service c6b9b0
                gpointer              user_data)
Packit Service c6b9b0
{
Packit Service c6b9b0
  GoaTelepathyProvider *self = GOA_TELEPATHY_PROVIDER (provider);
Packit Service c6b9b0
  GTask *task;
Packit Service c6b9b0
Packit Service c6b9b0
  task = g_task_new (self, cancellable, callback, user_data);
Packit Service c6b9b0
  g_task_set_source_tag (task, remove_account);
Packit Service c6b9b0
Packit Service c6b9b0
  goa_tp_account_linker_remove_tp_account (tp_linker,
Packit Service c6b9b0
                                           object,
Packit Service c6b9b0
                                           cancellable,
Packit Service c6b9b0
                                           remove_account_remove_tp_account_cb,
Packit Service c6b9b0
                                           g_object_ref (task));
Packit Service c6b9b0
Packit Service c6b9b0
  g_object_unref (task);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static gboolean
Packit Service c6b9b0
remove_account_finish (GoaProvider   *provider,
Packit Service c6b9b0
                       GAsyncResult  *res,
Packit Service c6b9b0
                       GError       **error)
Packit Service c6b9b0
{
Packit Service c6b9b0
  GoaTelepathyProvider *self = GOA_TELEPATHY_PROVIDER (provider);
Packit Service c6b9b0
  GTask *task;
Packit Service c6b9b0
Packit Service c6b9b0
  g_return_val_if_fail (g_task_is_valid (res, self), FALSE);
Packit Service c6b9b0
  task = G_TASK (res);
Packit Service c6b9b0
Packit Service c6b9b0
  g_return_val_if_fail (g_task_get_source_tag (task) == remove_account, FALSE);
Packit Service c6b9b0
Packit Service c6b9b0
  return g_task_propagate_boolean (task, error);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
/* ---------------------------------------------------------------------------------------------------- */
Packit Service c6b9b0
Packit Service c6b9b0
typedef struct
Packit Service c6b9b0
{
Packit Service c6b9b0
  guint ref_count;
Packit Service c6b9b0
  GoaObject *object;
Packit Service c6b9b0
  GtkWindow *parent;
Packit Service c6b9b0
} EditData;
Packit Service c6b9b0
Packit Service c6b9b0
static EditData *
Packit Service c6b9b0
edit_data_new (GoaObject *object,
Packit Service c6b9b0
               GtkWindow *parent)
Packit Service c6b9b0
{
Packit Service c6b9b0
  EditData *data;
Packit Service c6b9b0
Packit Service c6b9b0
  data = g_slice_new0 (EditData);
Packit Service c6b9b0
  data->ref_count = 1;
Packit Service c6b9b0
  data->object = g_object_ref (object);
Packit Service c6b9b0
  data->parent = parent;
Packit Service c6b9b0
Packit Service c6b9b0
  return data;
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
edit_data_unref (EditData *data)
Packit Service c6b9b0
{
Packit Service c6b9b0
  data->ref_count--;
Packit Service c6b9b0
  if (data->ref_count >= 1)
Packit Service c6b9b0
    return;
Packit Service c6b9b0
Packit Service c6b9b0
  g_object_unref (data->object);
Packit Service c6b9b0
  g_slice_free (EditData, data);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
edit_button_destroy_cb (GtkWidget *button,
Packit Service c6b9b0
                        gpointer   user_data)
Packit Service c6b9b0
{
Packit Service c6b9b0
  EditData *data = user_data;
Packit Service c6b9b0
Packit Service c6b9b0
  edit_data_unref (data);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
edit_data_handle_button (EditData  *data,
Packit Service c6b9b0
                         GtkWidget *button,
Packit Service c6b9b0
                         GCallback  cb)
Packit Service c6b9b0
{
Packit Service c6b9b0
  g_return_if_fail (GTK_IS_BUTTON (button));
Packit Service c6b9b0
Packit Service c6b9b0
  g_signal_connect (button, "clicked", cb, data);
Packit Service c6b9b0
  g_signal_connect (button, "destroy", G_CALLBACK (edit_button_destroy_cb), data);
Packit Service c6b9b0
Packit Service c6b9b0
  data->ref_count++;
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
maybe_show_error (GtkWindow   *parent,
Packit Service c6b9b0
                  GError      *error,
Packit Service c6b9b0
                  const gchar *msg)
Packit Service c6b9b0
{
Packit Service c6b9b0
  GtkWidget *dialog;
Packit Service c6b9b0
Packit Service c6b9b0
  if (error->domain == GOA_ERROR && error->code == GOA_ERROR_DIALOG_DISMISSED)
Packit Service c6b9b0
    return;
Packit Service c6b9b0
Packit Service c6b9b0
  dialog = gtk_message_dialog_new (GTK_WINDOW (parent),
Packit Service c6b9b0
      GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
Packit Service c6b9b0
      GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
Packit Service c6b9b0
      "%s: %s (%s, %d)",
Packit Service c6b9b0
      msg,
Packit Service c6b9b0
      error->message,
Packit Service c6b9b0
      g_quark_to_string (error->domain),
Packit Service c6b9b0
      error->code);
Packit Service c6b9b0
  g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
Packit Service c6b9b0
  gtk_dialog_run (GTK_DIALOG (dialog));
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
edit_parameters_clicked_cb (GtkButton *button,
Packit Service c6b9b0
                            gpointer   user_data)
Packit Service c6b9b0
{
Packit Service c6b9b0
  EditData *data = user_data;
Packit Service c6b9b0
  GError *error = NULL;
Packit Service c6b9b0
Packit Service c6b9b0
  if (!edit_connection_parameters (data->object, data->parent, &error))
Packit Service c6b9b0
    maybe_show_error (data->parent, error, _("Cannot save the connection parameters"));
Packit Service c6b9b0
  g_clear_error (&error);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
edit_personal_details_clicked_cb (GtkButton *button,
Packit Service c6b9b0
                                  gpointer   user_data)
Packit Service c6b9b0
{
Packit Service c6b9b0
  EditData *data = user_data;
Packit Service c6b9b0
  GError *error = NULL;
Packit Service c6b9b0
Packit Service c6b9b0
  if (!edit_personal_details (data->object, data->parent, &error))
Packit Service c6b9b0
    maybe_show_error (data->parent, error,
Packit Service c6b9b0
        _("Cannot save your personal information on the server"));
Packit Service c6b9b0
  g_clear_error (&error);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
show_account (GoaProvider         *provider,
Packit Service c6b9b0
              GoaClient           *client,
Packit Service c6b9b0
              GoaObject           *object,
Packit Service c6b9b0
              GtkBox              *vbox,
Packit Service c6b9b0
              G_GNUC_UNUSED GtkGrid *dummy1,
Packit Service c6b9b0
              G_GNUC_UNUSED GtkGrid *dummy2)
Packit Service c6b9b0
{
Packit Service c6b9b0
  EditData *data = NULL;
Packit Service c6b9b0
  GtkWidget *grid;
Packit Service c6b9b0
  GtkWidget *params_button = NULL;
Packit Service c6b9b0
  GtkWidget *details_button = NULL;
Packit Service c6b9b0
  GtkWidget *button_box = NULL;
Packit Service c6b9b0
  gint row = 0;
Packit Service c6b9b0
Packit Service c6b9b0
  goa_utils_account_add_attention_needed (client, object, provider, vbox);
Packit Service c6b9b0
Packit Service c6b9b0
  grid = gtk_grid_new ();
Packit Service c6b9b0
  gtk_widget_set_halign (grid, GTK_ALIGN_CENTER);
Packit Service c6b9b0
  gtk_widget_set_hexpand (grid, TRUE);
Packit Service c6b9b0
  gtk_widget_set_margin_end (grid, 72);
Packit Service c6b9b0
  gtk_widget_set_margin_start (grid, 72);
Packit Service c6b9b0
  gtk_widget_set_margin_top (grid, 24);
Packit Service c6b9b0
  gtk_grid_set_column_spacing (GTK_GRID (grid), 12);
Packit Service c6b9b0
  gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
Packit Service c6b9b0
  gtk_container_add (GTK_CONTAINER (vbox), grid);
Packit Service c6b9b0
Packit Service c6b9b0
  goa_utils_account_add_header (object, GTK_GRID (grid), row++);
Packit Service c6b9b0
Packit Service c6b9b0
  goa_util_add_row_switch_from_keyfile_with_blurb (GTK_GRID (grid),
Packit Service c6b9b0
                                                   row++,
Packit Service c6b9b0
                                                   object,
Packit Service c6b9b0
                                                   /* Translators: This is a label for a series of
Packit Service c6b9b0
                                                    * options switches. For example: “Use for Mail”. */
Packit Service c6b9b0
                                                   _("Use for"),
Packit Service c6b9b0
                                                   "chat-disabled",
Packit Service c6b9b0
                                                   _("C_hat"));
Packit Service c6b9b0
Packit Service c6b9b0
  data = edit_data_new (object, tpaw_get_toplevel_window (GTK_WIDGET (vbox)));
Packit Service c6b9b0
Packit Service c6b9b0
  /* Connection Settings button */
Packit Service c6b9b0
  params_button = gtk_button_new_with_mnemonic (_("_Connection Settings"));
Packit Service c6b9b0
  edit_data_handle_button (data, params_button, G_CALLBACK (edit_parameters_clicked_cb));
Packit Service c6b9b0
Packit Service c6b9b0
  /* Edit Personal Information button */
Packit Service c6b9b0
  details_button = gtk_button_new_with_mnemonic (_("_Personal Details"));
Packit Service c6b9b0
  edit_data_handle_button (data, details_button, G_CALLBACK (edit_personal_details_clicked_cb));
Packit Service c6b9b0
Packit Service c6b9b0
  /* Box containing the buttons */
Packit Service c6b9b0
  button_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
Packit Service c6b9b0
  gtk_box_pack_start (GTK_BOX (button_box), params_button,
Packit Service c6b9b0
      FALSE, FALSE, 12);
Packit Service c6b9b0
  gtk_container_add (GTK_CONTAINER (button_box), details_button);
Packit Service c6b9b0
Packit Service c6b9b0
  goa_util_add_row_widget (GTK_GRID (grid), row++, NULL, button_box);
Packit Service c6b9b0
Packit Service c6b9b0
  edit_data_unref (data);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
/* ---------------------------------------------------------------------------------------------------- */
Packit Service c6b9b0
Packit Service c6b9b0
GoaTelepathyProvider *
Packit Service c6b9b0
goa_telepathy_provider_new_from_protocol_name (const gchar *protocol_name)
Packit Service c6b9b0
{
Packit Service c6b9b0
  g_return_val_if_fail (protocol_name != NULL, NULL);
Packit Service c6b9b0
Packit Service c6b9b0
  return g_object_new (GOA_TYPE_TELEPATHY_PROVIDER,
Packit Service c6b9b0
                       "protocol-name", protocol_name,
Packit Service c6b9b0
                       NULL);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
/* ---------------------------------------------------------------------------------------------------- */
Packit Service c6b9b0
Packit Service c6b9b0
GoaTelepathyProvider *
Packit Service c6b9b0
goa_telepathy_provider_new_from_protocol (TpawProtocol *protocol)
Packit Service c6b9b0
{
Packit Service c6b9b0
  g_return_val_if_fail (TPAW_IS_PROTOCOL (protocol), NULL);
Packit Service c6b9b0
Packit Service c6b9b0
  return g_object_new (GOA_TYPE_TELEPATHY_PROVIDER,
Packit Service c6b9b0
                       "protocol", protocol,
Packit Service c6b9b0
                       NULL);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
/* ---------------------------------------------------------------------------------------------------- */
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
goa_telepathy_provider_get_property (GObject *object,
Packit Service c6b9b0
                                     guint property_id,
Packit Service c6b9b0
                                     GValue *value,
Packit Service c6b9b0
                                     GParamSpec *pspec)
Packit Service c6b9b0
{
Packit Service c6b9b0
    GoaTelepathyProviderPrivate *priv = GOA_TELEPATHY_PROVIDER (object)->priv;
Packit Service c6b9b0
Packit Service c6b9b0
    switch (property_id) {
Packit Service c6b9b0
    case PROP_PROTOCOL:
Packit Service c6b9b0
        g_value_set_object (value, priv->protocol);
Packit Service c6b9b0
        break;
Packit Service c6b9b0
    case PROP_PROTOCOL_NAME:
Packit Service c6b9b0
        g_value_set_string (value, priv->protocol_name);
Packit Service c6b9b0
        break;
Packit Service c6b9b0
    default:
Packit Service c6b9b0
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
Packit Service c6b9b0
        break;
Packit Service c6b9b0
    }
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
goa_telepathy_provider_set_property (GObject *object,
Packit Service c6b9b0
                                     guint property_id,
Packit Service c6b9b0
                                     const GValue *value,
Packit Service c6b9b0
                                     GParamSpec *pspec)
Packit Service c6b9b0
{
Packit Service c6b9b0
    GoaTelepathyProviderPrivate *priv = GOA_TELEPATHY_PROVIDER (object)->priv;
Packit Service c6b9b0
Packit Service c6b9b0
    switch (property_id) {
Packit Service c6b9b0
    case PROP_PROTOCOL:
Packit Service c6b9b0
        priv->protocol = g_value_dup_object (value);
Packit Service c6b9b0
        break;
Packit Service c6b9b0
    case PROP_PROTOCOL_NAME:
Packit Service c6b9b0
        priv->protocol_name = g_value_dup_string (value);
Packit Service c6b9b0
        break;
Packit Service c6b9b0
    default:
Packit Service c6b9b0
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
Packit Service c6b9b0
        break;
Packit Service c6b9b0
    }
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
goa_telepathy_provider_init (GoaTelepathyProvider *self)
Packit Service c6b9b0
{
Packit Service c6b9b0
  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
Packit Service c6b9b0
        GOA_TYPE_TELEPATHY_PROVIDER, GoaTelepathyProviderPrivate);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
goa_telepathy_provider_constructed (GObject *object)
Packit Service c6b9b0
{
Packit Service c6b9b0
  GoaTelepathyProviderPrivate *priv = GOA_TELEPATHY_PROVIDER (object)->priv;
Packit Service c6b9b0
Packit Service c6b9b0
  G_OBJECT_CLASS (goa_telepathy_provider_parent_class)->constructed (object);
Packit Service c6b9b0
Packit Service c6b9b0
  if (priv->protocol != NULL)
Packit Service c6b9b0
    {
Packit Service c6b9b0
      if (priv->protocol_name != NULL)
Packit Service c6b9b0
        g_error ("You cannot set \"protocol-name\" if you set \"protocol\"");
Packit Service c6b9b0
      priv->protocol_name = g_strdup (tpaw_protocol_get_protocol_name (priv->protocol));
Packit Service c6b9b0
    }
Packit Service c6b9b0
  else
Packit Service c6b9b0
    {
Packit Service c6b9b0
      if (priv->protocol_name == NULL)
Packit Service c6b9b0
        g_error ("You must set \"protocol-name\" or \"protocol\" on GoaTelepathyProvider");
Packit Service c6b9b0
    }
Packit Service c6b9b0
Packit Service c6b9b0
  priv->provider_type = g_strdup_printf ("%s/%s",
Packit Service c6b9b0
      GOA_TELEPATHY_NAME, priv->protocol_name);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
goa_telepathy_provider_finalize (GObject *object)
Packit Service c6b9b0
{
Packit Service c6b9b0
  GoaTelepathyProviderPrivate *priv = GOA_TELEPATHY_PROVIDER (object)->priv;
Packit Service c6b9b0
Packit Service c6b9b0
  g_clear_object (&priv->protocol);
Packit Service c6b9b0
  g_free (priv->protocol_name);
Packit Service c6b9b0
  g_free (priv->provider_type);
Packit Service c6b9b0
Packit Service c6b9b0
  (G_OBJECT_CLASS (goa_telepathy_provider_parent_class)->finalize) (object);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
goa_telepathy_provider_class_init (GoaTelepathyProviderClass *klass)
Packit Service c6b9b0
{
Packit Service c6b9b0
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
Packit Service c6b9b0
  GoaProviderClass *provider_class = GOA_PROVIDER_CLASS (klass);
Packit Service c6b9b0
Packit Service c6b9b0
  goa_utils_initialize_client_factory ();
Packit Service c6b9b0
Packit Service c6b9b0
  object_class->constructed  = goa_telepathy_provider_constructed;
Packit Service c6b9b0
  object_class->finalize     = goa_telepathy_provider_finalize;
Packit Service c6b9b0
  object_class->get_property = goa_telepathy_provider_get_property;
Packit Service c6b9b0
  object_class->set_property = goa_telepathy_provider_set_property;
Packit Service c6b9b0
Packit Service c6b9b0
  provider_class->get_provider_type     = get_provider_type;
Packit Service c6b9b0
  provider_class->get_provider_name     = get_provider_name;
Packit Service c6b9b0
  provider_class->get_provider_icon     = get_provider_icon;
Packit Service c6b9b0
  provider_class->get_provider_group    = get_provider_group;
Packit Service c6b9b0
  provider_class->get_provider_features = get_provider_features;
Packit Service c6b9b0
  provider_class->initialize            = initialize;
Packit Service c6b9b0
  provider_class->add_account           = add_account;
Packit Service c6b9b0
  provider_class->refresh_account       = refresh_account;
Packit Service c6b9b0
  provider_class->build_object          = build_object;
Packit Service c6b9b0
  provider_class->remove_account        = remove_account;
Packit Service c6b9b0
  provider_class->remove_account_finish = remove_account_finish;
Packit Service c6b9b0
  provider_class->show_account          = show_account;
Packit Service c6b9b0
Packit Service c6b9b0
  g_type_class_add_private (object_class, sizeof (GoaTelepathyProviderPrivate));
Packit Service c6b9b0
Packit Service c6b9b0
  /**
Packit Service c6b9b0
   * GoaTelepathyProvider:protocol
Packit Service c6b9b0
   *
Packit Service c6b9b0
   * A #TpawProtocol associated to this provider (or NULL).
Packit Service c6b9b0
   */
Packit Service c6b9b0
  properties[PROP_PROTOCOL] =
Packit Service c6b9b0
    g_param_spec_object ("protocol",
Packit Service c6b9b0
        "Protocol",
Packit Service c6b9b0
        "A #TpawProtocol associated to the provider (or NULL)",
Packit Service c6b9b0
        TPAW_TYPE_PROTOCOL,
Packit Service c6b9b0
        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
Packit Service c6b9b0
Packit Service c6b9b0
  /**
Packit Service c6b9b0
   * GoaTelepathyProvider:protocol-name
Packit Service c6b9b0
   *
Packit Service c6b9b0
   * The name of the protocol associated to the provider.
Packit Service c6b9b0
   */
Packit Service c6b9b0
  properties[PROP_PROTOCOL_NAME] =
Packit Service c6b9b0
    g_param_spec_string ("protocol-name",
Packit Service c6b9b0
        "Protocol name",
Packit Service c6b9b0
        "The name of the protocol associated to the provider",
Packit Service c6b9b0
        NULL,
Packit Service c6b9b0
        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
Packit Service c6b9b0
Packit Service c6b9b0
  g_object_class_install_properties (object_class, NUM_PROPERTIES, properties);
Packit Service c6b9b0
}