1 /*
2  * Seahorse
3  *
4  * Copyright (C) 2006 Stefan Walter
5  * Copyright (C) 2011 Collabora Ltd.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15  * See the GNU General Public License for more details.
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see
18  * <http://www.gnu.org/licenses/>.
19  */
20 
21 #include "config.h"
22 
23 #include "seahorse-unknown-source.h"
24 
25 #include "seahorse-pgp-key.h"
26 #include "seahorse-unknown.h"
27 
28 #include <gcr/gcr-base.h>
29 
30 #include <glib/gi18n.h>
31 
32 enum {
33     PROP_0,
34     PROP_LABEL,
35     PROP_DESCRIPTION,
36     PROP_ICON,
37     PROP_CATEGORY,
38     PROP_URI,
39     PROP_ACTIONS,
40     PROP_ACTION_PREFIX,
41     PROP_MENU_MODEL,
42     PROP_SHOW_IF_EMPTY,
43     N_PROPS
44 };
45 
46 struct _SeahorseUnknownSource {
47 	GObject parent;
48 	GHashTable *keys;
49 };
50 
51 struct _SeahorseUnknownSourceClass {
52 	GObjectClass parent_class;
53 };
54 
55 static void      seahorse_unknown_source_collection_iface      (GcrCollectionIface *iface);
56 
57 static void      seahorse_unknown_source_place_iface           (SeahorsePlaceIface *iface);
58 
59 G_DEFINE_TYPE_WITH_CODE (SeahorseUnknownSource, seahorse_unknown_source, G_TYPE_OBJECT,
60                          G_IMPLEMENT_INTERFACE (GCR_TYPE_COLLECTION, seahorse_unknown_source_collection_iface);
61                          G_IMPLEMENT_INTERFACE (SEAHORSE_TYPE_PLACE, seahorse_unknown_source_place_iface);
62 );
63 
64 static void
seahorse_unknown_source_init(SeahorseUnknownSource * self)65 seahorse_unknown_source_init (SeahorseUnknownSource *self)
66 {
67 	self->keys = g_hash_table_new_full (seahorse_pgp_keyid_hash,
68 	                                    seahorse_pgp_keyid_equal,
69 	                                    g_free, g_object_unref);
70 }
71 
72 static void
seahorse_unknown_source_load(SeahorsePlace * self,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)73 seahorse_unknown_source_load (SeahorsePlace *self,
74                               GCancellable *cancellable,
75                               GAsyncReadyCallback callback,
76                               gpointer user_data)
77 {
78 	g_return_if_reached ();
79 }
80 
81 static gboolean
seahorse_unknown_source_load_finish(SeahorsePlace * self,GAsyncResult * res,GError ** error)82 seahorse_unknown_source_load_finish (SeahorsePlace *self,
83                                      GAsyncResult *res,
84                                      GError **error)
85 {
86 	g_return_val_if_reached (FALSE);
87 }
88 
89 static gchar *
seahorse_unknown_source_get_label(SeahorsePlace * self)90 seahorse_unknown_source_get_label (SeahorsePlace* self)
91 {
92 	return g_strdup ("");
93 }
94 
95 static void
seahorse_unknown_source_set_label(SeahorsePlace * self,const char * label)96 seahorse_unknown_source_set_label (SeahorsePlace *self, const char *label)
97 {
98 }
99 
100 static gchar *
seahorse_unknown_source_get_description(SeahorsePlace * self)101 seahorse_unknown_source_get_description (SeahorsePlace* self)
102 {
103 	return NULL;
104 }
105 
106 static gchar *
seahorse_unknown_source_get_uri(SeahorsePlace * self)107 seahorse_unknown_source_get_uri (SeahorsePlace* self)
108 {
109 	return NULL;
110 }
111 
112 static GIcon *
seahorse_unknown_source_get_icon(SeahorsePlace * self)113 seahorse_unknown_source_get_icon (SeahorsePlace* self)
114 {
115 	return NULL;
116 }
117 
118 static SeahorsePlaceCategory
seahorse_unknown_source_get_category(SeahorsePlace * place)119 seahorse_unknown_source_get_category (SeahorsePlace *place)
120 {
121     return SEAHORSE_PLACE_CATEGORY_KEYS;
122 }
123 
124 static GActionGroup *
seahorse_unknown_source_get_actions(SeahorsePlace * self)125 seahorse_unknown_source_get_actions (SeahorsePlace* self)
126 {
127 	return NULL;
128 }
129 
130 static const gchar *
seahorse_unknown_source_get_action_prefix(SeahorsePlace * self)131 seahorse_unknown_source_get_action_prefix (SeahorsePlace* self)
132 {
133     return NULL;
134 }
135 
136 static GMenuModel *
seahorse_unknown_source_get_menu_model(SeahorsePlace * self)137 seahorse_unknown_source_get_menu_model (SeahorsePlace* self)
138 {
139 	return NULL;
140 }
141 
142 static gboolean
seahorse_unknown_source_get_show_if_empty(SeahorsePlace * place)143 seahorse_unknown_source_get_show_if_empty (SeahorsePlace *place)
144 {
145     return TRUE;
146 }
147 
148 static void
seahorse_unknown_source_get_property(GObject * obj,guint prop_id,GValue * value,GParamSpec * pspec)149 seahorse_unknown_source_get_property (GObject *obj,
150                                       guint prop_id,
151                                       GValue *value,
152                                       GParamSpec *pspec)
153 {
154 	SeahorsePlace *place = SEAHORSE_PLACE (obj);
155 
156 	switch (prop_id) {
157 	case PROP_LABEL:
158 		g_value_take_string (value, seahorse_unknown_source_get_label (place));
159 		break;
160 	case PROP_DESCRIPTION:
161 		g_value_take_string (value, seahorse_unknown_source_get_description (place));
162 		break;
163 	case PROP_URI:
164 		g_value_take_string (value, seahorse_unknown_source_get_uri (place));
165 		break;
166     case PROP_ICON:
167         g_value_take_object (value, seahorse_unknown_source_get_icon (place));
168         break;
169     case PROP_CATEGORY:
170         g_value_set_enum (value, seahorse_unknown_source_get_category (place));
171         break;
172     case PROP_ACTIONS:
173         g_value_take_object (value, seahorse_unknown_source_get_actions (place));
174         break;
175     case PROP_ACTION_PREFIX:
176         g_value_set_string (value, seahorse_unknown_source_get_action_prefix (place));
177         break;
178     case PROP_MENU_MODEL:
179         g_value_take_object (value, seahorse_unknown_source_get_menu_model (place));
180         break;
181     case PROP_SHOW_IF_EMPTY:
182         g_value_set_boolean (value, TRUE);
183         break;
184     default:
185         G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
186         break;
187     }
188 }
189 
190 static void
seahorse_unknown_source_set_property(GObject * obj,guint prop_id,const GValue * value,GParamSpec * pspec)191 seahorse_unknown_source_set_property (GObject *obj,
192                                       guint prop_id,
193                                       const GValue *value,
194                                       GParamSpec *pspec)
195 {
196 	SeahorsePlace *place = SEAHORSE_PLACE (obj);
197 
198 	switch (prop_id) {
199 	case PROP_LABEL:
200 		seahorse_unknown_source_set_label (place, g_value_get_boxed (value));
201 		break;
202 	default:
203 		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
204 		break;
205 	}
206 }
207 
208 static void
seahorse_unknown_source_finalize(GObject * obj)209 seahorse_unknown_source_finalize (GObject *obj)
210 {
211 	SeahorseUnknownSource *self = SEAHORSE_UNKNOWN_SOURCE (obj);
212 
213 	g_hash_table_destroy (self->keys);
214 
215 	G_OBJECT_CLASS (seahorse_unknown_source_parent_class)->finalize (obj);
216 }
217 
218 static void
seahorse_unknown_source_class_init(SeahorseUnknownSourceClass * klass)219 seahorse_unknown_source_class_init (SeahorseUnknownSourceClass *klass)
220 {
221 	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
222 
223 	gobject_class->get_property = seahorse_unknown_source_get_property;
224 	gobject_class->set_property = seahorse_unknown_source_set_property;
225 	gobject_class->finalize = seahorse_unknown_source_finalize;
226 
227     g_object_class_override_property (gobject_class, PROP_LABEL, "label");
228     g_object_class_override_property (gobject_class, PROP_DESCRIPTION, "description");
229     g_object_class_override_property (gobject_class, PROP_ICON, "icon");
230     g_object_class_override_property (gobject_class, PROP_CATEGORY, "category");
231     g_object_class_override_property (gobject_class, PROP_ACTIONS, "actions");
232     g_object_class_override_property (gobject_class, PROP_ACTION_PREFIX, "action-prefix");
233     g_object_class_override_property (gobject_class, PROP_MENU_MODEL, "menu-model");
234     g_object_class_override_property (gobject_class, PROP_URI, "uri");
235     g_object_class_override_property (gobject_class, PROP_SHOW_IF_EMPTY, "show-if-empty");
236 }
237 
238 static guint
seahorse_unknown_source_get_length(GcrCollection * collection)239 seahorse_unknown_source_get_length (GcrCollection *collection)
240 {
241 	SeahorseUnknownSource *self = SEAHORSE_UNKNOWN_SOURCE (collection);
242 	return g_hash_table_size (self->keys);
243 }
244 
245 static GList *
seahorse_unknown_source_get_objects(GcrCollection * collection)246 seahorse_unknown_source_get_objects (GcrCollection *collection)
247 {
248 	SeahorseUnknownSource *self = SEAHORSE_UNKNOWN_SOURCE (collection);
249 	return g_hash_table_get_values (self->keys);
250 }
251 
252 static gboolean
seahorse_unknown_source_contains(GcrCollection * collection,GObject * object)253 seahorse_unknown_source_contains (GcrCollection *collection,
254                                   GObject *object)
255 {
256 	SeahorseUnknownSource *self = SEAHORSE_UNKNOWN_SOURCE (collection);
257 	const gchar *identifier = seahorse_object_get_identifier (SEAHORSE_OBJECT (object));
258 	return g_hash_table_lookup (self->keys, identifier) == object;
259 }
260 
261 static void
seahorse_unknown_source_collection_iface(GcrCollectionIface * iface)262 seahorse_unknown_source_collection_iface (GcrCollectionIface *iface)
263 {
264 	iface->contains = seahorse_unknown_source_contains;
265 	iface->get_length = seahorse_unknown_source_get_length;
266 	iface->get_objects = seahorse_unknown_source_get_objects;
267 }
268 
269 static void
seahorse_unknown_source_place_iface(SeahorsePlaceIface * iface)270 seahorse_unknown_source_place_iface (SeahorsePlaceIface *iface)
271 {
272     iface->load = seahorse_unknown_source_load;
273     iface->load_finish = seahorse_unknown_source_load_finish;
274     iface->get_actions = seahorse_unknown_source_get_actions;
275     iface->get_menu_model = seahorse_unknown_source_get_menu_model;
276     iface->get_description = seahorse_unknown_source_get_description;
277     iface->get_icon = seahorse_unknown_source_get_icon;
278     iface->get_category = seahorse_unknown_source_get_category;
279     iface->get_label = seahorse_unknown_source_get_label;
280     iface->set_label = seahorse_unknown_source_set_label;
281     iface->get_uri = seahorse_unknown_source_get_uri;
282     iface->get_show_if_empty = seahorse_unknown_source_get_show_if_empty;
283 }
284 
285 SeahorseUnknownSource*
seahorse_unknown_source_new(void)286 seahorse_unknown_source_new (void)
287 {
288 	return g_object_new (SEAHORSE_TYPE_UNKNOWN_SOURCE, NULL);
289 }
290 
291 static void
on_cancellable_gone(gpointer user_data,GObject * where_the_object_was)292 on_cancellable_gone (gpointer user_data,
293                      GObject *where_the_object_was)
294 {
295 	/* TODO: Change the icon */
296 }
297 
298 SeahorseObject *
seahorse_unknown_source_add_object(SeahorseUnknownSource * self,const gchar * keyid,GCancellable * cancellable)299 seahorse_unknown_source_add_object (SeahorseUnknownSource *self,
300                                     const gchar *keyid,
301                                     GCancellable *cancellable)
302 {
303 	SeahorseObject *object;
304 
305 	g_return_val_if_fail (keyid != NULL, NULL);
306 	g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), NULL);
307 
308 	object = g_hash_table_lookup (self->keys, keyid);
309 	if (object == NULL) {
310 		object = SEAHORSE_OBJECT (seahorse_unknown_new (self, keyid, NULL));
311 		g_hash_table_insert (self->keys, g_strdup (keyid), object);
312 	}
313 
314 	if (cancellable)
315 		g_object_weak_ref (G_OBJECT (cancellable), on_cancellable_gone, object);
316 
317 	return object;
318 }
319