2011-06-24 14:17:31 +01:00
|
|
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
|
|
/*
|
2017-10-25 12:23:23 +02:00
|
|
|
* Copyright (C) 2011 - 2017 Red Hat, Inc.
|
2011-06-24 14:17:31 +01:00
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General
|
2014-01-23 12:57:27 +01:00
|
|
|
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
2011-06-24 14:17:31 +01:00
|
|
|
*
|
|
|
|
* Author: David Zeuthen <davidz@redhat.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
2012-12-03 13:14:34 +01:00
|
|
|
#include <gio/gio.h>
|
2011-06-24 14:17:31 +01:00
|
|
|
#include <string.h>
|
|
|
|
#include <glib/gi18n-lib.h>
|
|
|
|
|
|
|
|
#define GOA_API_IS_SUBJECT_TO_CHANGE
|
|
|
|
#include <goa/goa.h>
|
|
|
|
|
|
|
|
#include "cc-online-accounts-panel.h"
|
2020-11-03 15:25:58 +13:00
|
|
|
#include "cc-online-account-provider-row.h"
|
2020-11-03 16:01:34 +13:00
|
|
|
#include "cc-online-account-row.h"
|
2013-01-23 15:10:01 +01:00
|
|
|
#include "cc-online-accounts-resources.h"
|
2011-06-24 14:17:31 +01:00
|
|
|
|
2023-12-11 13:09:32 -08:00
|
|
|
#define GOA_API_IS_SUBJECT_TO_CHANGE
|
|
|
|
#define GOA_BACKEND_API_IS_SUBJECT_TO_CHANGE
|
|
|
|
#include <goabackend/goabackend.h>
|
2016-11-10 13:32:43 -02:00
|
|
|
|
2022-05-11 11:32:15 +12:00
|
|
|
struct _CcOnlineAccountsPanel
|
2011-06-24 14:17:31 +01:00
|
|
|
{
|
|
|
|
CcPanel parent_instance;
|
|
|
|
|
2019-11-20 15:00:36 +13:00
|
|
|
GtkFrame *accounts_frame;
|
|
|
|
GtkListBox *accounts_listbox;
|
2023-07-04 18:18:27 -03:00
|
|
|
AdwBanner *offline_banner;
|
2019-11-20 15:00:36 +13:00
|
|
|
GtkListBox *providers_listbox;
|
|
|
|
|
2024-03-26 09:00:13 -07:00
|
|
|
GoaClient *client;
|
|
|
|
GVariant *parameters;
|
|
|
|
GListStore *providers;
|
2011-06-24 14:17:31 +01:00
|
|
|
};
|
|
|
|
|
2022-05-11 11:32:15 +12:00
|
|
|
CC_PANEL_REGISTER (CcOnlineAccountsPanel, cc_online_accounts_panel);
|
2011-06-24 14:17:31 +01:00
|
|
|
|
2012-08-08 17:04:39 +02:00
|
|
|
enum {
|
|
|
|
PROP_0,
|
2013-03-01 11:18:08 +01:00
|
|
|
PROP_PARAMETERS
|
2012-08-08 17:04:39 +02:00
|
|
|
};
|
|
|
|
|
2022-01-17 16:05:05 -03:00
|
|
|
/* Rows methods */
|
|
|
|
|
2022-05-11 11:32:15 +12:00
|
|
|
typedef void (*RowForAccountCallback) (CcOnlineAccountsPanel *self, GtkWidget *row, GList *other_rows);
|
2016-11-09 17:06:18 -02:00
|
|
|
|
|
|
|
static void
|
2022-05-11 11:32:15 +12:00
|
|
|
remove_row_for_account_cb (CcOnlineAccountsPanel *self,
|
|
|
|
GtkWidget *row,
|
|
|
|
GList *other_rows)
|
2016-11-09 17:06:18 -02:00
|
|
|
{
|
2022-01-17 16:05:05 -03:00
|
|
|
gtk_list_box_remove (self->accounts_listbox, row);
|
|
|
|
gtk_widget_set_visible (GTK_WIDGET (self->accounts_frame), other_rows != NULL);
|
|
|
|
}
|
2016-11-09 17:06:18 -02:00
|
|
|
|
2022-01-17 16:05:05 -03:00
|
|
|
static void
|
2022-05-11 11:32:15 +12:00
|
|
|
modify_row_for_account (CcOnlineAccountsPanel *self,
|
2022-01-17 16:05:05 -03:00
|
|
|
GoaObject *object,
|
|
|
|
RowForAccountCallback callback)
|
|
|
|
{
|
|
|
|
GtkWidget *child;
|
|
|
|
GList *children = NULL;
|
|
|
|
GList *l;
|
2016-11-09 17:06:18 -02:00
|
|
|
|
2022-01-17 16:05:05 -03:00
|
|
|
for (child = gtk_widget_get_first_child (GTK_WIDGET (self->accounts_listbox));
|
|
|
|
child;
|
|
|
|
child = gtk_widget_get_next_sibling (child))
|
2016-11-09 17:06:18 -02:00
|
|
|
{
|
2022-01-17 16:05:05 -03:00
|
|
|
children = g_list_prepend (children, child);
|
2016-11-09 17:06:18 -02:00
|
|
|
}
|
|
|
|
|
2022-01-17 16:05:05 -03:00
|
|
|
children = g_list_reverse (children);
|
2016-11-09 17:06:18 -02:00
|
|
|
|
2022-01-17 16:05:05 -03:00
|
|
|
for (l = children; l != NULL; l = l->next)
|
|
|
|
{
|
|
|
|
GoaObject *row_object;
|
2016-11-09 17:06:18 -02:00
|
|
|
|
2020-11-03 16:01:34 +13:00
|
|
|
row_object = cc_online_account_row_get_object (CC_ONLINE_ACCOUNT_ROW (l->data));
|
2022-01-17 16:05:05 -03:00
|
|
|
if (row_object == object)
|
|
|
|
{
|
|
|
|
GtkWidget *row = GTK_WIDGET (l->data);
|
2016-11-09 17:06:18 -02:00
|
|
|
|
2022-01-17 16:05:05 -03:00
|
|
|
children = g_list_remove_link (children, l);
|
|
|
|
callback (self, row, children);
|
|
|
|
g_list_free (l);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2016-11-10 14:46:38 -02:00
|
|
|
|
2022-01-17 16:05:05 -03:00
|
|
|
g_list_free (children);
|
|
|
|
}
|
2016-11-10 14:46:38 -02:00
|
|
|
|
2017-08-19 11:23:12 -03:00
|
|
|
static void
|
2024-02-08 13:28:57 -08:00
|
|
|
show_account_cb (GoaProvider *provider,
|
|
|
|
GAsyncResult *result,
|
|
|
|
CcOnlineAccountsPanel *self)
|
2017-08-19 11:23:12 -03:00
|
|
|
{
|
2024-02-08 13:28:57 -08:00
|
|
|
g_autoptr (GError) error = NULL;
|
2023-12-11 13:09:32 -08:00
|
|
|
|
2024-02-08 13:28:57 -08:00
|
|
|
if (!goa_provider_show_account_finish (provider, result, &error))
|
|
|
|
{
|
|
|
|
if (!g_error_matches (error, GOA_ERROR, GOA_ERROR_DIALOG_DISMISSED) && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
|
|
|
g_warning ("Error showing account: %s", error->message);
|
|
|
|
}
|
2018-03-05 08:53:46 +01:00
|
|
|
}
|
|
|
|
|
2012-08-08 17:04:39 +02:00
|
|
|
static void
|
2022-05-11 11:32:15 +12:00
|
|
|
show_account (CcOnlineAccountsPanel *self,
|
|
|
|
GoaObject *object)
|
2012-08-08 17:04:39 +02:00
|
|
|
{
|
2024-02-08 13:28:57 -08:00
|
|
|
g_autoptr (GoaProvider) provider = NULL;
|
|
|
|
GtkRoot *root;
|
2022-01-17 16:05:05 -03:00
|
|
|
GoaAccount *account;
|
2023-12-11 13:09:32 -08:00
|
|
|
const char *provider_type;
|
2013-03-01 11:18:08 +01:00
|
|
|
|
2023-12-11 13:09:32 -08:00
|
|
|
/* Find the provider with a matching type */
|
2024-02-08 13:28:57 -08:00
|
|
|
account = goa_object_peek_account (object);
|
2023-12-11 13:09:32 -08:00
|
|
|
provider_type = goa_account_get_provider_type (account);
|
|
|
|
provider = goa_provider_get_for_provider_type (provider_type);
|
|
|
|
if (provider == NULL)
|
2022-01-17 16:05:05 -03:00
|
|
|
{
|
2023-12-11 13:09:32 -08:00
|
|
|
g_warning ("Error showing account: Unsupported provider");
|
2022-01-17 16:05:05 -03:00
|
|
|
return;
|
2012-08-08 17:04:39 +02:00
|
|
|
}
|
|
|
|
|
2024-02-08 13:28:57 -08:00
|
|
|
root = gtk_widget_get_root (GTK_WIDGET (self));
|
2023-12-11 13:09:32 -08:00
|
|
|
goa_provider_show_account (provider,
|
|
|
|
self->client,
|
|
|
|
object,
|
2024-02-08 13:28:57 -08:00
|
|
|
GTK_WINDOW (root),
|
|
|
|
cc_panel_get_cancellable (CC_PANEL (self)),
|
|
|
|
(GAsyncReadyCallback) show_account_cb,
|
|
|
|
self);
|
2012-08-08 17:04:39 +02:00
|
|
|
}
|
|
|
|
|
2017-08-16 18:53:33 -03:00
|
|
|
static void
|
2024-02-08 13:28:57 -08:00
|
|
|
create_account_cb (GoaProvider *provider,
|
|
|
|
GAsyncResult *result,
|
|
|
|
CcOnlineAccountsPanel *self)
|
2011-06-24 14:17:31 +01:00
|
|
|
{
|
2024-02-08 13:28:57 -08:00
|
|
|
g_autoptr (GoaObject) object = NULL;
|
|
|
|
g_autoptr (GError) error = NULL;
|
2023-12-11 13:09:32 -08:00
|
|
|
|
2024-02-08 13:28:57 -08:00
|
|
|
object = goa_provider_add_account_finish (provider, result, &error);
|
|
|
|
if (error != NULL)
|
2022-01-17 16:05:05 -03:00
|
|
|
{
|
2024-02-08 13:28:57 -08:00
|
|
|
if (!g_error_matches (error, GOA_ERROR, GOA_ERROR_DIALOG_DISMISSED) && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
|
|
|
g_warning ("Error creating account: %s", error->message);
|
|
|
|
|
2022-01-17 16:05:05 -03:00
|
|
|
return;
|
|
|
|
}
|
2011-06-24 14:17:31 +01:00
|
|
|
|
2023-12-11 13:09:32 -08:00
|
|
|
show_account (self, object);
|
2022-01-17 16:05:05 -03:00
|
|
|
}
|
2012-08-08 17:04:39 +02:00
|
|
|
|
2024-02-08 13:28:57 -08:00
|
|
|
static void
|
|
|
|
create_account (CcOnlineAccountsPanel *self,
|
|
|
|
GoaProvider *provider)
|
|
|
|
{
|
|
|
|
GtkRoot *parent;
|
|
|
|
|
|
|
|
g_return_if_fail (GOA_IS_PROVIDER (provider));
|
|
|
|
|
|
|
|
parent = gtk_widget_get_root (GTK_WIDGET (self));
|
|
|
|
goa_provider_add_account (provider,
|
|
|
|
self->client,
|
|
|
|
GTK_WINDOW (parent),
|
|
|
|
cc_panel_get_cancellable (CC_PANEL (self)),
|
|
|
|
(GAsyncReadyCallback) create_account_cb,
|
|
|
|
self);
|
|
|
|
}
|
|
|
|
|
2022-01-17 16:05:05 -03:00
|
|
|
static void
|
2022-05-11 11:32:15 +12:00
|
|
|
select_account_by_id (CcOnlineAccountsPanel *self,
|
|
|
|
const gchar *account_id)
|
2022-01-17 16:05:05 -03:00
|
|
|
{
|
|
|
|
GtkWidget *child;
|
2016-11-09 12:30:13 -02:00
|
|
|
|
2022-01-17 16:05:05 -03:00
|
|
|
for (child = gtk_widget_get_first_child (GTK_WIDGET (self->accounts_listbox));
|
|
|
|
child;
|
|
|
|
child = gtk_widget_get_next_sibling (child))
|
|
|
|
{
|
|
|
|
GoaAccount *account;
|
|
|
|
GoaObject *row_object;
|
2016-11-09 12:30:13 -02:00
|
|
|
|
2020-11-03 16:01:34 +13:00
|
|
|
row_object = cc_online_account_row_get_object (CC_ONLINE_ACCOUNT_ROW (child));
|
2022-01-17 16:05:05 -03:00
|
|
|
account = goa_object_peek_account (row_object);
|
2016-11-09 14:43:41 -02:00
|
|
|
|
2022-01-17 16:05:05 -03:00
|
|
|
if (g_strcmp0 (goa_account_get_id (account), account_id) == 0)
|
|
|
|
{
|
|
|
|
show_account (self, row_object);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2011-06-24 14:17:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2022-05-11 11:32:15 +12:00
|
|
|
command_add (CcOnlineAccountsPanel *self,
|
|
|
|
GVariant *parameters)
|
2011-06-24 14:17:31 +01:00
|
|
|
{
|
2022-01-17 16:05:05 -03:00
|
|
|
const gchar *provider_name = NULL;
|
2024-02-08 13:28:57 -08:00
|
|
|
g_autoptr (GVariant) v = NULL;
|
2011-06-24 14:17:31 +01:00
|
|
|
|
2022-01-17 16:05:05 -03:00
|
|
|
g_assert (self != NULL);
|
|
|
|
g_assert (parameters != NULL);
|
2011-06-24 14:17:31 +01:00
|
|
|
|
2022-01-17 16:05:05 -03:00
|
|
|
switch (g_variant_n_children (parameters))
|
|
|
|
{
|
|
|
|
case 2:
|
|
|
|
g_variant_get_child (parameters, 1, "v", &v);
|
|
|
|
if (g_variant_is_of_type (v, G_VARIANT_TYPE_STRING))
|
|
|
|
provider_name = g_variant_get_string (v, NULL);
|
|
|
|
else
|
|
|
|
g_warning ("Wrong type for the second argument (provider name) GVariant, expected 's' but got '%s'",
|
|
|
|
(gchar *)g_variant_get_type (v));
|
|
|
|
break;
|
2011-06-24 14:17:31 +01:00
|
|
|
|
2022-01-17 16:05:05 -03:00
|
|
|
default:
|
|
|
|
g_warning ("Unexpected parameters found, ignore request");
|
|
|
|
return;
|
|
|
|
}
|
2016-11-09 15:55:45 -02:00
|
|
|
|
2022-01-17 16:05:05 -03:00
|
|
|
if (provider_name != NULL)
|
|
|
|
{
|
2024-03-26 09:00:13 -07:00
|
|
|
g_autoptr (GoaProvider) provider = NULL;
|
|
|
|
unsigned int n_items = 0;
|
2016-11-10 09:25:04 -02:00
|
|
|
|
2024-03-26 09:00:13 -07:00
|
|
|
n_items = g_list_model_get_n_items (G_LIST_MODEL (self->providers));
|
|
|
|
for (unsigned int i = 0; i < n_items; i++)
|
2022-01-17 16:05:05 -03:00
|
|
|
{
|
2023-12-11 13:09:32 -08:00
|
|
|
const char *provider_type = NULL;
|
2011-06-24 14:17:31 +01:00
|
|
|
|
2024-03-26 09:00:13 -07:00
|
|
|
provider = g_list_model_get_item (G_LIST_MODEL (self->providers), i);
|
2023-12-11 13:09:32 -08:00
|
|
|
provider_type = goa_provider_get_provider_type (provider);
|
2016-11-10 13:34:56 -02:00
|
|
|
|
2022-01-17 16:05:05 -03:00
|
|
|
if (g_strcmp0 (provider_type, provider_name) == 0)
|
|
|
|
break;
|
2024-03-26 09:00:13 -07:00
|
|
|
|
|
|
|
g_clear_object (&provider);
|
2022-01-17 16:05:05 -03:00
|
|
|
}
|
2016-11-10 13:34:56 -02:00
|
|
|
|
2024-03-26 09:00:13 -07:00
|
|
|
if (provider == NULL)
|
2022-01-17 16:05:05 -03:00
|
|
|
{
|
|
|
|
g_warning ("Unable to get a provider for type '%s'", provider_name);
|
|
|
|
return;
|
|
|
|
}
|
2011-06-24 14:17:31 +01:00
|
|
|
|
2022-01-17 16:05:05 -03:00
|
|
|
create_account (self, provider);
|
2011-06-24 14:17:31 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-17 19:02:11 -03:00
|
|
|
static void
|
|
|
|
load_custom_css (void)
|
|
|
|
{
|
2024-02-08 13:28:57 -08:00
|
|
|
g_autoptr (GtkCssProvider) provider = NULL;
|
2022-01-17 19:02:11 -03:00
|
|
|
|
|
|
|
provider = gtk_css_provider_new ();
|
|
|
|
gtk_css_provider_load_from_resource (provider, "/org/gnome/control-center/online-accounts/online-accounts.css");
|
|
|
|
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
|
|
|
GTK_STYLE_PROVIDER (provider),
|
|
|
|
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
|
|
|
}
|
|
|
|
|
2022-01-17 16:05:05 -03:00
|
|
|
/* Callbacks */
|
2011-06-24 14:17:31 +01:00
|
|
|
|
2024-02-10 10:27:00 -08:00
|
|
|
static int
|
|
|
|
goa_provider_priority (const char *provider_type)
|
|
|
|
{
|
|
|
|
static const char *goa_priority[] = {
|
|
|
|
"owncloud", /* Nextcloud */
|
|
|
|
"google", /* Google */
|
2024-03-08 13:05:17 +00:00
|
|
|
"windows_live", /* Microsoft Personal */
|
2024-02-10 10:27:00 -08:00
|
|
|
"ms_graph", /* Microsoft 365 */
|
|
|
|
"exchange", /* Microsoft Exchange */
|
2024-03-26 09:04:51 -07:00
|
|
|
"fedora", /* Fedora */
|
2024-03-08 13:05:17 +00:00
|
|
|
"imap_smtp", /* Email (IMAP and SMTP) */
|
|
|
|
"webdav", /* Calendars, Contacts, Files (WebDAV) */
|
2024-02-10 10:27:00 -08:00
|
|
|
"kerberos", /* Enterprise Login (Kerberos) */
|
|
|
|
};
|
|
|
|
|
|
|
|
for (size_t i = 0; i < G_N_ELEMENTS (goa_priority); i++)
|
|
|
|
{
|
|
|
|
if (g_str_equal (goa_priority[i], provider_type))
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* New or unknown providers are sorted last */
|
|
|
|
return G_N_ELEMENTS (goa_priority) + 1;
|
|
|
|
}
|
|
|
|
|
2024-03-26 09:00:13 -07:00
|
|
|
static GtkWidget *
|
|
|
|
provider_create_row (gpointer item,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
return (GtkWidget *) cc_online_account_provider_row_new (GOA_PROVIDER (item));
|
|
|
|
}
|
|
|
|
|
2024-02-10 10:27:00 -08:00
|
|
|
static int
|
2022-01-17 16:05:05 -03:00
|
|
|
sort_accounts_func (GtkListBoxRow *a,
|
|
|
|
GtkListBoxRow *b,
|
2024-02-10 10:27:00 -08:00
|
|
|
gpointer user_data)
|
2012-08-08 17:04:39 +02:00
|
|
|
{
|
2022-01-17 16:05:05 -03:00
|
|
|
GoaAccount *a_account, *b_account;
|
|
|
|
GoaObject *a_object, *b_object;
|
2024-02-10 10:27:00 -08:00
|
|
|
const char *a_name, *b_name;
|
2016-11-09 14:43:41 -02:00
|
|
|
|
2020-11-03 16:01:34 +13:00
|
|
|
a_object = cc_online_account_row_get_object (CC_ONLINE_ACCOUNT_ROW (a));
|
2022-01-17 16:05:05 -03:00
|
|
|
a_account = goa_object_peek_account (a_object);
|
2024-02-10 10:27:00 -08:00
|
|
|
a_name = goa_account_get_provider_type (a_account);
|
2016-11-09 14:43:41 -02:00
|
|
|
|
2020-11-03 16:01:34 +13:00
|
|
|
b_object = cc_online_account_row_get_object (CC_ONLINE_ACCOUNT_ROW (b));
|
2022-01-17 16:05:05 -03:00
|
|
|
b_account = goa_object_peek_account (b_object);
|
2024-02-10 10:27:00 -08:00
|
|
|
b_name = goa_account_get_provider_type (b_account);
|
2012-08-08 17:04:39 +02:00
|
|
|
|
2024-02-10 10:27:00 -08:00
|
|
|
return goa_provider_priority (a_name) - goa_provider_priority (b_name);
|
2012-08-08 17:04:39 +02:00
|
|
|
}
|
|
|
|
|
2024-02-10 10:27:00 -08:00
|
|
|
static int
|
2024-03-26 09:00:13 -07:00
|
|
|
sort_providers_func (GoaProvider *a,
|
|
|
|
GoaProvider *b,
|
|
|
|
gpointer user_data)
|
2011-06-24 14:17:31 +01:00
|
|
|
{
|
2024-03-26 09:00:13 -07:00
|
|
|
const char *a_name = goa_provider_get_provider_type (a);
|
|
|
|
const char *b_name = goa_provider_get_provider_type (b);
|
2011-06-24 14:17:31 +01:00
|
|
|
|
2024-02-10 10:27:00 -08:00
|
|
|
return goa_provider_priority (a_name) - goa_provider_priority (b_name);
|
2023-12-11 13:09:32 -08:00
|
|
|
}
|
2011-06-24 14:17:31 +01:00
|
|
|
|
2023-12-11 13:09:32 -08:00
|
|
|
static void
|
|
|
|
add_account (CcOnlineAccountsPanel *self,
|
2024-02-08 13:28:57 -08:00
|
|
|
GoaObject *object)
|
2023-12-11 13:09:32 -08:00
|
|
|
{
|
|
|
|
CcOnlineAccountRow *row;
|
2016-11-09 14:43:41 -02:00
|
|
|
|
2023-12-11 13:09:32 -08:00
|
|
|
row = cc_online_account_row_new (object);
|
|
|
|
gtk_list_box_append (self->accounts_listbox, GTK_WIDGET (row));
|
|
|
|
gtk_widget_set_visible (GTK_WIDGET (self->accounts_frame), TRUE);
|
|
|
|
}
|
2022-01-17 16:05:05 -03:00
|
|
|
|
2023-12-11 13:09:32 -08:00
|
|
|
static void
|
|
|
|
add_provider (CcOnlineAccountsPanel *self,
|
2024-03-26 09:00:13 -07:00
|
|
|
GoaProvider *provider)
|
2023-12-11 13:09:32 -08:00
|
|
|
{
|
2024-03-26 09:00:13 -07:00
|
|
|
g_list_store_insert_sorted (self->providers,
|
|
|
|
provider,
|
|
|
|
(GCompareDataFunc) sort_providers_func,
|
|
|
|
self);
|
2012-08-21 17:23:50 +02:00
|
|
|
}
|
|
|
|
|
2017-02-22 13:21:03 +01:00
|
|
|
static void
|
2023-05-31 10:31:12 +12:00
|
|
|
on_account_added_cb (CcOnlineAccountsPanel *self,
|
|
|
|
GoaObject *object)
|
2017-02-22 13:21:03 +01:00
|
|
|
{
|
2022-01-17 16:05:05 -03:00
|
|
|
add_account (self, object);
|
2017-02-22 13:21:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2023-05-31 10:31:12 +12:00
|
|
|
on_account_removed_cb (CcOnlineAccountsPanel *self,
|
|
|
|
GoaObject *object)
|
2017-02-22 13:21:03 +01:00
|
|
|
{
|
2022-01-17 16:05:05 -03:00
|
|
|
modify_row_for_account (self, object, remove_row_for_account_cb);
|
2017-02-22 13:21:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2022-05-11 11:32:15 +12:00
|
|
|
on_accounts_listbox_row_activated (CcOnlineAccountsPanel *self,
|
|
|
|
GtkListBoxRow *activated_row)
|
2017-02-22 13:03:49 +01:00
|
|
|
{
|
2020-11-03 16:01:34 +13:00
|
|
|
GoaObject *object = cc_online_account_row_get_object (CC_ONLINE_ACCOUNT_ROW (activated_row));
|
2017-02-22 13:03:49 +01:00
|
|
|
|
2022-01-17 16:05:05 -03:00
|
|
|
show_account (self, object);
|
|
|
|
}
|
2017-02-22 13:03:49 +01:00
|
|
|
|
2022-01-17 16:05:05 -03:00
|
|
|
static void
|
2022-05-11 11:32:15 +12:00
|
|
|
on_provider_row_activated_cb (CcOnlineAccountsPanel *self,
|
2024-02-08 13:28:57 -08:00
|
|
|
GtkListBoxRow *activated_row)
|
2022-01-17 16:05:05 -03:00
|
|
|
{
|
2023-12-11 13:09:32 -08:00
|
|
|
GoaProvider *provider = cc_online_account_provider_row_get_provider (CC_ONLINE_ACCOUNT_PROVIDER_ROW (activated_row));
|
2016-11-09 14:43:41 -02:00
|
|
|
|
2022-01-17 16:05:05 -03:00
|
|
|
create_account (self, provider);
|
|
|
|
}
|
2016-11-09 14:43:41 -02:00
|
|
|
|
2023-12-11 13:09:32 -08:00
|
|
|
static void
|
2024-02-08 13:28:57 -08:00
|
|
|
goa_provider_get_all_cb (GObject *object,
|
2023-12-11 13:09:32 -08:00
|
|
|
GAsyncResult *res,
|
2024-02-08 13:28:57 -08:00
|
|
|
gpointer user_data)
|
2022-01-17 16:05:05 -03:00
|
|
|
{
|
2023-12-11 13:09:32 -08:00
|
|
|
g_autoptr (CcOnlineAccountsPanel) self = CC_ONLINE_ACCOUNTS_PANEL (user_data);
|
2024-02-08 13:28:57 -08:00
|
|
|
g_autolist (GoaProvider) providers = NULL;
|
|
|
|
g_autolist (GoaAccount) accounts = NULL;
|
2023-12-11 13:09:32 -08:00
|
|
|
g_autoptr (GError) error = NULL;
|
2012-08-21 17:23:50 +02:00
|
|
|
|
2023-12-11 13:09:32 -08:00
|
|
|
/* goa_provider_get_all() doesn't have a cancellable argument, so check if
|
|
|
|
* the panel cancellable was triggered.
|
|
|
|
*/
|
|
|
|
if (g_cancellable_is_cancelled (cc_panel_get_cancellable (CC_PANEL (self))))
|
|
|
|
return;
|
2022-01-17 16:05:05 -03:00
|
|
|
|
2023-12-11 13:09:32 -08:00
|
|
|
if (!goa_provider_get_all_finish (&providers, res, &error))
|
|
|
|
{
|
|
|
|
g_warning ("Error listing providers: %s", error->message);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const GList *iter = providers; iter != NULL; iter = iter->next)
|
|
|
|
add_provider (self, GOA_PROVIDER (iter->data));
|
|
|
|
|
|
|
|
/* Load existing accounts */
|
|
|
|
accounts = goa_client_get_accounts (self->client);
|
|
|
|
|
|
|
|
for (const GList *iter = accounts; iter != NULL; iter = iter->next)
|
|
|
|
add_account (self, GOA_OBJECT (iter->data));
|
|
|
|
|
|
|
|
g_signal_connect_swapped (self->client,
|
|
|
|
"account-added",
|
|
|
|
G_CALLBACK (on_account_added_cb),
|
|
|
|
self);
|
|
|
|
|
|
|
|
g_signal_connect_swapped (self->client,
|
|
|
|
"account-removed",
|
|
|
|
G_CALLBACK (on_account_removed_cb),
|
|
|
|
self);
|
2012-08-21 17:23:50 +02:00
|
|
|
|
2023-12-11 13:09:32 -08:00
|
|
|
/* With the client ready, check if we have a pending command */
|
|
|
|
gtk_widget_set_sensitive (GTK_WIDGET (self), TRUE);
|
|
|
|
|
|
|
|
if (self->parameters != NULL)
|
|
|
|
{
|
|
|
|
g_autoptr (GVariant) parameters = NULL;
|
|
|
|
|
|
|
|
parameters = g_steal_pointer (&self->parameters);
|
|
|
|
g_object_set (self, "parameters", parameters, NULL);
|
|
|
|
}
|
2016-11-09 14:43:41 -02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2024-02-08 13:28:57 -08:00
|
|
|
goa_client_new_cb (GObject *object,
|
2023-12-11 13:09:32 -08:00
|
|
|
GAsyncResult *res,
|
2024-02-08 13:28:57 -08:00
|
|
|
gpointer user_data)
|
2016-11-09 14:43:41 -02:00
|
|
|
{
|
2023-12-11 13:09:32 -08:00
|
|
|
g_autoptr (CcOnlineAccountsPanel) self = CC_ONLINE_ACCOUNTS_PANEL (user_data);
|
|
|
|
g_autoptr (GError) error = NULL;
|
2022-01-17 16:05:05 -03:00
|
|
|
|
2023-12-11 13:09:32 -08:00
|
|
|
self->client = goa_client_new_finish (res, &error);
|
|
|
|
if (self->client == NULL)
|
|
|
|
{
|
|
|
|
g_warning ("Error connect to service: %s", error->message);
|
|
|
|
gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
goa_provider_get_all (goa_provider_get_all_cb, g_object_ref (self));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* CcPanel overrides */
|
|
|
|
|
|
|
|
static const char *
|
|
|
|
cc_online_accounts_panel_get_help_uri (CcPanel *panel)
|
|
|
|
{
|
|
|
|
return "help:gnome-help/accounts";
|
2012-08-21 17:23:50 +02:00
|
|
|
}
|
|
|
|
|
2022-01-17 16:05:05 -03:00
|
|
|
/* GObject overrides */
|
2011-06-24 14:17:31 +01:00
|
|
|
|
|
|
|
static void
|
2022-05-11 11:32:15 +12:00
|
|
|
cc_online_accounts_panel_set_property (GObject *object,
|
|
|
|
guint property_id,
|
|
|
|
const GValue *value,
|
|
|
|
GParamSpec *pspec)
|
2011-06-24 14:17:31 +01:00
|
|
|
{
|
2023-12-11 13:09:32 -08:00
|
|
|
CcOnlineAccountsPanel *self = CC_ONLINE_ACCOUNTS_PANEL (object);
|
|
|
|
|
2022-01-17 16:05:05 -03:00
|
|
|
switch (property_id)
|
2020-04-17 16:43:53 +12:00
|
|
|
{
|
2022-01-17 16:05:05 -03:00
|
|
|
case PROP_PARAMETERS:
|
|
|
|
{
|
2022-05-11 11:36:45 +12:00
|
|
|
GVariant *parameters;
|
2024-02-08 13:28:57 -08:00
|
|
|
g_autoptr (GVariant) v = NULL;
|
2022-01-17 16:05:05 -03:00
|
|
|
const gchar *first_arg = NULL;
|
2011-06-24 14:17:31 +01:00
|
|
|
|
2022-01-17 16:05:05 -03:00
|
|
|
parameters = g_value_get_variant (value);
|
|
|
|
if (parameters == NULL)
|
|
|
|
return;
|
online-accounts: Track the lifecycle of CcGoaPanel across async calls
Due to an API bug in GNOME Online Accounts, the asynchronous
goa_provider_get_all method doesn't accept a GCancellable argument.
This makes it difficult to cancel an ongoing call when the CcGoaPanel
gets destroyed.
Prior to commit c26f8ae018900a55, this was hacked around by taking a
reference on the panel for the duration of the call. Instead of
cancelling a pending call on destruction, it would keep the panel alive
until the call was over. However, that was lost during commit
c26f8ae018900a55.
One thing to bear in mind is that GtkWidgets, CcGoaPanel is one, can
be destroyed by a gtk_widget_destroy call, which is subtly different
than a simple sequence of g_object_unref calls. When gtk_widget_destroy
is used, it invokes the GObject::dispose virtual method of the widget.
It is expected this will cause anything holding a reference to this
widget to drop their references, leading to GObject::finalize being
called. However, there is no guarantee that this will happen in the
same iteration of the GMainLoop. Therefore, it is possible that when
the goa_provider_get_all call finishes, the CcGoaPanel might be in a
disposed, but not yet finalized state.
When a GObject is in a disposed-but-not-finalized state, only a very
limited number of operations can be performed on it. Its reference
count can be altered, the memory used by the instance struct can be
accessed, but none of the member GObjects can be assumed to be valid.
eg., it's definitely illegal to add new rows to the member GtkListBox.
Hence a boolean flag is used to mark the destroyed state of the panel.
This second part is a small improvement over the earlier hack.
https://gitlab.gnome.org/GNOME/gnome-control-center/issues/208
2018-10-04 11:28:15 +02:00
|
|
|
|
2022-01-17 16:05:05 -03:00
|
|
|
if (g_variant_n_children (parameters) > 0)
|
|
|
|
{
|
|
|
|
g_variant_get_child (parameters, 0, "v", &v);
|
|
|
|
if (g_variant_is_of_type (v, G_VARIANT_TYPE_STRING))
|
|
|
|
first_arg = g_variant_get_string (v, NULL);
|
|
|
|
else
|
|
|
|
g_warning ("Wrong type for the second argument GVariant, expected 's' but got '%s'",
|
|
|
|
(gchar *)g_variant_get_type (v));
|
|
|
|
}
|
2013-03-01 12:11:14 +01:00
|
|
|
|
2023-12-11 13:09:32 -08:00
|
|
|
/* Waiting for the client to load */
|
2024-02-12 09:44:57 -08:00
|
|
|
if (self->client == NULL)
|
2023-12-11 13:09:32 -08:00
|
|
|
{
|
|
|
|
g_clear_pointer (&self->parameters, g_variant_unref);
|
|
|
|
self->parameters = g_value_dup_variant (value);
|
|
|
|
}
|
|
|
|
else if (g_strcmp0 (first_arg, "add") == 0)
|
|
|
|
{
|
2024-02-12 09:44:57 -08:00
|
|
|
command_add (CC_ONLINE_ACCOUNTS_PANEL (object), parameters);
|
2023-12-11 13:09:32 -08:00
|
|
|
}
|
2022-01-17 16:05:05 -03:00
|
|
|
else if (first_arg != NULL)
|
2023-12-11 13:09:32 -08:00
|
|
|
{
|
|
|
|
select_account_by_id (CC_ONLINE_ACCOUNTS_PANEL (object), first_arg);
|
|
|
|
}
|
2022-01-17 16:05:05 -03:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
2011-06-24 14:17:31 +01:00
|
|
|
}
|
|
|
|
|
2022-01-17 16:05:05 -03:00
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
2011-06-24 14:17:31 +01:00
|
|
|
}
|
2016-11-10 13:01:02 -02:00
|
|
|
|
|
|
|
static void
|
2022-05-11 11:32:15 +12:00
|
|
|
cc_online_accounts_panel_finalize (GObject *object)
|
2016-11-10 13:01:02 -02:00
|
|
|
{
|
2023-05-31 15:07:30 +12:00
|
|
|
CcOnlineAccountsPanel *self = CC_ONLINE_ACCOUNTS_PANEL (object);
|
2016-11-10 13:01:02 -02:00
|
|
|
|
2023-05-31 15:07:30 +12:00
|
|
|
g_clear_object (&self->client);
|
2023-12-11 13:09:32 -08:00
|
|
|
g_clear_pointer (&self->parameters, g_variant_unref);
|
2024-03-26 09:00:13 -07:00
|
|
|
g_clear_object (&self->providers);
|
2022-01-17 16:05:05 -03:00
|
|
|
|
2022-05-11 11:32:15 +12:00
|
|
|
G_OBJECT_CLASS (cc_online_accounts_panel_parent_class)->finalize (object);
|
2016-11-10 13:01:02 -02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2022-05-11 11:32:15 +12:00
|
|
|
cc_online_accounts_panel_class_init (CcOnlineAccountsPanelClass *klass)
|
2016-11-10 13:01:02 -02:00
|
|
|
{
|
2022-01-17 16:05:05 -03:00
|
|
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
CcPanelClass *panel_class = CC_PANEL_CLASS (klass);
|
2016-11-10 13:01:02 -02:00
|
|
|
|
2022-05-11 11:32:15 +12:00
|
|
|
panel_class->get_help_uri = cc_online_accounts_panel_get_help_uri;
|
2016-11-10 13:01:02 -02:00
|
|
|
|
2022-05-11 11:32:15 +12:00
|
|
|
object_class->set_property = cc_online_accounts_panel_set_property;
|
|
|
|
object_class->finalize = cc_online_accounts_panel_finalize;
|
2016-11-10 13:01:02 -02:00
|
|
|
|
2022-01-17 16:05:05 -03:00
|
|
|
g_object_class_override_property (object_class, PROP_PARAMETERS, "parameters");
|
2016-11-10 13:01:02 -02:00
|
|
|
|
2022-01-17 16:05:05 -03:00
|
|
|
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/online-accounts/cc-online-accounts-panel.ui");
|
|
|
|
|
2022-05-11 11:32:15 +12:00
|
|
|
gtk_widget_class_bind_template_child (widget_class, CcOnlineAccountsPanel, accounts_frame);
|
|
|
|
gtk_widget_class_bind_template_child (widget_class, CcOnlineAccountsPanel, accounts_listbox);
|
2023-07-04 18:18:27 -03:00
|
|
|
gtk_widget_class_bind_template_child (widget_class, CcOnlineAccountsPanel, offline_banner);
|
2022-05-11 11:32:15 +12:00
|
|
|
gtk_widget_class_bind_template_child (widget_class, CcOnlineAccountsPanel, providers_listbox);
|
2022-01-17 16:05:05 -03:00
|
|
|
|
|
|
|
gtk_widget_class_bind_template_callback (widget_class, on_accounts_listbox_row_activated);
|
|
|
|
gtk_widget_class_bind_template_callback (widget_class, on_provider_row_activated_cb);
|
2016-11-10 13:01:02 -02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2022-05-11 11:32:15 +12:00
|
|
|
cc_online_accounts_panel_init (CcOnlineAccountsPanel *self)
|
2016-11-10 13:01:02 -02:00
|
|
|
{
|
2022-01-17 16:05:05 -03:00
|
|
|
GNetworkMonitor *monitor;
|
2016-11-10 13:01:02 -02:00
|
|
|
|
2022-01-17 16:05:05 -03:00
|
|
|
g_resources_register (cc_online_accounts_get_resource ());
|
2016-11-10 13:01:02 -02:00
|
|
|
|
2022-01-17 16:05:05 -03:00
|
|
|
gtk_widget_init_template (GTK_WIDGET (self));
|
2016-11-10 13:01:02 -02:00
|
|
|
|
2022-01-17 16:05:05 -03:00
|
|
|
gtk_list_box_set_sort_func (self->accounts_listbox,
|
|
|
|
sort_accounts_func,
|
|
|
|
self,
|
|
|
|
NULL);
|
2016-11-10 13:01:02 -02:00
|
|
|
|
2024-03-26 09:00:13 -07:00
|
|
|
self->providers = g_list_store_new (GOA_TYPE_PROVIDER);
|
|
|
|
gtk_list_box_bind_model (self->providers_listbox,
|
|
|
|
G_LIST_MODEL (self->providers),
|
|
|
|
provider_create_row,
|
|
|
|
self,
|
|
|
|
NULL);
|
2016-11-10 13:01:02 -02:00
|
|
|
|
2022-01-17 16:05:05 -03:00
|
|
|
monitor = g_network_monitor_get_default();
|
|
|
|
g_object_bind_property (monitor,
|
|
|
|
"network-available",
|
2023-07-04 18:18:27 -03:00
|
|
|
self->offline_banner,
|
|
|
|
"revealed",
|
2022-01-17 16:05:05 -03:00
|
|
|
G_BINDING_SYNC_CREATE | G_BINDING_INVERT_BOOLEAN);
|
|
|
|
|
|
|
|
g_object_bind_property (monitor,
|
|
|
|
"network-available",
|
|
|
|
self->providers_listbox,
|
|
|
|
"sensitive",
|
|
|
|
G_BINDING_SYNC_CREATE);
|
|
|
|
|
2022-01-17 19:02:11 -03:00
|
|
|
load_custom_css ();
|
2023-12-11 13:09:32 -08:00
|
|
|
|
|
|
|
/* Disable the panel while we wait for the client */
|
|
|
|
gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
|
|
|
|
goa_client_new (cc_panel_get_cancellable (CC_PANEL (self)),
|
|
|
|
goa_client_new_cb,
|
|
|
|
g_object_ref (self));
|
2016-11-10 13:01:02 -02:00
|
|
|
}
|