1
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
3
* Copyright (C) 2008-2011 Red Hat, Inc.
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Lesser General Public
7
* License as published by the Free Software Foundation; either
8
* version 2 of the License, or (at your option) any later version.
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Lesser General Public License for more details.
15
* You should have received a copy of the GNU Lesser General
16
* Public License along with this library; if not, write to the
17
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18
* Boston, MA 02111-1307, USA.
20
* Author: David Zeuthen <davidz@redhat.com>
25
#include <glib/gi18n-lib.h>
27
#define GOA_API_IS_SUBJECT_TO_CHANGE
28
#define GOA_BACKEND_API_IS_SUBJECT_TO_CHANGE
29
#include <goabackend/goabackend.h>
31
#include "cc-online-accounts-model.h"
33
struct _GoaPanelAccountsModel
35
GtkListStore parent_instance;
42
GtkListStoreClass parent_class;
43
} GoaPanelAccountsModelClass;
51
static void init_model (GoaPanelAccountsModel *model);
54
find_iter_for_object (GoaPanelAccountsModel *model,
56
GtkTreeIter *out_iter);
58
static void on_account_added (GoaClient *client,
62
static void on_account_removed (GoaClient *client,
66
static void on_account_changed (GoaClient *client,
70
G_DEFINE_TYPE (GoaPanelAccountsModel, goa_panel_accounts_model, GTK_TYPE_LIST_STORE);
73
goa_panel_accounts_model_finalize (GObject *object)
75
GoaPanelAccountsModel *model = GOA_PANEL_ACCOUNTS_MODEL (object);
77
g_signal_handlers_disconnect_by_func (model->client, G_CALLBACK (on_account_added), model);
78
g_signal_handlers_disconnect_by_func (model->client, G_CALLBACK (on_account_removed), model);
79
g_signal_handlers_disconnect_by_func (model->client, G_CALLBACK (on_account_changed), model);
80
g_object_unref (model->client);
82
G_OBJECT_CLASS (goa_panel_accounts_model_parent_class)->finalize (object);
86
goa_panel_accounts_model_init (GoaPanelAccountsModel *model)
91
goa_panel_accounts_model_get_property (GObject *object,
96
GoaPanelAccountsModel *model = GOA_PANEL_ACCOUNTS_MODEL (object);
101
g_value_set_object (value, goa_panel_accounts_model_get_client (model));
105
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
111
goa_panel_accounts_model_set_property (GObject *object,
116
GoaPanelAccountsModel *model = GOA_PANEL_ACCOUNTS_MODEL (object);
121
model->client = g_value_dup_object (value);
125
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
130
/* ---------------------------------------------------------------------------------------------------- */
133
goa_panel_accounts_model_constructed (GObject *object)
135
GoaPanelAccountsModel *model = GOA_PANEL_ACCOUNTS_MODEL (object);
136
GType types[GOA_PANEL_ACCOUNTS_MODEL_N_COLUMNS];
138
G_STATIC_ASSERT (5 == GOA_PANEL_ACCOUNTS_MODEL_N_COLUMNS);
140
types[0] = G_TYPE_STRING;
141
types[1] = GOA_TYPE_OBJECT;
142
types[2] = G_TYPE_BOOLEAN;
143
types[3] = G_TYPE_STRING;
144
types[4] = G_TYPE_ICON;
146
gtk_list_store_set_column_types (GTK_LIST_STORE (model),
147
GOA_PANEL_ACCOUNTS_MODEL_N_COLUMNS,
150
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model),
151
GOA_PANEL_ACCOUNTS_MODEL_COLUMN_SORT_KEY,
154
g_signal_connect (model->client,
156
G_CALLBACK (on_account_added),
158
g_signal_connect (model->client,
160
G_CALLBACK (on_account_removed),
162
g_signal_connect (model->client,
164
G_CALLBACK (on_account_changed),
169
if (G_OBJECT_CLASS (goa_panel_accounts_model_parent_class)->constructed != NULL)
170
G_OBJECT_CLASS (goa_panel_accounts_model_parent_class)->constructed (object);
174
goa_panel_accounts_model_class_init (GoaPanelAccountsModelClass *klass)
176
GObjectClass *gobject_class;
178
gobject_class = G_OBJECT_CLASS (klass);
179
gobject_class->finalize = goa_panel_accounts_model_finalize;
180
gobject_class->constructed = goa_panel_accounts_model_constructed;
181
gobject_class->get_property = goa_panel_accounts_model_get_property;
182
gobject_class->set_property = goa_panel_accounts_model_set_property;
185
* GoaPanelAccountsModel:client:
187
* The #GoaClient used by the #GoaPanelAccountsModel instance.
189
g_object_class_install_property (gobject_class,
191
g_param_spec_object ("client",
193
"The client used by the tree model",
197
G_PARAM_CONSTRUCT_ONLY |
198
G_PARAM_STATIC_STRINGS));
202
* goa_panel_accounts_model_new:
203
* @client: A #GoaClient.
205
* Creates a new #GoaPanelAccountsModel for viewing the accounts known
208
* Returns: A #GoaPanelAccountsModel. Free with g_object_unref().
210
GoaPanelAccountsModel *
211
goa_panel_accounts_model_new (GoaClient *client)
213
return GOA_PANEL_ACCOUNTS_MODEL (g_object_new (GOA_TYPE_PANEL_ACCOUNTS_MODEL,
219
* goa_panel_accounts_model_get_client:
220
* @model: A #GoaPanelAccountsModel.
222
* Gets the #GoaClient used by @model.
224
* Returns: (transfer none): A #GoaClient. Do not free, the object
228
goa_panel_accounts_model_get_client (GoaPanelAccountsModel *model)
230
g_return_val_if_fail (GOA_IS_PANEL_ACCOUNTS_MODEL (model), NULL);
231
return model->client;
235
* goa_panel_accounts_model_get_iter_for_object:
236
* @model: A #GoaPanelAccountsModel.
237
* @object: A #GoaObject.
238
* @iter: (out): Return location for #GtkTreeIter.
240
* Finds @model<!-- -->'s row for @object.
242
* Returns: %TRUE if @iter was set, %FALSE if @object wasn't found.
245
goa_panel_accounts_model_get_iter_for_object (GoaPanelAccountsModel *model,
249
g_return_val_if_fail (GOA_IS_PANEL_ACCOUNTS_MODEL (model), FALSE);
250
g_return_val_if_fail (GOA_IS_OBJECT (object), FALSE);
251
g_return_val_if_fail (iter != NULL, FALSE);
252
return find_iter_for_object (model, object, iter);
255
/* ---------------------------------------------------------------------------------------------------- */
265
find_iter_for_object_cb (GtkTreeModel *model,
270
FindIterData *data = user_data;
271
GoaObject *iter_object;
275
gtk_tree_model_get (model,
277
GOA_PANEL_ACCOUNTS_MODEL_COLUMN_OBJECT, &iter_object,
279
if (iter_object == NULL)
282
if (iter_object == data->object)
290
if (iter_object != NULL)
291
g_object_unref (iter_object);
296
find_iter_for_object (GoaPanelAccountsModel *model,
298
GtkTreeIter *out_iter)
301
memset (&data, 0, sizeof (data));
302
data.object = object;
304
gtk_tree_model_foreach (GTK_TREE_MODEL (model),
305
find_iter_for_object_cb,
309
if (out_iter != NULL)
310
*out_iter = data.iter;
315
/* ---------------------------------------------------------------------------------------------------- */
318
set_values (GoaPanelAccountsModel *model,
327
account = goa_object_peek_account (object);
330
icon = g_icon_new_for_string (goa_account_get_provider_icon (account), &error);
333
goa_warning ("Error creating GIcon for account: %s (%s, %d)",
334
error->message, g_quark_to_string (error->domain), error->code);
335
g_error_free (error);
338
markup = g_strdup_printf ("<b>%s</b>\n<small>%s</small>",
339
goa_account_get_provider_name (account),
340
goa_account_get_presentation_identity (account));
342
gtk_list_store_set (GTK_LIST_STORE (model),
344
GOA_PANEL_ACCOUNTS_MODEL_COLUMN_SORT_KEY, goa_account_get_id (account),
345
GOA_PANEL_ACCOUNTS_MODEL_COLUMN_OBJECT, object,
346
GOA_PANEL_ACCOUNTS_MODEL_COLUMN_ATTENTION_NEEDED, goa_account_get_attention_needed (account),
347
GOA_PANEL_ACCOUNTS_MODEL_COLUMN_MARKUP, markup,
348
GOA_PANEL_ACCOUNTS_MODEL_COLUMN_ICON, icon,
352
g_clear_object (&icon);
356
add_account (GoaPanelAccountsModel *model,
360
gtk_list_store_insert (GTK_LIST_STORE (model),
362
G_MAXINT); /* position */
363
set_values (model, object, &iter);
367
remove_account (GoaPanelAccountsModel *model,
371
if (!find_iter_for_object (model, object, &iter))
373
goa_warning ("Error removing object %s - not in tree", g_dbus_object_get_object_path (G_DBUS_OBJECT (object)));
377
gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
382
update_account (GoaPanelAccountsModel *model,
386
if (!find_iter_for_object (model, object, &iter))
388
goa_warning ("Error updating object %s - not in tree", g_dbus_object_get_object_path (G_DBUS_OBJECT (object)));
392
set_values (model, object, &iter);
397
init_model (GoaPanelAccountsModel *model)
402
accounts = goa_client_get_accounts (model->client);
403
for (l = accounts; l != NULL; l = l->next)
405
GoaObject *object = GOA_OBJECT (l->data);
406
add_account (model, object);
408
g_list_foreach (accounts, (GFunc) g_object_unref, NULL);
409
g_list_free (accounts);
413
on_account_added (GoaClient *client,
417
GoaPanelAccountsModel *model = GOA_PANEL_ACCOUNTS_MODEL (user_data);
418
add_account (model, object);
422
on_account_removed (GoaClient *client,
426
GoaPanelAccountsModel *model = GOA_PANEL_ACCOUNTS_MODEL (user_data);
427
remove_account (model, object);
431
on_account_changed (GoaClient *client,
435
GoaPanelAccountsModel *model = GOA_PANEL_ACCOUNTS_MODEL (user_data);
436
update_account (model, object);