~ubuntu-branches/ubuntu/precise/gnome-keyring/precise

« back to all changes in this revision

Viewing changes to gcr/gcr-tree-selector.c

  • Committer: Bazaar Package Importer
  • Author(s): Chris Coulson, Chris Coulson, Mathieu Trudel-Lapierre
  • Date: 2011-08-10 12:29:33 UTC
  • mfrom: (1.1.70 upstream)
  • Revision ID: james.westby@ubuntu.com-20110810122933-0ezu9rqbnw956vwn
Tags: 3.1.4-0ubuntu1
[ Chris Coulson ]
* New upstream release
* Drop the multi-flavor (gtk2/gtk3) build - the new version supports
  only gtk3
  - update debian/rules
  - bump debian/compat to 7, else we need to add debian/tmp back to all
    the install files so that dh_install can find them (or continue to
    specify DEB_DH_INSTALL_SOURCEDIR in debian/rules)
  - Drop libgcr1 and libgcr-dev from debian/control.in
  - Remove debian/libgcr1.install and debian/libgcr-dev.install
  - Drop the libgtk2.0-dev build-depend
* Update for the libgck -> libgck-1 soname change
  - update debian/control
  - rename debian/libgck0.install => debian/libgck-1-0.install
  - update debian/libgck-1-0.install
  - rename debian/libgck0.symbols => debian/libgck-1-0.symbols
  - update debian/libgck-1-0.symbols
  - rename debian/libgck-dev.install => debian/libgck-1-dev.install
  - update debian/libgck-1-dev.install
* Update symbols for libgcr-3. Note that upstream removed some symbols
  without bumping the soname (in addition to adding symbols). However,
  these aren't actually used anywhere, and they have only ever existed
  in the current unstable series so we just ignore this for now :/
  - update debian/libgcr-3-1.symbols
* Drop debian/patches/05_onlyshowin_unity.patch - fixed upstream
* Add build-depend on libp11-kit-dev
* Install the contents of /usr/share/icons and /etc/pkcs11
  - update debian/gnome-keyring.install
* Revert an unintentional change of the libgcr soname to an older version
  - add debian/patches/05_revert_gcr_soname_bump.patch
  - update debian/patches/series

[ Mathieu Trudel-Lapierre ]
* debian/patches/99git_fs_caps_11a5d41.patch,
  debian/patches/99git_ipc_lock_caps_ad67edd.patch: dropped, included in
  release upstream tarball.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * gnome-keyring
 
3
 *
 
4
 * Copyright (C) 2010 Stefan Walter
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU Lesser General Public License as
 
8
 * published by the Free Software Foundation; either version 2.1 of
 
9
 * the License, or (at your option) any later version.
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful, but
 
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
 * Lesser General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU Lesser General Public
 
17
 * License along with this program; if not, write to the Free Software
 
18
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 
19
 * 02111-1307, USA.
 
20
 */
 
21
 
 
22
#include "config.h"
 
23
 
 
24
#include "gcr-collection-model.h"
 
25
#include "gcr-internal.h"
 
26
#include "gcr-tree-selector.h"
 
27
 
 
28
#include <glib/gi18n-lib.h>
 
29
 
 
30
#include <string.h>
 
31
 
 
32
/**
 
33
 * SECTION:gcr-tree-selector
 
34
 * @title: GcrTreeSelector
 
35
 * @short_description: A selector widget to select certificates or keys.
 
36
 *
 
37
 * The #GcrTreeSelector can be used to select certificates or keys. It allows
 
38
 * the user to select multiple objects from a tree.
 
39
 */
 
40
 
 
41
/**
 
42
 * GcrTreeSelector:
 
43
 * @parent: The parent object
 
44
 *
 
45
 * A tree selector widget.
 
46
 */
 
47
 
 
48
/**
 
49
 * GcrTreeSelectorClass:
 
50
 *
 
51
 * The class for #GcrTreeSelector.
 
52
 */
 
53
 
 
54
enum {
 
55
        PROP_0,
 
56
        PROP_COLLECTION,
 
57
        PROP_COLUMNS
 
58
};
 
59
 
 
60
struct _GcrTreeSelectorPrivate {
 
61
        GcrCollection *collection;
 
62
        const GcrColumn *columns;
 
63
        GtkTreeModel *sort;
 
64
        GcrCollectionModel *model;
 
65
};
 
66
 
 
67
G_DEFINE_TYPE (GcrTreeSelector, gcr_tree_selector, GTK_TYPE_TREE_VIEW);
 
68
 
 
69
/* -----------------------------------------------------------------------------
 
70
 * INTERNAL
 
71
 */
 
72
 
 
73
static void
 
74
on_check_column_toggled (GtkCellRendererToggle *cell, gchar *path, GcrCollectionModel *model)
 
75
{
 
76
        GtkTreeIter iter;
 
77
 
 
78
        g_assert (path != NULL);
 
79
 
 
80
        if (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (model), &iter, path))
 
81
                gcr_collection_model_toggle_selected (model, &iter);
 
82
}
 
83
 
 
84
typedef gint (*SortFunc) (GValue *, GValue *);
 
85
 
 
86
static gint
 
87
sort_string (GValue *val_a, GValue *val_b)
 
88
{
 
89
        const gchar *str_a = g_value_get_string (val_a);
 
90
        const gchar *str_b = g_value_get_string (val_b);
 
91
 
 
92
        if (str_a == str_b)
 
93
                return 0;
 
94
        else if (!str_a)
 
95
                return -1;
 
96
        else if (!str_b)
 
97
                return 1;
 
98
        else
 
99
                return g_utf8_collate (str_a, str_b);
 
100
}
 
101
 
 
102
static gint
 
103
sort_date (GValue *val_a, GValue *val_b)
 
104
{
 
105
        GDate *date_a = g_value_get_boxed (val_a);
 
106
        GDate *date_b = g_value_get_boxed (val_b);
 
107
 
 
108
        if (date_a == date_b)
 
109
                return 0;
 
110
        else if (!date_a)
 
111
                return -1;
 
112
        else if (!date_b)
 
113
                return 1;
 
114
        else
 
115
                return g_date_compare (date_a, date_b);
 
116
}
 
117
 
 
118
static inline SortFunc
 
119
sort_implementation_for_type (GType type)
 
120
{
 
121
        if (type == G_TYPE_STRING)
 
122
                return sort_string;
 
123
        else if (type == G_TYPE_DATE)
 
124
                return sort_date;
 
125
        else
 
126
                return NULL;
 
127
}
 
128
 
 
129
static gint
 
130
on_sort_column (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b,
 
131
                gpointer user_data)
 
132
{
 
133
        GcrColumn *column = user_data;
 
134
        SortFunc func;
 
135
        GObject *object_a;
 
136
        GObject *object_b;
 
137
        GValue val_a;
 
138
        GValue val_b;
 
139
        gint ret;
 
140
 
 
141
        object_a = gcr_collection_model_object_for_iter (GCR_COLLECTION_MODEL (model), a);
 
142
        g_return_val_if_fail (G_IS_OBJECT (object_a), 0);
 
143
        object_b = gcr_collection_model_object_for_iter (GCR_COLLECTION_MODEL (model), b);
 
144
        g_return_val_if_fail (G_IS_OBJECT (object_b), 0);
 
145
 
 
146
        memset (&val_a, 0, sizeof (val_a));
 
147
        memset (&val_b, 0, sizeof (val_b));
 
148
 
 
149
        g_value_init (&val_a, column->property_type);
 
150
        g_value_init (&val_b, column->property_type);
 
151
 
 
152
        g_object_get_property (object_a, column->property_name, &val_a);
 
153
        g_object_get_property (object_b, column->property_name, &val_b);
 
154
 
 
155
        func = sort_implementation_for_type (column->property_type);
 
156
        g_return_val_if_fail (func, 0);
 
157
 
 
158
        ret = (func) (&val_a, &val_b);
 
159
 
 
160
        g_value_unset (&val_a);
 
161
        g_value_unset (&val_b);
 
162
 
 
163
        return ret;
 
164
}
 
165
 
 
166
static void
 
167
add_string_column (GcrTreeSelector *self, const GcrColumn *column, gint column_id)
 
168
{
 
169
        GtkCellRenderer *cell;
 
170
        GtkTreeViewColumn *col;
 
171
        const gchar *label;
 
172
 
 
173
        g_assert (column->column_type == G_TYPE_STRING);
 
174
        g_assert (!(column->flags & GCR_COLUMN_HIDDEN));
 
175
 
 
176
        cell = gtk_cell_renderer_text_new ();
 
177
        g_object_set (G_OBJECT (cell), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
 
178
        label = column->label ? g_dpgettext2 (NULL, "column", column->label) : "";
 
179
        col = gtk_tree_view_column_new_with_attributes (label, cell, "text", column_id, NULL);
 
180
        gtk_tree_view_column_set_resizable (col, TRUE);
 
181
        if (column->flags & GCR_COLUMN_SORTABLE)
 
182
                gtk_tree_view_column_set_sort_column_id (col, column_id);
 
183
        gtk_tree_view_append_column (GTK_TREE_VIEW (self), col);
 
184
}
 
185
 
 
186
static void
 
187
add_icon_column (GcrTreeSelector *self, const GcrColumn *column, gint column_id)
 
188
{
 
189
        GtkCellRenderer *cell;
 
190
        GtkTreeViewColumn *col;
 
191
        const gchar *label;
 
192
 
 
193
        g_assert (column->column_type == G_TYPE_ICON);
 
194
        g_assert (!(column->flags & GCR_COLUMN_HIDDEN));
 
195
 
 
196
        cell = gtk_cell_renderer_pixbuf_new ();
 
197
        g_object_set (cell, "stock-size", GTK_ICON_SIZE_BUTTON, NULL);
 
198
        label = column->label ? g_dpgettext2 (NULL, "column", column->label) : "";
 
199
        col = gtk_tree_view_column_new_with_attributes (label, cell, "gicon", column_id, NULL);
 
200
        gtk_tree_view_column_set_resizable (col, TRUE);
 
201
        if (column->flags & GCR_COLUMN_SORTABLE)
 
202
                gtk_tree_view_column_set_sort_column_id (col, column_id);
 
203
        gtk_tree_view_append_column (GTK_TREE_VIEW (self), col);
 
204
}
 
205
 
 
206
static void
 
207
add_check_column (GcrTreeSelector *self, guint column_id)
 
208
{
 
209
        GtkCellRenderer *cell;
 
210
        GtkTreeViewColumn *col;
 
211
 
 
212
        cell = gtk_cell_renderer_toggle_new ();
 
213
        g_signal_connect (cell, "toggled", G_CALLBACK (on_check_column_toggled), self->pv->model);
 
214
 
 
215
        col = gtk_tree_view_column_new_with_attributes ("", cell, "active", column_id, NULL);
 
216
        gtk_tree_view_column_set_resizable (col, FALSE);
 
217
        gtk_tree_view_append_column (GTK_TREE_VIEW (self), col);
 
218
}
 
219
 
 
220
/* -----------------------------------------------------------------------------
 
221
 * OBJECT
 
222
 */
 
223
 
 
224
static GObject*
 
225
gcr_tree_selector_constructor (GType type, guint n_props, GObjectConstructParam *props)
 
226
{
 
227
        GcrTreeSelector *self = GCR_TREE_SELECTOR (G_OBJECT_CLASS (gcr_tree_selector_parent_class)->constructor(type, n_props, props));
 
228
        const GcrColumn *column;
 
229
        GtkTreeSortable *sortable;
 
230
        guint i;
 
231
 
 
232
        g_return_val_if_fail (self, NULL);
 
233
        g_return_val_if_fail (self->pv->columns, NULL);
 
234
 
 
235
        self->pv->model = gcr_collection_model_new_full (self->pv->collection,
 
236
                                                         self->pv->columns);
 
237
 
 
238
        self->pv->sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (self->pv->model));
 
239
        sortable = GTK_TREE_SORTABLE (self->pv->sort);
 
240
 
 
241
        gtk_tree_view_set_model (GTK_TREE_VIEW (self), GTK_TREE_MODEL (self->pv->sort));
 
242
 
 
243
        /* First add the check mark column */
 
244
        add_check_column (self, gcr_collection_model_column_for_selected (self->pv->model));
 
245
 
 
246
        for (column = self->pv->columns, i = 0; column->property_name; ++column, ++i) {
 
247
                if (column->flags & GCR_COLUMN_HIDDEN)
 
248
                        continue;
 
249
 
 
250
                if (column->column_type == G_TYPE_STRING)
 
251
                        add_string_column (self, column, i);
 
252
                else if (column->column_type == G_TYPE_ICON)
 
253
                        add_icon_column (self, column, i);
 
254
                else
 
255
                        g_warning ("skipping unsupported column '%s' of type: %s",
 
256
                                   column->property_name, g_type_name (column->column_type));
 
257
 
 
258
                /* Setup the column itself */
 
259
                if (column->flags & GCR_COLUMN_SORTABLE) {
 
260
                        if (sort_implementation_for_type (column->property_type))
 
261
                                gtk_tree_sortable_set_sort_func (sortable, i, on_sort_column,
 
262
                                                                 (gpointer)column, NULL);
 
263
                        else
 
264
                                g_warning ("no sort implementation defined for type '%s' on column '%s'",
 
265
                                           g_type_name (column->property_type), column->property_name);
 
266
                }
 
267
        }
 
268
 
 
269
        return G_OBJECT (self);
 
270
}
 
271
 
 
272
static void
 
273
gcr_tree_selector_init (GcrTreeSelector *self)
 
274
{
 
275
        self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_TREE_SELECTOR, GcrTreeSelectorPrivate);
 
276
}
 
277
 
 
278
static void
 
279
gcr_tree_selector_dispose (GObject *obj)
 
280
{
 
281
        GcrTreeSelector *self = GCR_TREE_SELECTOR (obj);
 
282
 
 
283
        if (self->pv->model)
 
284
                g_object_unref (self->pv->model);
 
285
        self->pv->model = NULL;
 
286
 
 
287
        if (self->pv->collection)
 
288
                g_object_unref (self->pv->collection);
 
289
        self->pv->collection = NULL;
 
290
 
 
291
        if (self->pv->sort)
 
292
                g_object_unref (self->pv->sort);
 
293
        self->pv->sort = NULL;
 
294
 
 
295
        G_OBJECT_CLASS (gcr_tree_selector_parent_class)->dispose (obj);
 
296
}
 
297
 
 
298
static void
 
299
gcr_tree_selector_finalize (GObject *obj)
 
300
{
 
301
        GcrTreeSelector *self = GCR_TREE_SELECTOR (obj);
 
302
 
 
303
        g_assert (!self->pv->collection);
 
304
        g_assert (!self->pv->model);
 
305
 
 
306
        G_OBJECT_CLASS (gcr_tree_selector_parent_class)->finalize (obj);
 
307
}
 
308
 
 
309
static void
 
310
gcr_tree_selector_set_property (GObject *obj, guint prop_id, const GValue *value,
 
311
                                GParamSpec *pspec)
 
312
{
 
313
        GcrTreeSelector *self = GCR_TREE_SELECTOR (obj);
 
314
        switch (prop_id) {
 
315
        case PROP_COLLECTION:
 
316
                g_return_if_fail (!self->pv->collection);
 
317
                self->pv->collection = g_value_dup_object (value);
 
318
                g_return_if_fail (self->pv->collection);
 
319
                break;
 
320
        case PROP_COLUMNS:
 
321
                g_return_if_fail (!self->pv->columns);
 
322
                self->pv->columns = g_value_get_pointer (value);
 
323
                g_return_if_fail (self->pv->columns);
 
324
                break;
 
325
        default:
 
326
                G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
 
327
                break;
 
328
        }
 
329
}
 
330
 
 
331
static void
 
332
gcr_tree_selector_get_property (GObject *obj, guint prop_id, GValue *value,
 
333
                                GParamSpec *pspec)
 
334
{
 
335
        GcrTreeSelector *self = GCR_TREE_SELECTOR (obj);
 
336
 
 
337
        switch (prop_id) {
 
338
        case PROP_COLLECTION:
 
339
                g_value_set_object (value, gcr_tree_selector_get_collection (self));
 
340
                break;
 
341
        case PROP_COLUMNS:
 
342
                g_value_set_pointer (value, (gpointer)gcr_tree_selector_get_columns (self));
 
343
                break;
 
344
        default:
 
345
                G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
 
346
                break;
 
347
        }
 
348
}
 
349
 
 
350
static void
 
351
gcr_tree_selector_class_init (GcrTreeSelectorClass *klass)
 
352
{
 
353
        GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 
354
 
 
355
        gobject_class->constructor = gcr_tree_selector_constructor;
 
356
        gobject_class->dispose = gcr_tree_selector_dispose;
 
357
        gobject_class->finalize = gcr_tree_selector_finalize;
 
358
        gobject_class->set_property = gcr_tree_selector_set_property;
 
359
        gobject_class->get_property = gcr_tree_selector_get_property;
 
360
 
 
361
        g_type_class_add_private (gobject_class, sizeof (GcrTreeSelectorPrivate));
 
362
 
 
363
        /**
 
364
         * GcrTreeSelector:collection:
 
365
         *
 
366
         * The collection which contains the objects to display in the selector.
 
367
         */
 
368
        g_object_class_install_property (gobject_class, PROP_COLLECTION,
 
369
                   g_param_spec_object ("collection", "Collection", "Collection to select from",
 
370
                                        GCR_TYPE_COLLECTION, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
371
 
 
372
        /**
 
373
         * GcrTreeSelector:columns:
 
374
         *
 
375
         * The columns to use to display the objects.
 
376
         */
 
377
        g_object_class_install_property (gobject_class, PROP_COLUMNS,
 
378
                   g_param_spec_pointer ("columns", "Columns", "Columns to display in selector",
 
379
                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
380
 
 
381
        _gcr_initialize ();
 
382
}
 
383
 
 
384
/* -----------------------------------------------------------------------------
 
385
 * PUBLIC
 
386
 */
 
387
 
 
388
/**
 
389
 * gcr_tree_selector_new:
 
390
 * @collection: The collection that contains the objects to display
 
391
 * @columns: The columns to use to display the objects
 
392
 *
 
393
 * Create a new #GcrTreeSelector.
 
394
 *
 
395
 * Returns: A newly allocated selector, which should be released with
 
396
 *     g_object_unref().
 
397
 */
 
398
GcrTreeSelector*
 
399
gcr_tree_selector_new (GcrCollection *collection, const GcrColumn *columns)
 
400
{
 
401
        return g_object_new (GCR_TYPE_TREE_SELECTOR,
 
402
                             "collection", collection,
 
403
                             "columns", columns,
 
404
                             NULL);
 
405
}
 
406
 
 
407
/**
 
408
 * gcr_tree_selector_get_collection:
 
409
 * @self: The selector
 
410
 *
 
411
 * Get the collection that this selector is displaying objects from.
 
412
 *
 
413
 * Returns: The collection, owned by the selector.
 
414
 */
 
415
GcrCollection*
 
416
gcr_tree_selector_get_collection (GcrTreeSelector *self)
 
417
{
 
418
        g_return_val_if_fail (GCR_IS_TREE_SELECTOR (self), NULL);
 
419
        return self->pv->collection;
 
420
}
 
421
 
 
422
/**
 
423
 * gcr_tree_selector_get_columns:
 
424
 * @self: The selector
 
425
 *
 
426
 * Get the columns displayed in a selector in multiple mode.
 
427
 *
 
428
 * Returns: The columns, owned by the selector.
 
429
 */
 
430
const GcrColumn*
 
431
gcr_tree_selector_get_columns (GcrTreeSelector *self)
 
432
{
 
433
        g_return_val_if_fail (GCR_IS_TREE_SELECTOR (self), NULL);
 
434
        return self->pv->columns;
 
435
}
 
436
 
 
437
/**
 
438
 * gcr_tree_selector_get_selected:
 
439
 * @self: The selector
 
440
 *
 
441
 * Get a list of selected objects.
 
442
 *
 
443
 * Returns: The list of selected objects, to be released with g_list_free().
 
444
 */
 
445
GList*
 
446
gcr_tree_selector_get_selected (GcrTreeSelector *self)
 
447
{
 
448
        g_return_val_if_fail (GCR_IS_TREE_SELECTOR (self), NULL);
 
449
        return gcr_collection_model_get_selected_objects (self->pv->model);
 
450
}
 
451
 
 
452
/**
 
453
 * gcr_tree_selector_set_selected:
 
454
 * @self: The selector
 
455
 * @selected: The list of objects to select.
 
456
 *
 
457
 * Select certain objects in the selector.
 
458
 */
 
459
void
 
460
gcr_tree_selector_set_selected (GcrTreeSelector *self, GList *selected)
 
461
{
 
462
        g_return_if_fail (GCR_IS_TREE_SELECTOR (self));
 
463
        gcr_collection_model_set_selected_objects (self->pv->model, selected);
 
464
}