1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-names-model.c GtkTreeModel for names on the bus
4 * Copyright (C) 2005 Red Hat, Inc.
6 * Licensed under the Academic Free License version 2.1
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "dbus-names-model.h"
24 #include <glib/gi18n.h>
35 typedef struct NamesModel NamesModel;
36 typedef struct NamesModelClass NamesModelClass;
38 GType names_model_get_type (void);
43 DBusGConnection *connection;
44 DBusGProxy *driver_proxy;
45 DBusGPendingCall *pending_list_names;
48 struct NamesModelClass
50 GtkListStoreClass parent;
53 #define TYPE_NAMES_MODEL (names_model_get_type ())
54 #define NAMES_MODEL(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), TYPE_NAMES_MODEL, NamesModel))
55 #define NAMES_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_NAMES_MODEL, NamesModelClass))
56 #define IS_NAMES_MODEL(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), TYPE_NAMES_MODEL))
57 #define IS_NAMES_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_NAMES_MODEL))
58 #define NAMES_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_NAMES_MODEL, NamesModelClass))
61 have_names_notify (DBusGPendingCall *call,
64 NamesModel *names_model;
70 names_model = NAMES_MODEL (data);
72 g_assert (names_model->pending_list_names);
73 g_assert (names_model->driver_proxy);
77 if (!dbus_g_proxy_end_call (names_model->driver_proxy,
78 names_model->pending_list_names,
79 &error, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
80 &names, &n_elements, DBUS_TYPE_INVALID))
82 g_assert (names == NULL);
83 g_assert (error != NULL);
85 g_printerr (_("Failed to load names on the bus: %s\n"), error->message);
95 g_assert (i < n_elements);
98 g_printerr ("%d of %d: %s\n",
99 i, n_elements, names[i]);
102 gtk_list_store_append (GTK_LIST_STORE (names_model),
105 gtk_list_store_set (GTK_LIST_STORE (names_model),
107 MODEL_COLUMN_NAME, names[i],
117 names_model_find_name (NamesModel *names_model,
123 if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (names_model),
131 gtk_tree_model_get (GTK_TREE_MODEL (names_model),
133 MODEL_COLUMN_NAME, &s,
135 if (s && strcmp (s, name) == 0)
144 while (gtk_tree_model_iter_next (GTK_TREE_MODEL (names_model),
151 name_owner_changed (DBusGProxy *driver_proxy,
153 const char *old_owner,
154 const char *new_owner,
157 NamesModel *names_model = NAMES_MODEL (data);
160 g_printerr ("Name '%s' changed owner '%s' -> '%s'\n",
161 name, old_owner, new_owner);
164 if (*new_owner == '\0')
166 /* this name has vanished */
169 if (names_model_find_name (names_model, name, &iter))
170 gtk_list_store_remove (GTK_LIST_STORE (names_model),
173 else if (*old_owner == '\0')
175 /* this name has been added */
178 if (!names_model_find_name (names_model, name, &iter))
180 gtk_list_store_append (GTK_LIST_STORE (names_model),
183 gtk_list_store_set (GTK_LIST_STORE (names_model),
185 MODEL_COLUMN_NAME, name,
192 names_model_reload (NamesModel *names_model)
194 GtkListStore *list_store;
196 list_store = GTK_LIST_STORE (names_model);
198 if (names_model->pending_list_names)
200 dbus_g_pending_call_cancel (names_model->pending_list_names);
201 dbus_g_pending_call_unref (names_model->pending_list_names);
202 names_model->pending_list_names = NULL;
205 gtk_list_store_clear (list_store);
207 if (names_model->connection == NULL)
210 names_model->pending_list_names =
211 dbus_g_proxy_begin_call (names_model->driver_proxy,
215 dbus_g_pending_call_set_notify (names_model->pending_list_names,
216 have_names_notify, names_model, NULL);
220 names_model_set_connection (NamesModel *names_model,
221 DBusGConnection *connection)
223 g_return_if_fail (IS_NAMES_MODEL (names_model));
225 if (connection == names_model->connection)
228 if (names_model->connection)
230 dbus_g_proxy_disconnect_signal (names_model->driver_proxy,
232 G_CALLBACK (name_owner_changed),
235 g_object_unref (names_model->driver_proxy);
236 names_model->driver_proxy = NULL;
237 dbus_g_connection_unref (names_model->connection);
238 names_model->connection = NULL;
243 names_model->connection = connection;
244 dbus_g_connection_ref (names_model->connection);
246 names_model->driver_proxy =
247 dbus_g_proxy_new_for_name (names_model->connection,
250 DBUS_INTERFACE_DBUS);
251 g_assert (names_model->driver_proxy);
253 dbus_g_proxy_add_signal (names_model->driver_proxy,
255 DBUS_TYPE_STRING_AS_STRING
256 DBUS_TYPE_STRING_AS_STRING
257 DBUS_TYPE_STRING_AS_STRING);
259 dbus_g_proxy_connect_signal (names_model->driver_proxy,
261 G_CALLBACK (name_owner_changed),
266 names_model_reload (names_model);
269 G_DEFINE_TYPE(NamesModel, names_model, GTK_TYPE_LIST_STORE)
279 names_model_dispose (GObject *object)
281 NamesModel *names_model = NAMES_MODEL (object);
283 names_model_set_connection (names_model, NULL);
285 g_assert (names_model->connection == NULL);
286 g_assert (names_model->driver_proxy == NULL);
287 g_assert (names_model->pending_list_names == NULL);
289 (G_OBJECT_CLASS (names_model_parent_class)->dispose) (object);
293 names_model_finalize (GObject *object)
295 NamesModel *names_model = NAMES_MODEL (object);
297 g_assert (names_model->connection == NULL);
298 g_assert (names_model->driver_proxy == NULL);
299 g_assert (names_model->pending_list_names == NULL);
301 (G_OBJECT_CLASS (names_model_parent_class)->finalize) (object);
305 names_model_set_property (GObject *object,
310 NamesModel *names_model;
312 names_model = NAMES_MODEL (object);
316 case PROP_CONNECTION:
317 names_model_set_connection (names_model, g_value_get_boxed (value));
321 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
327 names_model_get_property (GObject *object,
332 NamesModel *names_model;
334 names_model = NAMES_MODEL (object);
338 case PROP_CONNECTION:
339 g_value_set_boxed (value, names_model->connection);
343 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
349 names_model_init (NamesModel *names_model)
351 GtkListStore *list_store;
352 GType types[MODEL_COLUMN_LAST];
354 list_store = GTK_LIST_STORE (names_model);
356 types[0] = G_TYPE_STRING; /* name */
357 gtk_list_store_set_column_types (list_store, MODEL_COLUMN_LAST, types);
361 names_model_class_init (NamesModelClass *names_model_class)
363 GObjectClass *gobject_class = G_OBJECT_CLASS (names_model_class);
365 gobject_class->finalize = names_model_finalize;
366 gobject_class->dispose = names_model_dispose;
367 gobject_class->set_property = names_model_set_property;
368 gobject_class->get_property = names_model_get_property;
370 g_object_class_install_property (gobject_class,
372 g_param_spec_boxed ("connection",
374 _("Connection to the message bus"),
375 DBUS_TYPE_G_CONNECTION,
380 names_model_new (DBusGConnection *connection)
382 NamesModel *names_model;
384 names_model = g_object_new (TYPE_NAMES_MODEL,
385 "connection", connection,
388 return GTK_TREE_MODEL (names_model);