~ubuntu-branches/ubuntu/lucid/seahorse/lucid

« back to all changes in this revision

Viewing changes to libseahorse/seahorse-object-model.c

  • Committer: Bazaar Package Importer
  • Author(s): Christophe Sauthier
  • Date: 2009-01-08 17:05:02 UTC
  • mfrom: (1.2.39 upstream)
  • Revision ID: james.westby@ubuntu.com-20090108170502-zs2i7svo0b7l3ecz
Tags: 2.25.4-0ubuntu1
* New upstream version (LP: #315147).
* Update debian/patches/80_autoconf_update.patch
* debian/rules:
  - addition of a shlibs rule for libcryptui0 (>= 2.25.4)
* Fix bdeps to match upstream configure check:
  - set libgnome-keyring-dev to (>= 2.25.3).
  - add libtasn1-3-dev.
* debian/seahorse.install:
  - inclusion of debian/tmp/usr/share/gnome/autostart/seahorse-daemon.desktop.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Seahorse
 
3
 *
 
4
 * Copyright (C) 2006 Stefan Walter
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation; either version 2 of the License, or
 
9
 * (at your option) any later version.
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
14
 * See the GNU General Public License for more details.
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the
 
17
 * Free Software Foundation, Inc.,
 
18
 * 59 Temple Place, Suite 330,
 
19
 * Boston, MA 02111-1307, USA.
 
20
 */
 
21
 
 
22
#include "config.h"
 
23
 
 
24
#include <string.h>
 
25
 
 
26
#include "seahorse-object-model.h"
 
27
#include "seahorse-marshal.h"
 
28
 
 
29
#include "common/seahorse-bind.h"
 
30
 
 
31
enum {
 
32
    PROP_0,
 
33
    PROP_DATA_COLUMN,
 
34
};
 
35
 
 
36
enum {
 
37
    UPDATE_ROW,
 
38
    LAST_SIGNAL
 
39
};
 
40
 
 
41
static guint signals[LAST_SIGNAL] = { 0 };
 
42
 
 
43
typedef struct _SeahorseObjectModelPrivate {
 
44
    GHashTable *rows;
 
45
    guint data_column;
 
46
} SeahorseObjectModelPrivate;
 
47
 
 
48
G_DEFINE_TYPE (SeahorseObjectModel, seahorse_object_model, GTK_TYPE_TREE_STORE);
 
49
 
 
50
#define SEAHORSE_OBJECT_MODEL_GET_PRIVATE(obj)  \
 
51
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), SEAHORSE_TYPE_OBJECT_MODEL, SeahorseObjectModelPrivate))
 
52
 
 
53
/* Internal data stored at 0 in the tree store in order to keep track
 
54
 * of the location, key-store and key.
 
55
 */
 
56
typedef struct {
 
57
        SeahorseObjectModel *self;
 
58
        GPtrArray           *refs;     /* GtkTreeRowReference pointers */
 
59
        SeahorseObject      *object;     /* The key we're dealing with */
 
60
        gpointer            binding;
 
61
} SeahorseObjectRow;
 
62
 
 
63
/* -----------------------------------------------------------------------------
 
64
 * INTERNAL 
 
65
 */
 
66
 
 
67
static void
 
68
key_notify (SeahorseObject *object, SeahorseObjectModel *self)
 
69
{
 
70
    SeahorseObjectModelPrivate *pv = SEAHORSE_OBJECT_MODEL_GET_PRIVATE (self);
 
71
    SeahorseObjectRow *skrow;
 
72
    GtkTreeIter iter;
 
73
    GtkTreePath *path;
 
74
    int i;
 
75
 
 
76
    skrow = g_hash_table_lookup (pv->rows, object);
 
77
    if (!skrow)
 
78
        return;
 
79
    
 
80
    for (i = 0; i < skrow->refs->len; i++) {
 
81
        
 
82
        path = gtk_tree_row_reference_get_path (g_ptr_array_index (skrow->refs, i));
 
83
        if (path) {
 
84
            gtk_tree_model_get_iter (GTK_TREE_MODEL (self), &iter, path);
 
85
            g_signal_emit (self, signals[UPDATE_ROW], 0, object, &iter);
 
86
            gtk_tree_path_free (path);
 
87
        }
 
88
    }
 
89
}
 
90
 
 
91
static void
 
92
key_destroyed (gpointer data, GObject *was)
 
93
{
 
94
        SeahorseObjectModelPrivate *pv = SEAHORSE_OBJECT_MODEL_GET_PRIVATE (data);
 
95
        SeahorseObjectRow *skrow = g_hash_table_lookup (pv->rows, was);
 
96
        if (skrow) {
 
97
                skrow->object = NULL;
 
98
                skrow->binding = NULL;
 
99
                g_hash_table_remove (pv->rows, was);
 
100
        }
 
101
}
 
102
 
 
103
 
 
104
static gboolean
 
105
remove_each (SeahorseObject *object, gchar *path, SeahorseObjectModel *self)
 
106
{
 
107
    return TRUE;
 
108
}
 
109
 
 
110
static SeahorseObjectRow*
 
111
key_row_new (SeahorseObjectModel *self, SeahorseObject *object)
 
112
{
 
113
    SeahorseObjectRow *skrow;
 
114
    
 
115
    g_assert (SEAHORSE_IS_OBJECT_MODEL (self));
 
116
    g_assert (SEAHORSE_IS_OBJECT (object));
 
117
    
 
118
    skrow = g_new0 (SeahorseObjectRow, 1);
 
119
    skrow->refs = g_ptr_array_new ();
 
120
    skrow->self = self;
 
121
    skrow->object = object;
 
122
    skrow->binding = seahorse_bind_objects (NULL, object, (SeahorseTransfer)key_notify, self);
 
123
    
 
124
    g_object_weak_ref (G_OBJECT (object), key_destroyed, self);
 
125
    
 
126
    return skrow;
 
127
}
 
128
 
 
129
static void
 
130
key_row_free (SeahorseObjectRow *skrow)
 
131
{
 
132
    SeahorseObjectModel *self = skrow->self;
 
133
    SeahorseObjectModelPrivate *pv = SEAHORSE_OBJECT_MODEL_GET_PRIVATE (self);
 
134
    GtkTreeRowReference *ref;
 
135
    GtkTreePath *path;
 
136
    GtkTreeIter iter;
 
137
    guint i;
 
138
    
 
139
    g_return_if_fail (pv->data_column != -1);
 
140
    
 
141
    for (i = 0; i < skrow->refs->len; i++) {
 
142
        
 
143
        ref = (GtkTreeRowReference*)g_ptr_array_index (skrow->refs, i);
 
144
        if (ref) {
 
145
            path = gtk_tree_row_reference_get_path (ref);
 
146
            if (path) {
 
147
                gtk_tree_model_get_iter (GTK_TREE_MODEL (self), &iter, path);
 
148
                gtk_tree_store_set (GTK_TREE_STORE (self), &iter, 
 
149
                                    pv->data_column, NULL, -1);
 
150
                gtk_tree_path_free (path);
 
151
            }
 
152
            gtk_tree_row_reference_free (ref);
 
153
        }
 
154
        
 
155
    }
 
156
    
 
157
    if (skrow->binding)
 
158
            seahorse_bind_disconnect (skrow->binding);
 
159
    if (skrow->object)
 
160
            g_object_weak_unref (G_OBJECT (skrow->object), key_destroyed, skrow->self);
 
161
 
 
162
    g_ptr_array_free (skrow->refs, TRUE);
 
163
    g_free (skrow);
 
164
}
 
165
 
 
166
static void
 
167
row_inserted (SeahorseObjectModel *self, GtkTreePath *path, GtkTreeIter *iter, 
 
168
              gpointer user_data)
 
169
{
 
170
    SeahorseObjectModelPrivate *pv = SEAHORSE_OBJECT_MODEL_GET_PRIVATE (self);
 
171
    g_return_if_fail (pv->data_column != -1);
 
172
    /* XXX: The following line causes problems with GtkTreeModelFilter */
 
173
    /* gtk_tree_store_set (GTK_TREE_STORE (self), iter, pv->data_column, NULL, -1); */
 
174
}
 
175
 
 
176
/* -----------------------------------------------------------------------------
 
177
 * OBJECT 
 
178
 */
 
179
 
 
180
static void
 
181
seahorse_object_model_init (SeahorseObjectModel *self)
 
182
{
 
183
    SeahorseObjectModelPrivate *pv = SEAHORSE_OBJECT_MODEL_GET_PRIVATE (self);
 
184
    pv->rows = g_hash_table_new_full (g_direct_hash, g_direct_equal,
 
185
                                      NULL, (GDestroyNotify)key_row_free);
 
186
    pv->data_column = -1;
 
187
    g_signal_connect (self, "row-inserted", G_CALLBACK (row_inserted), NULL);
 
188
}
 
189
 
 
190
static void
 
191
seahorse_object_model_set_property (GObject *gobject, guint prop_id,
 
192
                                 const GValue *value, GParamSpec *pspec)
 
193
{
 
194
    SeahorseObjectModel *self = SEAHORSE_OBJECT_MODEL (gobject);
 
195
    SeahorseObjectModelPrivate *pv = SEAHORSE_OBJECT_MODEL_GET_PRIVATE (self);
 
196
 
 
197
    switch (prop_id) {
 
198
    case PROP_DATA_COLUMN:
 
199
        g_assert (pv->data_column == -1);
 
200
        pv->data_column = g_value_get_uint (value);
 
201
        break;
 
202
    }
 
203
}
 
204
 
 
205
static void
 
206
seahorse_object_model_get_property (GObject *gobject, guint prop_id,
 
207
                                 GValue *value, GParamSpec *pspec)
 
208
{
 
209
    SeahorseObjectModel *self = SEAHORSE_OBJECT_MODEL (gobject);
 
210
    SeahorseObjectModelPrivate *pv = SEAHORSE_OBJECT_MODEL_GET_PRIVATE (self);
 
211
 
 
212
    switch (prop_id) {
 
213
    case PROP_DATA_COLUMN:
 
214
        g_value_set_uint (value, pv->data_column);
 
215
        break;
 
216
    }
 
217
}
 
218
 
 
219
static void
 
220
seahorse_object_model_dispose (GObject *gobject)
 
221
{
 
222
    SeahorseObjectModel *self = SEAHORSE_OBJECT_MODEL (gobject);
 
223
    SeahorseObjectModelPrivate *pv = SEAHORSE_OBJECT_MODEL_GET_PRIVATE (self);
 
224
    
 
225
    /* Release all our pointers and stuff */
 
226
    g_hash_table_foreach_remove (pv->rows, (GHRFunc)remove_each, self);
 
227
    G_OBJECT_CLASS (seahorse_object_model_parent_class)->dispose (gobject);
 
228
}
 
229
 
 
230
static void
 
231
seahorse_object_model_finalize (GObject *gobject)
 
232
{
 
233
    SeahorseObjectModel *self = SEAHORSE_OBJECT_MODEL (gobject);
 
234
    SeahorseObjectModelPrivate *pv = SEAHORSE_OBJECT_MODEL_GET_PRIVATE (self);
 
235
 
 
236
    if (pv->rows)
 
237
        g_hash_table_destroy (pv->rows);
 
238
    pv->rows = NULL;
 
239
    
 
240
    G_OBJECT_CLASS (seahorse_object_model_parent_class)->finalize (gobject);
 
241
}
 
242
 
 
243
static void
 
244
seahorse_object_model_class_init (SeahorseObjectModelClass *klass)
 
245
{
 
246
    GObjectClass *gobject_class;
 
247
    
 
248
    seahorse_object_model_parent_class = g_type_class_peek_parent (klass);
 
249
    gobject_class = G_OBJECT_CLASS (klass);
 
250
    
 
251
    gobject_class->dispose = seahorse_object_model_dispose;
 
252
    gobject_class->finalize = seahorse_object_model_finalize;
 
253
    gobject_class->set_property = seahorse_object_model_set_property;
 
254
    gobject_class->get_property = seahorse_object_model_get_property;
 
255
    
 
256
    g_object_class_install_property (gobject_class, PROP_DATA_COLUMN,
 
257
        g_param_spec_uint ("data-column", "Column data is stored", "Column where internal data is stored",
 
258
                           0, ~0, 0, G_PARAM_READWRITE | G_PARAM_READWRITE));
 
259
 
 
260
    signals[UPDATE_ROW] = g_signal_new ("update-row", SEAHORSE_TYPE_OBJECT_MODEL, 
 
261
                G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (SeahorseObjectModelClass, update_row),
 
262
                NULL, NULL, seahorse_marshal_VOID__OBJECT_POINTER, G_TYPE_NONE, 2, SEAHORSE_TYPE_OBJECT, G_TYPE_POINTER);
 
263
    
 
264
    g_type_class_add_private (klass, sizeof (SeahorseObjectModelPrivate));
 
265
}
 
266
 
 
267
/* -----------------------------------------------------------------------------
 
268
 * PUBLIC 
 
269
 */
 
270
 
 
271
 
 
272
SeahorseObjectModel* 
 
273
seahorse_object_model_new (gint n_columns, GType *types)
 
274
{
 
275
    SeahorseObjectModel *model;
 
276
    
 
277
    model = g_object_new (SEAHORSE_TYPE_OBJECT_MODEL, NULL);
 
278
    seahorse_object_model_set_column_types (model, n_columns, types);
 
279
    
 
280
    return model;
 
281
}
 
282
 
 
283
void
 
284
seahorse_object_model_set_column_types (SeahorseObjectModel *self, gint n_columns,
 
285
                                     GType *types)
 
286
{
 
287
    SeahorseObjectModelPrivate *pv = SEAHORSE_OBJECT_MODEL_GET_PRIVATE (self);
 
288
    GType *itypes;
 
289
    
 
290
    g_return_if_fail (SEAHORSE_IS_OBJECT_MODEL (self));
 
291
 
 
292
    itypes = g_new0(GType, n_columns + 1);
 
293
    memcpy (itypes, types, n_columns * sizeof (GType));
 
294
 
 
295
    itypes[n_columns] = G_TYPE_POINTER;
 
296
    pv->data_column = n_columns;
 
297
    gtk_tree_store_set_column_types (GTK_TREE_STORE (self), n_columns + 1, itypes);
 
298
    
 
299
    g_free (itypes);
 
300
}
 
301
 
 
302
void
 
303
seahorse_object_model_set_row_object (SeahorseObjectModel *self, GtkTreeIter *iter,
 
304
                                      SeahorseObject *object)
 
305
{
 
306
    SeahorseObjectModelPrivate *pv = SEAHORSE_OBJECT_MODEL_GET_PRIVATE (self);
 
307
    SeahorseObjectRow *skrow;
 
308
    GtkTreePath *path;
 
309
    GtkTreePath *ipath;
 
310
    int i;
 
311
    
 
312
    g_return_if_fail (SEAHORSE_IS_OBJECT_MODEL (self));
 
313
    g_return_if_fail (SEAHORSE_IS_OBJECT (object) || object == NULL);
 
314
    g_return_if_fail (pv->data_column >= 0);
 
315
    
 
316
    /* Add the row/key association */
 
317
    if (object) {
 
318
        
 
319
        /* Do we already have a row for this key? */
 
320
        skrow = (SeahorseObjectRow*)g_hash_table_lookup (pv->rows, object);
 
321
        if (!skrow) {
 
322
            skrow = key_row_new (self, object);
 
323
 
 
324
            /* Put it in our row cache */
 
325
            g_hash_table_replace (pv->rows, object, skrow);
 
326
        }
 
327
        
 
328
        path = gtk_tree_model_get_path (GTK_TREE_MODEL (self), iter);
 
329
        g_ptr_array_add (skrow->refs, gtk_tree_row_reference_new (GTK_TREE_MODEL (self), path));
 
330
        gtk_tree_path_free (path);
 
331
        
 
332
    /* Remove the row/key association */
 
333
    } else {
 
334
        
 
335
        gtk_tree_model_get (GTK_TREE_MODEL (self), iter, pv->data_column, &skrow, -1);
 
336
        if (skrow) {
 
337
            
 
338
            ipath = gtk_tree_model_get_path (GTK_TREE_MODEL (self), iter);
 
339
            g_return_if_fail (ipath != NULL);
 
340
            
 
341
            for (i = 0; i < skrow->refs->len; i++) {
 
342
                
 
343
                path = gtk_tree_row_reference_get_path (g_ptr_array_index (skrow->refs, i));
 
344
                
 
345
                /* Check if they're the same or invalid, remove */
 
346
                if (!path || gtk_tree_path_compare (path, ipath) == 0) {
 
347
                    gtk_tree_row_reference_free (g_ptr_array_index (skrow->refs, i));
 
348
                    g_ptr_array_remove_index_fast (skrow->refs, i);
 
349
                    i--;
 
350
                }
 
351
 
 
352
                if (path)
 
353
                    gtk_tree_path_free (path);
 
354
            }
 
355
            
 
356
            /* If we no longer have rows associated with this key, then remove */
 
357
            if (skrow->refs->len == 0)
 
358
                g_hash_table_remove (pv->rows, skrow->object);
 
359
        }
 
360
    }
 
361
    
 
362
    gtk_tree_store_set (GTK_TREE_STORE (self), iter, 
 
363
                        pv->data_column, object ? skrow : NULL, -1);
 
364
    
 
365
    if (object)
 
366
        key_notify (object, self);
 
367
}
 
368
 
 
369
SeahorseObject*
 
370
seahorse_object_model_get_row_key (SeahorseObjectModel *self, GtkTreeIter *iter)
 
371
{
 
372
    SeahorseObjectModelPrivate *pv = SEAHORSE_OBJECT_MODEL_GET_PRIVATE (self);
 
373
    SeahorseObjectRow *skrow;
 
374
    
 
375
    g_return_val_if_fail (SEAHORSE_IS_OBJECT_MODEL (self), NULL);
 
376
    g_return_val_if_fail (pv->data_column >= 0, NULL);
 
377
    
 
378
    gtk_tree_model_get (GTK_TREE_MODEL (self), iter, pv->data_column, &skrow, -1);
 
379
    if (!skrow)
 
380
        return NULL;
 
381
    g_assert (SEAHORSE_IS_OBJECT (skrow->object));
 
382
    return skrow->object;
 
383
}
 
384
 
 
385
void
 
386
seahorse_object_model_remove_rows_for_object (SeahorseObjectModel *self, SeahorseObject *object)
 
387
{
 
388
    SeahorseObjectModelPrivate *pv = SEAHORSE_OBJECT_MODEL_GET_PRIVATE (self);
 
389
    SeahorseObjectRow *skrow;
 
390
    GtkTreeIter iter;
 
391
    GtkTreePath *path;
 
392
    int i;
 
393
    
 
394
    g_return_if_fail (SEAHORSE_IS_OBJECT_MODEL (self));
 
395
    g_return_if_fail (SEAHORSE_IS_OBJECT (object));
 
396
    g_return_if_fail (pv->data_column >= 0);
 
397
    
 
398
    skrow = (SeahorseObjectRow*)g_hash_table_lookup (pv->rows, object);
 
399
    if (!skrow) 
 
400
        return;
 
401
    
 
402
    for (i = 0; i < skrow->refs->len; i++) {
 
403
        
 
404
        path = gtk_tree_row_reference_get_path (g_ptr_array_index (skrow->refs, i));
 
405
        if (path) {
 
406
            gtk_tree_model_get_iter (GTK_TREE_MODEL (self), &iter, path);
 
407
            gtk_tree_store_remove (GTK_TREE_STORE (self), &iter);
 
408
            gtk_tree_path_free (path);
 
409
        }
 
410
    }
 
411
    
 
412
    /* We no longer have rows associated with this key, then remove */
 
413
    g_hash_table_remove (pv->rows, object);
 
414
}
 
415
 
 
416
GSList*
 
417
seahorse_object_model_get_rows_for_object (SeahorseObjectModel *self, SeahorseObject *object)
 
418
{
 
419
    SeahorseObjectModelPrivate *pv = SEAHORSE_OBJECT_MODEL_GET_PRIVATE (self);
 
420
    GSList *rows = NULL;
 
421
    SeahorseObjectRow *skrow;
 
422
    GtkTreeIter *iter;
 
423
    GtkTreePath *path;
 
424
    int i;
 
425
    
 
426
    g_return_val_if_fail (SEAHORSE_IS_OBJECT_MODEL (self), NULL);
 
427
    g_return_val_if_fail (SEAHORSE_IS_OBJECT (object), NULL);
 
428
    
 
429
    skrow = (SeahorseObjectRow*)g_hash_table_lookup (pv->rows, object);
 
430
    if (!skrow) 
 
431
        return NULL;
 
432
    
 
433
    for (i = 0; i < skrow->refs->len; i++) {
 
434
        
 
435
        path = gtk_tree_row_reference_get_path (g_ptr_array_index (skrow->refs, i));
 
436
        if (path) {
 
437
            iter = g_new0(GtkTreeIter, 1);
 
438
            gtk_tree_model_get_iter (GTK_TREE_MODEL (self), iter, path);
 
439
            rows = g_slist_prepend (rows, iter);
 
440
            gtk_tree_path_free (path);
 
441
        }
 
442
    }
 
443
    
 
444
    return rows;
 
445
}
 
446
 
 
447
void
 
448
seahorse_object_model_free_rows (GSList *rows)
 
449
{
 
450
    GSList *l;
 
451
    for (l = rows; l; l = g_slist_next (l))
 
452
        g_free (l->data);
 
453
    g_slist_free (rows);
 
454
}