1 /*
2  * Seahorse
3  *
4  * Copyright (C) 2008 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, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "config.h"
21 
22 #include "seahorse-object.h"
23 
24 #include "seahorse-context.h"
25 #include "seahorse-source.h"
26 
27 #include "string.h"
28 
29 #include <glib/gi18n.h>
30 
31 /**
32  * _SeahorseObjectProps:
33  * @PROP_0:
34  * @PROP_CONTEXT:
35  * @PROP_SOURCE:
36  * @PROP_PREFERRED:
37  * @PROP_PARENT:
38  * @PROP_ID:
39  * @PROP_TAG:
40  * @PROP_LABEL:
41  * @PROP_MARKUP:
42  * @PROP_NICKNAME:
43  * @PROP_DESCRIPTION:
44  * @PROP_ICON:
45  * @PROP_IDENTIFIER:
46  * @PROP_LOCATION:
47  * @PROP_USAGE:
48  * @PROP_FLAGS:
49  */
50 enum _SeahorseObjectProps {
51 	PROP_0,
52 	PROP_CONTEXT,
53 	PROP_SOURCE,
54 	PROP_PREFERRED,
55 	PROP_PARENT,
56 	PROP_ID,
57 	PROP_TAG,
58 	PROP_LABEL,
59 	PROP_MARKUP,
60 	PROP_NICKNAME,
61 	PROP_DESCRIPTION,
62 	PROP_ICON,
63 	PROP_IDENTIFIER,
64 	PROP_LOCATION,
65 	PROP_USAGE,
66 	PROP_FLAGS
67 };
68 
69 /**
70  * _SeahorseObjectPrivate:
71  * @id: the id of the object
72  * @tag: DBUS: "ktype"
73  * @tag_explicit: If TRUE the tag will not be set automatically
74  * @source: Where did the object come from ?
75  * @context:
76  * @preferred: Points to the object to prefer over this one
77  * @parent: the object's parent
78  * @children: a list of children the object has
79  * @label: DBUS: "display-name"
80  * @markup: Markup text
81  * @markup_explicit: If TRUE the markup will not be set automatically
82  * @nickname: DBUS: "simple-name"
83  * @nickname_explicit: If TRUE the nickname will not be set automatically
84  * @description:  Description text DBUS: "key-desc"
85  * @description_explicit: If TRUE the description will not be set automatically
86  * @icon: DBUS: "stock-id"
87  * @identifier: DBUS: "key-id", "display-id", "raw-id"
88  * @identifier_explicit:
89  * @location: describes the loaction of the object (local, remte, invalid...)
90  * @usage: DBUS: "etype"
91  * @flags:
92  * @realizing: set while the object is realizing
93  * @realized: set as soon as the object is realized
94  */
95 struct _SeahorseObjectPrivate {
96 	GQuark id;
97 	GQuark tag;
98 	gboolean tag_explicit;
99 
100 	SeahorseSource *source;
101 	SeahorseContext *context;
102 	SeahorseObject *preferred;
103 	SeahorseObject *parent;
104 	GList *children;
105 
106     gchar *label;
107     gchar *markup;
108     gboolean markup_explicit;
109     gchar *nickname;
110     gboolean nickname_explicit;
111     gchar *description;
112     gboolean description_explicit;
113     gchar *icon;
114     gchar *identifier;
115     gboolean identifier_explicit;
116 
117     SeahorseLocation location;
118     SeahorseUsage usage;
119     guint flags;
120 
121 	gboolean realized;
122 	gboolean realizing;
123 };
124 
125 G_DEFINE_TYPE (SeahorseObject, seahorse_object, G_TYPE_OBJECT);
126 
127 /* -----------------------------------------------------------------------------
128  * INTERNAL
129  */
130 
131 /**
132  * register_child:
133  * @self: The parent
134  * @child: The new child
135  *
136  *
137  * Sets @child as a child of @self
138  */
139 static void
register_child(SeahorseObject * self,SeahorseObject * child)140 register_child (SeahorseObject* self, SeahorseObject* child)
141 {
142 	g_assert (SEAHORSE_IS_OBJECT (self));
143 	g_assert (SEAHORSE_IS_OBJECT (child));
144 	g_assert (self != child);
145 	g_assert (child->pv->parent == NULL);
146 
147 	child->pv->parent = self;
148 	self->pv->children = g_list_append (self->pv->children, child);
149 }
150 
151 /**
152  * unregister_child:
153  * @self: The parent
154  * @child: child to remove
155  *
156  *
157  * removes @child from the children list in @self
158  */
159 static void
unregister_child(SeahorseObject * self,SeahorseObject * child)160 unregister_child (SeahorseObject* self, SeahorseObject* child)
161 {
162 	g_assert (SEAHORSE_IS_OBJECT (self));
163 	g_assert (SEAHORSE_IS_OBJECT (child));
164 	g_assert (self != child);
165 	g_assert (child->pv->parent == self);
166 
167 	child->pv->parent = NULL;
168 	self->pv->children = g_list_remove (self->pv->children, child);
169 }
170 
171 /**
172  * set_string_storage:
173  * @value: The value to store
174  * @storage: The datastore to write the value to
175  *
176  * When storing, new memory will be allocated and the value copied
177  *
178  * Returns: TRUE if the value has been set new, FALSE else
179  */
180 static gboolean
set_string_storage(const gchar * value,gchar ** storage)181 set_string_storage (const gchar *value, gchar **storage)
182 {
183 	g_assert (storage);
184 
185 	if (value == NULL)
186 		value = "";
187 
188 	if (!value || !*storage || !g_str_equal (value, *storage)) {
189 		g_free (*storage);
190 		*storage = g_strdup (value);
191 		return TRUE;
192 	}
193 
194 	return FALSE;
195 }
196 
197 /**
198  * take_string_storage:
199  * @value: The value to store
200  * @storage: The datastore to write the value to
201  *
202  * When storing, the pointer to value is used. No new memory will be allocated
203  *
204  * Returns: TRUE if the value has been set new, FALSE else
205  */
206 static gboolean
take_string_storage(gchar * value,gchar ** storage)207 take_string_storage (gchar *value, gchar **storage)
208 {
209 	g_assert (storage);
210 
211 	if (value == NULL)
212 		value = g_strdup ("");
213 
214 	if (!value || !*storage || !g_str_equal (value, *storage)) {
215 		g_free (*storage);
216 		*storage = value;
217 		return TRUE;
218 	}
219 
220 	g_free (value);
221 	return FALSE;
222 }
223 
224 /**
225  * recalculate_id:
226  * @self: object to calculate for
227  *
228  * recalculates tag and identifier from id
229  *
230  */
231 static void
recalculate_id(SeahorseObject * self)232 recalculate_id (SeahorseObject *self)
233 {
234 	const gchar *str;
235 	const gchar *at;
236 	GQuark tag;
237 	gchar *result;
238 	gsize len;
239 
240 	/* No id, clear any tag and auto generated identifer */
241 	if (!self->pv->id) {
242 		if (!self->pv->tag_explicit) {
243 			self->pv->tag = 0;
244 			g_object_notify (G_OBJECT (self), "tag");
245 		}
246 
247 		if (!self->pv->identifier_explicit) {
248 			if (set_string_storage ("", &self->pv->identifier))
249 				g_object_notify (G_OBJECT (self), "identifier");
250 		}
251 
252 	/* Have hande, configure tag and auto generated identifer */
253 	} else {
254 		str = g_quark_to_string (self->pv->id);
255 		len = strlen (str);
256 		at = strchr (str, ':');
257 
258 		if (!self->pv->tag_explicit) {
259 			result = g_strndup (str, at ? at - str : len);
260 			tag = g_quark_from_string (result);
261 			g_free (result);
262 
263 			if (tag != self->pv->tag) {
264 				self->pv->tag = tag;
265 				g_object_notify (G_OBJECT (self), "tag");
266 			}
267 		}
268 
269 		if (!self->pv->identifier_explicit) {
270 			if (set_string_storage (at ? at + 1 : "", &self->pv->identifier))
271 				g_object_notify (G_OBJECT (self), "identifier");
272 		}
273 	}
274 }
275 
276 /**
277  * recalculate_label:
278  * @self: object to recalculate label for
279  *
280  * Recalculates nickname and markup from the label
281  *
282  */
283 static void
recalculate_label(SeahorseObject * self)284 recalculate_label (SeahorseObject *self)
285 {
286 	if (!self->pv->markup_explicit) {
287 		if (take_string_storage (g_markup_escape_text (self->pv->label ? self->pv->label : "", -1),
288 		                         &self->pv->markup))
289 			g_object_notify (G_OBJECT (self), "markup");
290 	}
291 
292 	if (!self->pv->nickname_explicit) {
293 		if (set_string_storage (self->pv->label, &self->pv->nickname))
294 			g_object_notify (G_OBJECT (self), "nickname");
295 	}
296 }
297 
298 /**
299  * recalculate_usage:
300  * @self: The #SeahorseObject to recalculate the usage decription for
301  *
302  * Basing on the usage identifiere this function will calculate a usage
303  * description and store it in the object.
304  *
305  */
306 static void
recalculate_usage(SeahorseObject * self)307 recalculate_usage (SeahorseObject *self)
308 {
309 	const gchar *desc;
310 
311 	if (!self->pv->description_explicit) {
312 
313 		switch (self->pv->usage) {
314 		case SEAHORSE_USAGE_SYMMETRIC_KEY:
315 			desc = _("Symmetric Key");
316 			break;
317 		case SEAHORSE_USAGE_PUBLIC_KEY:
318 			desc = _("Public Key");
319 			break;
320 		case SEAHORSE_USAGE_PRIVATE_KEY:
321 			desc = _("Private Key");
322 			break;
323 		case SEAHORSE_USAGE_CREDENTIALS:
324 			desc = _("Credentials");
325 			break;
326 		case SEAHORSE_USAGE_IDENTITY:
327 		    /*
328 		     * Translators: "This object is a means of storing items such as
329 		     * name, email address, etc. that make up one's digital identity.
330 		     */
331 			desc = _("Identity");
332 			break;
333 		default:
334 			desc = "";
335 			break;
336 		}
337 
338 		if (set_string_storage (desc, &self->pv->description))
339 			g_object_notify (G_OBJECT (self), "description");
340 	}
341 }
342 
343 
344 /* -----------------------------------------------------------------------------
345  * OBJECT
346  */
347 
348 /**
349  * seahorse_object_init:
350  * @self: The object to initialise
351  *
352  * Initialises the object with default data
353  *
354  */
355 static void
seahorse_object_init(SeahorseObject * self)356 seahorse_object_init (SeahorseObject *self)
357 {
358 	self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, SEAHORSE_TYPE_OBJECT,
359 	                                        SeahorseObjectPrivate);
360 	self->pv->label = g_strdup ("");
361 	self->pv->markup = g_strdup ("");
362 	self->pv->description = g_strdup ("");
363 	self->pv->icon = g_strdup ("gtk-missing-image");
364 	self->pv->identifier = g_strdup ("");
365 	self->pv->location = SEAHORSE_LOCATION_INVALID;
366 	self->pv->usage = SEAHORSE_USAGE_NONE;
367 }
368 
369 
370 /**
371  * seahorse_object_dispose:
372  * @obj: A #SeahorseObject to dispose
373  *
374  * Before this object is disposed, all it's children get new parents
375  *
376  */
377 static void
seahorse_object_dispose(GObject * obj)378 seahorse_object_dispose (GObject *obj)
379 {
380 	SeahorseObject *self = SEAHORSE_OBJECT (obj);
381 	SeahorseObject *parent;
382 	GList *l, *children;
383 
384 	if (self->pv->context != NULL) {
385 		seahorse_context_remove_object (self->pv->context, self);
386 		g_assert (self->pv->context == NULL);
387 	}
388 
389 	if (self->pv->source != NULL) {
390 		g_object_remove_weak_pointer (G_OBJECT (self->pv->source), (gpointer*)&self->pv->source);
391 		self->pv->source = NULL;
392 	}
393 
394 	if (self->pv->preferred != NULL) {
395 		g_object_remove_weak_pointer (G_OBJECT (self->pv->source), (gpointer*)&self->pv->preferred);
396 		self->pv->preferred = NULL;
397 	}
398 
399 	/*
400 	 * When an object is destroyed, we reparent all
401 	 * children to this objects parent. If no parent
402 	 * of this object, all children become root objects.
403 	 */
404 
405 	parent = self->pv->parent;
406 	if (parent)
407 		g_object_ref (parent);
408 
409 	children = g_list_copy (self->pv->children);
410 	for (l = children; l; l = g_list_next (l)) {
411 		g_return_if_fail (SEAHORSE_IS_OBJECT (l->data));
412 		seahorse_object_set_parent (l->data, parent);
413 	}
414 	g_list_free (children);
415 
416 	if (parent)
417 		g_object_unref (parent);
418 
419 	g_assert (self->pv->children == NULL);
420 
421 	/* Now remove this object from its parent */
422 	seahorse_object_set_parent (self, NULL);
423 
424 	G_OBJECT_CLASS (seahorse_object_parent_class)->dispose (obj);
425 }
426 
427 /**
428  * seahorse_object_finalize:
429  * @obj: #SeahorseObject to finalize
430  *
431  */
432 static void
seahorse_object_finalize(GObject * obj)433 seahorse_object_finalize (GObject *obj)
434 {
435 	SeahorseObject *self = SEAHORSE_OBJECT (obj);
436 
437 	g_assert (self->pv->source == NULL);
438 	g_assert (self->pv->preferred == NULL);
439 	g_assert (self->pv->parent == NULL);
440 	g_assert (self->pv->context == NULL);
441 	g_assert (self->pv->children == NULL);
442 
443 	g_free (self->pv->label);
444 	self->pv->label = NULL;
445 
446 	g_free (self->pv->markup);
447 	self->pv->markup = NULL;
448 
449 	g_free (self->pv->nickname);
450 	self->pv->nickname = NULL;
451 
452 	g_free (self->pv->description);
453 	self->pv->description = NULL;
454 
455 	g_free (self->pv->icon);
456 	self->pv->icon = NULL;
457 
458 	g_free (self->pv->identifier);
459 	self->pv->identifier = NULL;
460 
461 	G_OBJECT_CLASS (seahorse_object_parent_class)->finalize (obj);
462 }
463 
464 
465 /**
466  * seahorse_object_get_property:
467  * @obj: The object to get the property for
468  * @prop_id: The property requested
469  * @value: out - the value as #GValue
470  * @pspec: a #GParamSpec for the warning
471  *
472  * Returns: The property of the object @obj defined by the id @prop_id in @value.
473  *
474  */
475 static void
seahorse_object_get_property(GObject * obj,guint prop_id,GValue * value,GParamSpec * pspec)476 seahorse_object_get_property (GObject *obj, guint prop_id, GValue *value,
477                            GParamSpec *pspec)
478 {
479 	SeahorseObject *self = SEAHORSE_OBJECT (obj);
480 
481 	switch (prop_id) {
482 	case PROP_CONTEXT:
483 		g_value_set_object (value, seahorse_object_get_context (self));
484 		break;
485 	case PROP_SOURCE:
486 		g_value_set_object (value, seahorse_object_get_source (self));
487 		break;
488 	case PROP_PREFERRED:
489 		g_value_set_object (value, seahorse_object_get_preferred (self));
490 		break;
491 	case PROP_PARENT:
492 		g_value_set_object (value, seahorse_object_get_parent (self));
493 		break;
494 	case PROP_ID:
495 		g_value_set_uint (value, seahorse_object_get_id (self));
496 		break;
497 	case PROP_TAG:
498 		g_value_set_uint (value, seahorse_object_get_tag (self));
499 		break;
500 	case PROP_LABEL:
501 		g_value_set_string (value, seahorse_object_get_label (self));
502 		break;
503 	case PROP_NICKNAME:
504 		g_value_set_string (value, seahorse_object_get_nickname (self));
505 		break;
506 	case PROP_MARKUP:
507 		g_value_set_string (value, seahorse_object_get_markup (self));
508 		break;
509 	case PROP_DESCRIPTION:
510 		g_value_set_string (value, seahorse_object_get_description (self));
511 		break;
512 	case PROP_ICON:
513 		g_value_set_string (value, seahorse_object_get_icon (self));
514 		break;
515 	case PROP_IDENTIFIER:
516 		g_value_set_string (value, seahorse_object_get_identifier (self));
517 		break;
518 	case PROP_LOCATION:
519 		g_value_set_enum (value, seahorse_object_get_location (self));
520 		break;
521 	case PROP_USAGE:
522 		g_value_set_enum (value, seahorse_object_get_usage (self));
523 		break;
524 	case PROP_FLAGS:
525 		g_value_set_uint (value, seahorse_object_get_flags (self));
526 		break;
527 	default:
528 		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
529 		break;
530 	}
531 }
532 
533 /**
534  * seahorse_object_set_property:
535  * @obj: Object to set the property in
536  * @prop_id: the property to set
537  * @value: the value to set
538  * @pspec: To be used for warnings. #GParamSpec
539  *
540  * Sets a property in this object
541  *
542  */
543 static void
seahorse_object_set_property(GObject * obj,guint prop_id,const GValue * value,GParamSpec * pspec)544 seahorse_object_set_property (GObject *obj, guint prop_id, const GValue *value,
545                               GParamSpec *pspec)
546 {
547 	SeahorseObject *self = SEAHORSE_OBJECT (obj);
548 	SeahorseLocation loc;
549 	SeahorseUsage usage;
550 	guint flags;
551 	GQuark quark;
552 
553 	switch (prop_id) {
554 	case PROP_CONTEXT:
555 		if (self->pv->context)
556 			g_object_remove_weak_pointer (G_OBJECT (self->pv->context), (gpointer*)&self->pv->context);
557 		self->pv->context = SEAHORSE_CONTEXT (g_value_get_object (value));
558 		if (self->pv->context != NULL)
559 			g_object_add_weak_pointer (G_OBJECT (self->pv->context), (gpointer*)&self->pv->context);
560 		g_object_notify (G_OBJECT (self), "context");
561 		break;
562 	case PROP_SOURCE:
563 		seahorse_object_set_source (self, SEAHORSE_SOURCE (g_value_get_object (value)));
564 		break;
565 	case PROP_PREFERRED:
566 		seahorse_object_set_preferred (self, SEAHORSE_OBJECT (g_value_get_object (value)));
567 		break;
568 	case PROP_PARENT:
569 		seahorse_object_set_parent (self, SEAHORSE_OBJECT (g_value_get_object (value)));
570 		break;
571 	case PROP_ID:
572 		quark = g_value_get_uint (value);
573 		if (quark != self->pv->id) {
574 			self->pv->id = quark;
575 			g_object_freeze_notify (obj);
576 			g_object_notify (obj, "id");
577 			recalculate_id (self);
578 			g_object_thaw_notify (obj);
579 		}
580 		break;
581 	case PROP_TAG:
582 		quark = g_value_get_uint (value);
583 		if (quark != self->pv->tag) {
584 			self->pv->tag = quark;
585 			self->pv->tag_explicit = TRUE;
586 			g_object_notify (obj, "tag");
587 		}
588 		break;
589 	case PROP_LABEL:
590 		if (set_string_storage (g_value_get_string (value), &self->pv->label)) {
591 			g_object_freeze_notify (obj);
592 			g_object_notify (obj, "label");
593 			recalculate_label (self);
594 			g_object_thaw_notify (obj);
595 		}
596 		break;
597 	case PROP_NICKNAME:
598 		if (set_string_storage (g_value_get_string (value), &self->pv->nickname)) {
599 			self->pv->nickname_explicit = TRUE;
600 			g_object_notify (obj, "nickname");
601 		}
602 		break;
603 	case PROP_MARKUP:
604 		if (set_string_storage (g_value_get_string (value), &self->pv->markup)) {
605 			self->pv->markup_explicit = TRUE;
606 			g_object_notify (obj, "markup");
607 		}
608 		break;
609 	case PROP_DESCRIPTION:
610 		if (set_string_storage (g_value_get_string (value), &self->pv->description)) {
611 			self->pv->description_explicit = TRUE;
612 			g_object_notify (obj, "description");
613 		}
614 		break;
615 	case PROP_ICON:
616 		if (set_string_storage (g_value_get_string (value), &self->pv->icon))
617 			g_object_notify (obj, "icon");
618 		break;
619 	case PROP_IDENTIFIER:
620 		if (set_string_storage (g_value_get_string (value), &self->pv->identifier)) {
621 			self->pv->identifier_explicit = TRUE;
622 			g_object_notify (obj, "identifier");
623 		}
624 		break;
625 	case PROP_LOCATION:
626 		loc = g_value_get_enum (value);
627 		if (loc != self->pv->location) {
628 			self->pv->location = loc;
629 			g_object_notify (obj, "location");
630 		}
631 		break;
632 	case PROP_USAGE:
633 		usage = g_value_get_enum (value);
634 		if (usage != self->pv->usage) {
635 			self->pv->usage = usage;
636 			g_object_freeze_notify (obj);
637 			g_object_notify (obj, "usage");
638 			recalculate_usage (self);
639 			g_object_thaw_notify (obj);
640 		}
641 		break;
642 	case PROP_FLAGS:
643 		flags = g_value_get_uint (value);
644 		flags &= ~SEAHORSE_FLAG_DELETABLE;
645 		if (flags != self->pv->flags) {
646 			self->pv->flags = flags;
647 			g_object_notify (obj, "flags");
648 		}
649 		break;
650 	default:
651 		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
652 		break;
653 	}
654 }
655 
656 /**
657  * seahorse_object_real_realize:
658  * @self: The object
659  *
660  * To be overridden
661  *
662  */
663 static void
seahorse_object_real_realize(SeahorseObject * self)664 seahorse_object_real_realize (SeahorseObject *self)
665 {
666 	/*
667 	 * We do nothing by default. It's up to the derived class
668 	 * to override this and realize themselves when called.
669 	 */
670 
671 	self->pv->realized = TRUE;
672 }
673 
674 /**
675  * seahorse_object_real_refresh:
676  * @self: The object
677  *
678  * To be overridden
679  *
680  */
681 static void
seahorse_object_real_refresh(SeahorseObject * self)682 seahorse_object_real_refresh (SeahorseObject *self)
683 {
684 	/*
685 	 * We do nothing by default. It's up to the derived class
686 	 * to override this and refresh themselves when called.
687 	 */
688 }
689 
690 /**
691  * seahorse_object_class_init:
692  * @klass: the object class
693  *
694  * Initialises the object class
695  *
696  */
697 static void
seahorse_object_class_init(SeahorseObjectClass * klass)698 seahorse_object_class_init (SeahorseObjectClass *klass)
699 {
700 	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
701 
702 	seahorse_object_parent_class = g_type_class_peek_parent (klass);
703 	g_type_class_add_private (klass, sizeof (SeahorseObjectPrivate));
704 
705 	gobject_class->dispose = seahorse_object_dispose;
706 	gobject_class->finalize = seahorse_object_finalize;
707 	gobject_class->set_property = seahorse_object_set_property;
708 	gobject_class->get_property = seahorse_object_get_property;
709 
710 	klass->realize = seahorse_object_real_realize;
711 	klass->refresh = seahorse_object_real_refresh;
712 
713 	g_object_class_install_property (gobject_class, PROP_SOURCE,
714 	           g_param_spec_object ("source", "Object Source", "Source the Object came from",
715 	                                SEAHORSE_TYPE_SOURCE, G_PARAM_READWRITE));
716 
717 	g_object_class_install_property (gobject_class, PROP_CONTEXT,
718 	           g_param_spec_object ("context", "Context for object", "Object that this context belongs to",
719 	                                SEAHORSE_TYPE_CONTEXT, G_PARAM_READWRITE));
720 
721 	g_object_class_install_property (gobject_class, PROP_PREFERRED,
722 	           g_param_spec_object ("preferred", "Preferred Object", "An object to prefer over this one",
723 	                                SEAHORSE_TYPE_OBJECT, G_PARAM_READWRITE));
724 
725 	g_object_class_install_property (gobject_class, PROP_PREFERRED,
726 	           g_param_spec_object ("parent", "Parent Object", "This object's parent in the tree.",
727 	                                SEAHORSE_TYPE_OBJECT, G_PARAM_READWRITE));
728 
729 	g_object_class_install_property (gobject_class, PROP_ID,
730 	           g_param_spec_uint ("id", "Object ID", "This object's ID.",
731 	                              0, G_MAXUINT, 0, G_PARAM_READWRITE));
732 
733 	g_object_class_install_property (gobject_class, PROP_TAG,
734 	           g_param_spec_uint ("tag", "Object Type Tag", "This object's type tag.",
735 	                              0, G_MAXUINT, 0, G_PARAM_READWRITE));
736 
737 	g_object_class_install_property (gobject_class, PROP_LABEL,
738 	           g_param_spec_string ("label", "Object Display Label", "This object's displayable label.",
739 	                                "", G_PARAM_READWRITE));
740 
741 	g_object_class_install_property (gobject_class, PROP_NICKNAME,
742 	           g_param_spec_string ("nickname", "Object Short Name", "This object's short name.",
743 	                                "", G_PARAM_READWRITE));
744 
745 	g_object_class_install_property (gobject_class, PROP_ICON,
746 	           g_param_spec_string ("icon", "Object Icon", "Stock ID for object.",
747 	                                "", G_PARAM_READWRITE));
748 
749 	g_object_class_install_property (gobject_class, PROP_MARKUP,
750 	           g_param_spec_string ("markup", "Object Display Markup", "This object's displayable markup.",
751 	                                "", G_PARAM_READWRITE));
752 
753 	g_object_class_install_property (gobject_class, PROP_DESCRIPTION,
754 	           g_param_spec_string ("description", "Object Description", "Description of the type of object",
755 	                                "", G_PARAM_READWRITE));
756 
757 	g_object_class_install_property (gobject_class, PROP_IDENTIFIER,
758 	           g_param_spec_string ("identifier", "Object Identifier", "Displayable ID for the object.",
759 	                                "", G_PARAM_READWRITE));
760 
761 	g_object_class_install_property (gobject_class, PROP_LOCATION,
762 	           g_param_spec_enum ("location", "Object Location", "Where the object is located.",
763 	                              SEAHORSE_TYPE_LOCATION, SEAHORSE_LOCATION_INVALID, G_PARAM_READWRITE));
764 
765 	g_object_class_install_property (gobject_class, PROP_USAGE,
766 	           g_param_spec_enum ("usage", "Object Usage", "How this object is used.",
767 	                              SEAHORSE_TYPE_USAGE, SEAHORSE_USAGE_NONE, G_PARAM_READWRITE));
768 
769 	g_object_class_install_property (gobject_class, PROP_FLAGS,
770 	           g_param_spec_uint ("flags", "Object Flags", "This object's flags.",
771 	                              0, G_MAXUINT, 0, G_PARAM_READWRITE));
772 }
773 
774 /* -----------------------------------------------------------------------------
775  * PUBLIC
776  */
777 
778 /**
779  * seahorse_object_get_id:
780  * @self: Object
781  *
782  * Returns: the id of the object @self
783  */
784 GQuark
seahorse_object_get_id(SeahorseObject * self)785 seahorse_object_get_id (SeahorseObject *self)
786 {
787 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), 0);
788 	return self->pv->id;
789 }
790 
791 /**
792  * seahorse_object_get_tag:
793  * @self: Object
794  *
795  * Returns: the tag of the object @self
796  */
797 GQuark
seahorse_object_get_tag(SeahorseObject * self)798 seahorse_object_get_tag (SeahorseObject *self)
799 {
800 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), 0);
801 	if (!self->pv->tag)
802 		seahorse_object_realize (self);
803 	return self->pv->tag;
804 }
805 
806 /**
807  * seahorse_object_get_source:
808  * @self: Object
809  *
810  * Returns: the source of the object @self
811  */
812 SeahorseSource*
seahorse_object_get_source(SeahorseObject * self)813 seahorse_object_get_source (SeahorseObject *self)
814 {
815 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), NULL);
816 	return self->pv->source;
817 }
818 
819 
820 /**
821  * seahorse_object_set_source:
822  * @self: The object to set a new source for
823  * @value: The source to set
824  *
825  * sets the source for the object
826  */
827 void
seahorse_object_set_source(SeahorseObject * self,SeahorseSource * value)828 seahorse_object_set_source (SeahorseObject *self, SeahorseSource *value)
829 {
830 	g_return_if_fail (SEAHORSE_IS_OBJECT (self));
831 
832 	if (value == self->pv->source)
833 		return;
834 
835 	if (self->pv->source)
836 		g_object_remove_weak_pointer (G_OBJECT (self->pv->source), (gpointer*)&self->pv->source);
837 
838 	self->pv->source = value;
839 	if (self->pv->source != NULL)
840 		g_object_add_weak_pointer (G_OBJECT (self->pv->source), (gpointer*)&self->pv->source);
841 
842 	g_object_notify (G_OBJECT (self), "source");
843 }
844 
845 /**
846  * seahorse_object_get_context:
847  * @self: Object
848  *
849  * Returns: the context of the object @self
850  */
851 SeahorseContext*
seahorse_object_get_context(SeahorseObject * self)852 seahorse_object_get_context (SeahorseObject *self)
853 {
854 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), NULL);
855 	return self->pv->context;
856 }
857 
858 /**
859  * seahorse_object_get_preferred:
860  * @self: Object
861  *
862  * Returns: the preferred of the object @self
863  */
864 SeahorseObject*
seahorse_object_get_preferred(SeahorseObject * self)865 seahorse_object_get_preferred (SeahorseObject *self)
866 {
867 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), NULL);
868 	return self->pv->preferred;
869 }
870 
871 /**
872  * seahorse_object_set_preferred:
873  * @self: the object to set the preferred object for
874  * @value: the preferred object
875  *
876  *
877  */
878 void
seahorse_object_set_preferred(SeahorseObject * self,SeahorseObject * value)879 seahorse_object_set_preferred (SeahorseObject *self, SeahorseObject *value)
880 {
881 	g_return_if_fail (SEAHORSE_IS_OBJECT (self));
882 
883 	if (self->pv->preferred == value)
884 		return;
885 
886 	if (self->pv->preferred)
887 		g_object_remove_weak_pointer (G_OBJECT (self->pv->preferred), (gpointer*)&self->pv->preferred);
888 
889 	self->pv->preferred = value;
890 	if (self->pv->preferred != NULL)
891 		g_object_add_weak_pointer (G_OBJECT (self->pv->preferred), (gpointer*)&self->pv->preferred);
892 
893 	g_object_notify (G_OBJECT (self), "preferred");
894 }
895 
896 /**
897  * seahorse_object_get_parent:
898  * @self: Object
899  *
900  * Returns: the parent of the object @self
901  */
902 SeahorseObject*
seahorse_object_get_parent(SeahorseObject * self)903 seahorse_object_get_parent (SeahorseObject *self)
904 {
905 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), NULL);
906 	return self->pv->parent;
907 }
908 
909 /**
910  * seahorse_object_set_parent:
911  * @self: the child
912  * @value: the parent
913  *
914  * register @value as the parent of @self:
915  */
916 void
seahorse_object_set_parent(SeahorseObject * self,SeahorseObject * value)917 seahorse_object_set_parent (SeahorseObject *self, SeahorseObject *value)
918 {
919 	g_return_if_fail (SEAHORSE_IS_OBJECT (self));
920 	g_return_if_fail (self->pv->parent != self);
921 	g_return_if_fail (value != self);
922 
923 	if (value == self->pv->parent)
924 		return;
925 
926 	/* Set the new parent/child relationship */
927 	if (self->pv->parent != NULL)
928 		unregister_child (self->pv->parent, self);
929 
930 	if (value != NULL)
931 		register_child (value, self);
932 
933 	g_assert (self->pv->parent == value);
934 
935 	g_object_notify (G_OBJECT (self), "parent");
936 }
937 
938 /**
939  * seahorse_object_get_children:
940  * @self: Object
941  *
942  * Returns: the children of the object @self
943  */
944 GList*
seahorse_object_get_children(SeahorseObject * self)945 seahorse_object_get_children (SeahorseObject *self)
946 {
947 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), NULL);
948 	seahorse_object_realize (self);
949 	return g_list_copy (self->pv->children);
950 }
951 
952 /**
953  * seahorse_object_get_nth_child:
954  * @self: Object
955  * @index: the number of the child to return
956  *
957  * Returns: the child number @index
958  */
959 SeahorseObject*
seahorse_object_get_nth_child(SeahorseObject * self,guint index)960 seahorse_object_get_nth_child (SeahorseObject *self, guint index)
961 {
962 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), NULL);
963 	return SEAHORSE_OBJECT (g_list_nth_data (self->pv->children, index));
964 }
965 
966 /**
967  * seahorse_object_get_label:
968  * @self: Object
969  *
970  * Returns: the label of the object @self
971  */
972 const gchar*
seahorse_object_get_label(SeahorseObject * self)973 seahorse_object_get_label (SeahorseObject *self)
974 {
975 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), NULL);
976 	seahorse_object_realize (self);
977 	return self->pv->label;
978 }
979 
980 /**
981  * seahorse_object_get_markup:
982  * @self: Object
983  *
984  * Returns: the markup of the object @self
985  */
986 const gchar*
seahorse_object_get_markup(SeahorseObject * self)987 seahorse_object_get_markup (SeahorseObject *self)
988 {
989 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), NULL);
990 	seahorse_object_realize (self);
991 	return self->pv->markup;
992 }
993 
994 /**
995  * seahorse_object_get_nickname:
996  * @self: Object
997  *
998  * Returns: the nickname of the object @self
999  */
1000 const gchar*
seahorse_object_get_nickname(SeahorseObject * self)1001 seahorse_object_get_nickname (SeahorseObject *self)
1002 {
1003 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), NULL);
1004 	seahorse_object_realize (self);
1005 	return self->pv->nickname;
1006 }
1007 
1008 /**
1009  * seahorse_object_get_description:
1010  * @self: Object
1011  *
1012  * Returns: the description of the object @self
1013  */
1014 const gchar*
seahorse_object_get_description(SeahorseObject * self)1015 seahorse_object_get_description (SeahorseObject *self)
1016 {
1017 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), NULL);
1018 	seahorse_object_realize (self);
1019 	return self->pv->description;
1020 }
1021 
1022 /**
1023  * seahorse_object_get_icon:
1024  * @self: Object
1025  *
1026  * Returns: the icon of the object @self
1027  */
1028 const gchar*
seahorse_object_get_icon(SeahorseObject * self)1029 seahorse_object_get_icon (SeahorseObject *self)
1030 {
1031 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), NULL);
1032 	seahorse_object_realize (self);
1033 	return self->pv->icon;
1034 }
1035 
1036 /**
1037  * seahorse_object_get_identifier:
1038  * @self: Object
1039  *
1040  * Returns: the identifier of the object @self
1041  */
1042 const gchar*
seahorse_object_get_identifier(SeahorseObject * self)1043 seahorse_object_get_identifier (SeahorseObject *self)
1044 {
1045 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), NULL);
1046 	seahorse_object_realize (self);
1047 	return self->pv->identifier;
1048 }
1049 
1050 /**
1051  * seahorse_object_get_location:
1052  * @self: Object
1053  *
1054  * Returns: the location of the object @self
1055  */
1056 SeahorseLocation
seahorse_object_get_location(SeahorseObject * self)1057 seahorse_object_get_location (SeahorseObject *self)
1058 {
1059 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), SEAHORSE_LOCATION_INVALID);
1060 	if (self->pv->location == SEAHORSE_LOCATION_INVALID)
1061 		seahorse_object_realize (self);
1062 	return self->pv->location;
1063 }
1064 
1065 /**
1066  * seahorse_object_get_usage:
1067  * @self: Object
1068  *
1069  * Returns: the usage of the object @self
1070  */
1071 SeahorseUsage
seahorse_object_get_usage(SeahorseObject * self)1072 seahorse_object_get_usage (SeahorseObject *self)
1073 {
1074 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), SEAHORSE_USAGE_NONE);
1075 	if (self->pv->usage == SEAHORSE_USAGE_NONE)
1076 		seahorse_object_realize (self);
1077 	return self->pv->usage;
1078 }
1079 
1080 /**
1081  * seahorse_object_get_flags:
1082  * @self: Object
1083  *
1084  * Returns: the flags of the object @self
1085  */
1086 guint
seahorse_object_get_flags(SeahorseObject * self)1087 seahorse_object_get_flags (SeahorseObject *self)
1088 {
1089 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), 0);
1090 	seahorse_object_realize (self);
1091 	return self->pv->flags;
1092 }
1093 
1094 /**
1095  * seahorse_object_lookup_property:
1096  * @self: the object to look up the property
1097  * @field: the field to lookup
1098  * @value: the returned value
1099  *
1100  * Looks up the property @field in the object @self and returns it in @value
1101  *
1102  * Returns: TRUE if a property was found
1103  */
1104 gboolean
seahorse_object_lookup_property(SeahorseObject * self,const gchar * field,GValue * value)1105 seahorse_object_lookup_property (SeahorseObject *self, const gchar *field, GValue *value)
1106 {
1107 	GParamSpec *spec;
1108 
1109 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), FALSE);
1110 	g_return_val_if_fail (field, FALSE);
1111 	g_return_val_if_fail (value, FALSE);
1112 
1113 	spec = g_object_class_find_property (G_OBJECT_GET_CLASS (self), field);
1114 	if (!spec) {
1115 		/* Some name mapping to new style names */
1116 		if (g_str_equal (field, "simple-name"))
1117 			field = "nickname";
1118 		else if (g_str_equal (field, "key-id"))
1119 			field = "identifier";
1120 		else if (g_str_equal (field, "display-name"))
1121 			field = "label";
1122 		else if (g_str_equal (field, "key-desc"))
1123 			field = "description";
1124 		else if (g_str_equal (field, "ktype"))
1125 			field = "tag";
1126 		else if (g_str_equal (field, "etype"))
1127 			field = "usage";
1128 		else if (g_str_equal (field, "display-id"))
1129 			field = "identifier";
1130 		else if (g_str_equal (field, "stock-id"))
1131 			field = "icon";
1132 		else if (g_str_equal (field, "raw-id"))
1133 			field = "identifier";
1134 		else
1135 			return FALSE;
1136 
1137 		/* Try again */
1138 		spec = g_object_class_find_property (G_OBJECT_GET_CLASS (self), field);
1139 		if (!spec)
1140 			return FALSE;
1141 	}
1142 
1143 	g_value_init (value, spec->value_type);
1144 	g_object_get_property (G_OBJECT (self), field, value);
1145 	return TRUE;
1146 }
1147 
1148 /**
1149  * seahorse_object_realize:
1150  * @self: the object to realize
1151  *
1152  *
1153  * Realizes an object. Calls the klass method
1154  */
1155 void
seahorse_object_realize(SeahorseObject * self)1156 seahorse_object_realize (SeahorseObject *self)
1157 {
1158 	SeahorseObjectClass *klass;
1159 	g_return_if_fail (SEAHORSE_IS_OBJECT (self));
1160 	if (self->pv->realized)
1161 		return;
1162 	if (self->pv->realizing)
1163 		return;
1164 	klass = SEAHORSE_OBJECT_GET_CLASS (self);
1165 	g_return_if_fail (klass->realize);
1166 	self->pv->realizing = TRUE;
1167 	(klass->realize) (self);
1168 	self->pv->realizing = FALSE;
1169 }
1170 
1171 /**
1172  * seahorse_object_refresh:
1173  * @self: object to refresh
1174  *
1175  * calls the class refresh function
1176  *
1177  */
1178 void
seahorse_object_refresh(SeahorseObject * self)1179 seahorse_object_refresh (SeahorseObject *self)
1180 {
1181 	SeahorseObjectClass *klass;
1182 	g_return_if_fail (SEAHORSE_IS_OBJECT (self));
1183 	klass = SEAHORSE_OBJECT_GET_CLASS (self);
1184 	g_return_if_fail (klass->refresh);
1185 	(klass->refresh) (self);
1186 }
1187 
1188 /**
1189  * seahorse_object_predicate_match:
1190  * @self: the object to test
1191  * @obj: The predicate to match
1192  *
1193  * matches a seahorse object and a predicate
1194  *
1195  * Returns: FALSE if predicate does not match the #SeahorseObject, TRUE else
1196  */
1197 gboolean
seahorse_object_predicate_match(SeahorseObjectPredicate * self,SeahorseObject * obj)1198 seahorse_object_predicate_match (SeahorseObjectPredicate *self, SeahorseObject* obj)
1199 {
1200 	SeahorseObjectPrivate *pv;
1201 
1202 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (obj), FALSE);
1203 	pv = obj->pv;
1204 
1205 	seahorse_object_realize (obj);
1206 
1207 	/* Check all the fields */
1208 	if (self->tag != 0 && self->tag != pv->tag)
1209 		return FALSE;
1210 	if (self->id != 0 && self->id != pv->id)
1211 		return FALSE;
1212 	if (self->type != 0 && self->type != G_OBJECT_TYPE (obj))
1213 		return FALSE;
1214 	if (self->location != 0 && self->location != pv->location)
1215 		return FALSE;
1216 	if (self->usage != 0 && self->usage != pv->usage)
1217 		return FALSE;
1218 	if (self->flags != 0 && (self->flags & pv->flags) == 0)
1219 		return FALSE;
1220 	if (self->nflags != 0 && (self->nflags & pv->flags) != 0)
1221 		return FALSE;
1222 	if (self->source != NULL && self->source != pv->source)
1223 		return FALSE;
1224 
1225 	/* And any custom stuff */
1226 	if (self->custom != NULL && !self->custom (obj, self->custom_target))
1227 		return FALSE;
1228 
1229 	return TRUE;
1230 }
1231 
1232 /**
1233  * seahorse_object_predicate_clear:
1234  * @self: The predicate to clean
1235  *
1236  * Clears a seahorse predicate (#SeahorseObjectPredicate)
1237  */
1238 void
seahorse_object_predicate_clear(SeahorseObjectPredicate * self)1239 seahorse_object_predicate_clear (SeahorseObjectPredicate *self)
1240 {
1241 	memset (self, 0, sizeof (*self));
1242 }
1243