* libanjuta/interfaces/libanjuta.idl:
[anjuta-git-plugin.git] / libanjuta / anjuta-plugin-handle.c
blobf7a996f65f580470a3232b976206781ae9291df2
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * anjuta-plugin-handle.c
4 * Copyright (C) Naba Kumar <naba@gnome.org>
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.
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. See the
14 * 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, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 /**
22 * SECTION:anjuta-plugin-handle
23 * @short_description: Handle used by plugin manager to keep track of plugins.
24 * @see_also: #AnjutaPluginManager, #AnjutaPluginDescription, #AnjutaPlugin
25 * @stability: Unstable
26 * @include: libanjuta/anjuta-plugin-handle.h
28 * Plugin handle is wrapper for installed plugins. For each installed plugin
29 * there will be one corresponding plugin handle. It is mainly used by
30 * plugin manager to keep track of loading and unloading of plugins.
33 #include <string.h>
34 #include "anjuta-plugin-handle.h"
35 #include "resources.h"
36 #include "anjuta-debug.h"
38 enum
40 PROP_0,
42 PROP_ID,
43 PROP_NAME,
44 PROP_ABOUT,
45 PROP_ICON_PATH,
46 PROP_USER_ACTIVATABLE,
47 PROP_RESIDENT,
48 PROP_LANGUAGE,
49 PROP_DESCRIPTION,
50 PROP_DEPENDENCY_NAMES,
51 PROP_DEPENDENCIES,
52 PROP_DEPENDENTS,
53 PROP_INTERFACES,
54 PROP_CAN_LOAD,
55 PROP_CHECKED,
56 PROP_RESOLVE_PASS
59 struct _AnjutaPluginHandlePriv
61 char *id;
62 char *name;
63 char *about;
64 char *icon_path;
65 gboolean user_activatable;
66 gboolean resident;
67 char *language;
69 AnjutaPluginDescription *description;
71 /* The dependencies listed in the oaf file */
72 GList *dependency_names;
74 /* Interfaces exported by this plugin */
75 GList *interfaces;
77 /* Attributes defined for this plugin */
78 /* GHashTable *attributes; */
80 /* The keys of these tables represent the dependencies and dependents
81 * of the module. The values point back at the plugins */
82 GHashTable *dependencies;
83 GHashTable *dependents;
85 gboolean can_load;
86 gboolean checked;
88 /* The pass on which the module was resolved, or -1 if
89 * unresolved */
90 int resolve_pass;
93 static GObjectClass* parent_class = NULL;
95 static void
96 anjuta_plugin_handle_init (AnjutaPluginHandle *object)
98 object->priv = g_new0 (AnjutaPluginHandlePriv, 1);
100 object->priv->resolve_pass = -1;
102 object->priv->dependencies = g_hash_table_new (g_direct_hash,
103 g_direct_equal);
104 object->priv->dependents = g_hash_table_new (g_direct_hash,
105 g_direct_equal);
108 static void
109 anjuta_plugin_handle_finalize (GObject *object)
111 AnjutaPluginHandlePriv *priv;
113 priv = ANJUTA_PLUGIN_HANDLE (object)->priv;
115 g_free (priv->id);
116 priv->id = NULL;
117 g_free (priv->name);
118 priv->name = NULL;
119 g_free (priv->icon_path);
120 priv->icon_path = NULL;
121 g_free (priv->language);
122 priv->language = NULL;
124 g_list_foreach (priv->dependency_names, (GFunc)g_free, NULL);
125 g_list_free (priv->dependency_names);
126 priv->dependency_names = NULL;
128 g_list_foreach (priv->interfaces, (GFunc)g_free, NULL);
129 g_list_free (priv->dependency_names);
130 priv->dependency_names = NULL;
132 g_hash_table_destroy (priv->dependencies);
133 priv->dependencies = NULL;
134 g_hash_table_destroy (priv->dependents);
135 priv->dependents = NULL;
137 g_free (priv);
139 G_OBJECT_CLASS (parent_class)->finalize (object);
142 static void
143 anjuta_plugin_handle_set_property (GObject *object, guint prop_id,
144 const GValue *value, GParamSpec *pspec)
146 g_return_if_fail (ANJUTA_IS_PLUGIN_HANDLE (object));
148 switch (prop_id)
150 #if 0
151 case PROP_ID:
152 /* TODO: Add setter for "id" property here */
153 break;
154 case PROP_NAME:
155 /* TODO: Add setter for "name" property here */
156 break;
157 case PROP_ABOUT:
158 /* TODO: Add setter for "about" property here */
159 break;
160 case PROP_ICON_PATH:
161 /* TODO: Add setter for "icon-path" property here */
162 break;
163 case PROP_USER_ACTIVATABLE:
164 /* TODO: Add setter for "user-activatable" property here */
165 break;
166 case PROP_RESIDENT:
167 /* TODO: Add setter for "resident" property here */
168 break;
169 case PROP_LANGUAGE:
170 /* TODO: Add setter for "language" property here */
171 break;
172 case PROP_DESCRIPTION:
173 /* TODO: Add setter for "description" property here */
174 break;
175 case PROP_DEPENDENCY_NAMES:
176 /* TODO: Add setter for "dependency-names" property here */
177 break;
178 case PROP_DEPENDENCIES:
179 /* TODO: Add setter for "dependencies" property here */
180 break;
181 case PROP_DEPENDENTS:
182 /* TODO: Add setter for "dependents" property here */
183 break;
184 case PROP_INTERFACES:
185 /* TODO: Add setter for "interfaces" property here */
186 break;
187 case PROP_CAN_LOAD:
188 /* TODO: Add setter for "can-load" property here */
189 break;
190 case PROP_CHECKED:
191 /* TODO: Add setter for "checked" property here */
192 break;
193 case PROP_RESOLVE_PASS:
194 /* TODO: Add setter for "resolve-pass" property here */
195 break;
196 #endif
197 default:
198 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
199 break;
203 static void
204 anjuta_plugin_handle_get_property (GObject *object, guint prop_id,
205 GValue *value, GParamSpec *pspec)
207 AnjutaPluginHandlePriv *priv;
209 g_return_if_fail (ANJUTA_IS_PLUGIN_HANDLE (object));
210 priv = ANJUTA_PLUGIN_HANDLE (object)->priv;
211 switch (prop_id)
213 case PROP_ID:
214 g_value_set_string (value, priv->id);
215 break;
216 case PROP_NAME:
217 g_value_set_string (value, priv->name);
218 break;
219 case PROP_ABOUT:
220 g_value_set_string (value, priv->about);
221 break;
222 case PROP_ICON_PATH:
223 g_value_set_string (value, priv->icon_path);
224 break;
225 case PROP_USER_ACTIVATABLE:
226 g_value_set_boolean (value, priv->user_activatable);
227 break;
228 case PROP_RESIDENT:
229 g_value_set_boolean (value, priv->resident);
230 break;
231 case PROP_LANGUAGE:
232 g_value_set_string (value, priv->language);
233 break;
234 case PROP_DESCRIPTION:
235 g_value_set_pointer (value, priv->description);
236 break;
237 case PROP_DEPENDENCY_NAMES:
238 g_value_set_pointer (value, priv->dependency_names);
239 break;
240 case PROP_DEPENDENCIES:
241 g_value_set_pointer (value, priv->dependencies);
242 break;
243 case PROP_DEPENDENTS:
244 g_value_set_pointer (value, priv->dependents);
245 break;
246 case PROP_INTERFACES:
247 g_value_set_pointer (value, priv->interfaces);
248 break;
249 case PROP_CAN_LOAD:
250 g_value_set_boolean (value, priv->can_load);
251 break;
252 case PROP_CHECKED:
253 g_value_set_boolean (value, priv->checked);
254 break;
255 case PROP_RESOLVE_PASS:
256 g_value_set_int (value, priv->resolve_pass);
257 break;
258 default:
259 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
260 break;
264 static void
265 anjuta_plugin_handle_class_init (AnjutaPluginHandleClass *klass)
267 GObjectClass* object_class = G_OBJECT_CLASS (klass);
268 parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
270 object_class->finalize = anjuta_plugin_handle_finalize;
271 object_class->set_property = anjuta_plugin_handle_set_property;
272 object_class->get_property = anjuta_plugin_handle_get_property;
274 g_object_class_install_property (object_class,
275 PROP_ID,
276 g_param_spec_string ("id",
277 "ID",
278 "Unique plugin ID",
279 NULL,
280 G_PARAM_READABLE));
282 g_object_class_install_property (object_class,
283 PROP_NAME,
284 g_param_spec_string ("name",
285 "Name",
286 "Plugin name",
287 NULL,
288 G_PARAM_READABLE));
290 g_object_class_install_property (object_class,
291 PROP_ABOUT,
292 g_param_spec_string ("about",
293 "About Plugin",
294 "About description of the plugin",
295 NULL,
296 G_PARAM_READABLE));
298 g_object_class_install_property (object_class,
299 PROP_ICON_PATH,
300 g_param_spec_string ("icon-path",
301 "Icon Path",
302 "Icon path of the plugin",
303 NULL,
304 G_PARAM_READABLE));
306 g_object_class_install_property (object_class,
307 PROP_USER_ACTIVATABLE,
308 g_param_spec_boolean ("user-activatable",
309 "User Activatable",
310 "If the plugin is user activatable",
311 FALSE,
312 G_PARAM_READABLE));
314 g_object_class_install_property (object_class,
315 PROP_RESIDENT,
316 g_param_spec_boolean ("resident",
317 "Resident",
318 "If the plugin cannot be unloaded",
319 FALSE,
320 G_PARAM_READABLE));
322 g_object_class_install_property (object_class,
323 PROP_LANGUAGE,
324 g_param_spec_string ("language",
325 "Language",
326 "Language used to write the plugin",
327 NULL,
328 G_PARAM_READABLE));
330 g_object_class_install_property (object_class,
331 PROP_DESCRIPTION,
332 g_param_spec_pointer ("description",
333 "Description",
334 "Plugin description",
335 G_PARAM_READABLE));
337 g_object_class_install_property (object_class,
338 PROP_DEPENDENCY_NAMES,
339 g_param_spec_pointer ("dependency-names",
340 "Dependency names",
341 "Plugin dependency names listed in oaf file",
342 G_PARAM_READABLE));
344 g_object_class_install_property (object_class,
345 PROP_DEPENDENCIES,
346 g_param_spec_pointer ("dependencies",
347 "Dependencies",
348 "Plugin dependencies",
349 G_PARAM_READABLE));
351 g_object_class_install_property (object_class,
352 PROP_DEPENDENTS,
353 g_param_spec_pointer ("dependents",
354 "Dependents",
355 "Plugin dependents",
356 G_PARAM_READABLE));
358 g_object_class_install_property (object_class,
359 PROP_INTERFACES,
360 g_param_spec_pointer ("interfaces",
361 "Interfaces",
362 "Interfaces exported by the plugin",
363 G_PARAM_READABLE));
365 g_object_class_install_property (object_class,
366 PROP_CAN_LOAD,
367 g_param_spec_boolean ("can-load",
368 "Can Load",
369 "If the plugin can be loaded",
370 FALSE,
371 G_PARAM_READABLE));
373 g_object_class_install_property (object_class,
374 PROP_CHECKED,
375 g_param_spec_boolean ("checked",
376 "Checked",
377 "If the plugin is checked in UI",
378 FALSE,
379 G_PARAM_READABLE));
381 g_object_class_install_property (object_class,
382 PROP_RESOLVE_PASS,
383 g_param_spec_int ("resolve-pass",
384 "Resolve Pass",
385 "Dependency resolution pass",
386 G_MININT, /* TODO: Adjust minimum property value */
387 G_MAXINT, /* TODO: Adjust maximum property value */
389 G_PARAM_READABLE));
392 GType
393 anjuta_plugin_handle_get_type (void)
395 static GType our_type = 0;
397 if(our_type == 0)
399 static const GTypeInfo our_info =
401 sizeof (AnjutaPluginHandleClass), /* class_size */
402 (GBaseInitFunc) NULL, /* base_init */
403 (GBaseFinalizeFunc) NULL, /* base_finalize */
404 (GClassInitFunc) anjuta_plugin_handle_class_init, /* class_init */
405 (GClassFinalizeFunc) NULL, /* class_finalize */
406 NULL /* class_data */,
407 sizeof (AnjutaPluginHandle), /* instance_size */
408 0, /* n_preallocs */
409 (GInstanceInitFunc) anjuta_plugin_handle_init, /* instance_init */
410 NULL /* value_table */
413 our_type = g_type_register_static (G_TYPE_OBJECT, "AnjutaPluginHandle",
414 &our_info, 0);
417 return our_type;
421 static char *
422 get_icon_path (char *icon_name)
424 char *ret;
426 if (g_path_is_absolute (icon_name)) {
427 ret = g_strdup (icon_name);
428 } else {
429 ret = anjuta_res_get_pixmap_file (icon_name);
432 return ret;
435 static GList *
436 property_to_list (const char *value)
438 GList *l = NULL;
439 char **split_str;
440 char **p;
442 split_str = g_strsplit (value, ",", -1);
443 for (p = split_str; *p != NULL; p++) {
444 l = g_list_prepend (l, g_strdup (g_strstrip (*p)));
446 g_strfreev (split_str);
447 return l;
450 AnjutaPluginHandle*
451 anjuta_plugin_handle_new (const gchar *plugin_desc_path)
453 AnjutaPluginHandle *plugin_handle;
454 AnjutaPluginDescription *desc;
455 char *str;
456 gchar *contents;
457 gboolean success = TRUE;
459 /* Load file content */
460 if (g_file_get_contents (plugin_desc_path, &contents, NULL, NULL)) {
462 desc = anjuta_plugin_description_new_from_string (contents, NULL);
463 g_free (contents);
464 if (!desc) {
465 g_warning ("Bad plugin file: %s\n", plugin_desc_path);
466 return NULL;
469 else
471 return NULL;
474 plugin_handle = g_object_new (ANJUTA_TYPE_PLUGIN_HANDLE, NULL);
476 /* Initialize plugin handle */
477 plugin_handle->priv->description = desc;
478 plugin_handle->priv->user_activatable = TRUE;
479 plugin_handle->priv->resident = TRUE;
481 if (anjuta_plugin_description_get_string (desc, "Anjuta Plugin",
482 "Location", &str)) {
483 plugin_handle->priv->id = str;
484 } else {
485 g_warning ("Couldn't find 'Location'");
486 success = FALSE;
489 if (anjuta_plugin_description_get_string (desc, "Anjuta Plugin",
490 "Name", &str)) {
491 plugin_handle->priv->name = str;
492 } else {
493 g_warning ("couldn't find 'Name' attribute.");
494 success = FALSE;
497 if (anjuta_plugin_description_get_string (desc, "Anjuta Plugin",
498 "Description", &str)) {
499 plugin_handle->priv->about = str;
500 } else {
501 g_warning ("Couldn't find 'Description' attribute.");
502 success = FALSE;
505 if (anjuta_plugin_description_get_string (desc, "Anjuta Plugin",
506 "Icon", &str)) {
507 plugin_handle->priv->icon_path = get_icon_path (str);
508 g_free (str);
511 if (anjuta_plugin_description_get_string (desc, "Anjuta Plugin",
512 "Dependencies",
513 &str)) {
514 plugin_handle->priv->dependency_names = property_to_list (str);
515 g_free (str);
518 if (anjuta_plugin_description_get_string (desc, "Anjuta Plugin",
519 "Interfaces",
520 &str)) {
521 plugin_handle->priv->interfaces = property_to_list (str);
522 g_free (str);
525 if (anjuta_plugin_description_get_string (desc, "Anjuta Plugin",
526 "UserActivatable", &str)) {
527 if (str && strcasecmp (str, "no") == 0)
529 plugin_handle->priv->user_activatable = FALSE;
531 DEBUG_PRINT ("Plugin '%s' is not user activatable",
532 plugin_handle->priv->name?
533 plugin_handle->priv->name : "Unknown");
536 g_free (str);
539 if (anjuta_plugin_description_get_string (desc, "Anjuta Plugin",
540 "Resident", &str)) {
541 if (str && strcasecmp (str, "no") == 0)
543 plugin_handle->priv->resident = FALSE;
545 g_free (str);
548 if (anjuta_plugin_description_get_string (desc, "Anjuta Plugin",
549 "Language", &str)) {
550 plugin_handle->priv->language = str;
553 if (!success) {
554 g_object_unref (plugin_handle);
555 plugin_handle = NULL;
558 return plugin_handle;
561 const char*
562 anjuta_plugin_handle_get_id (AnjutaPluginHandle *plugin_handle)
564 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle), NULL);
565 return plugin_handle->priv->id;
568 const char*
569 anjuta_plugin_handle_get_name (AnjutaPluginHandle *plugin_handle)
571 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle), NULL);
572 return plugin_handle->priv->name;
575 const char*
576 anjuta_plugin_handle_get_about (AnjutaPluginHandle *plugin_handle)
578 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle), NULL);
579 return plugin_handle->priv->about;
582 const char*
583 anjuta_plugin_handle_get_icon_path (AnjutaPluginHandle *plugin_handle)
585 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle), NULL);
586 return plugin_handle->priv->icon_path;
589 gboolean
590 anjuta_plugin_handle_get_user_activatable (AnjutaPluginHandle *plugin_handle)
592 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle), FALSE);
593 return plugin_handle->priv->user_activatable;
596 gboolean
597 anjuta_plugin_handle_get_resident (AnjutaPluginHandle *plugin_handle)
599 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle), FALSE);
600 return plugin_handle->priv->resident;
603 const char*
604 anjuta_plugin_handle_get_language (AnjutaPluginHandle *plugin_handle)
606 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle), NULL);
607 return plugin_handle->priv->language;
610 AnjutaPluginDescription*
611 anjuta_plugin_handle_get_description (AnjutaPluginHandle *plugin_handle)
613 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle), NULL);
614 return plugin_handle->priv->description;
617 GList*
618 anjuta_plugin_handle_get_dependency_names (AnjutaPluginHandle *plugin_handle)
620 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle), NULL);
621 return plugin_handle->priv->dependency_names;
624 GHashTable*
625 anjuta_plugin_handle_get_dependencies (AnjutaPluginHandle *plugin_handle)
627 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle), NULL);
628 return plugin_handle->priv->dependencies;
631 GHashTable*
632 anjuta_plugin_handle_get_dependents (AnjutaPluginHandle *plugin_handle)
634 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle), NULL);
635 return plugin_handle->priv->dependents;
638 GList*
639 anjuta_plugin_handle_get_interfaces (AnjutaPluginHandle *plugin_handle)
641 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle), NULL);
642 return plugin_handle->priv->interfaces;
645 gboolean
646 anjuta_plugin_handle_get_can_load (AnjutaPluginHandle *plugin_handle)
648 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle), FALSE);
649 return plugin_handle->priv->can_load;
652 gboolean
653 anjuta_plugin_handle_get_checked (AnjutaPluginHandle *plugin_handle)
655 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle), FALSE);
656 return plugin_handle->priv->checked;
659 gint
660 anjuta_plugin_handle_get_resolve_pass (AnjutaPluginHandle *plugin_handle)
662 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle), 0);
663 return plugin_handle->priv->resolve_pass;
666 void
667 anjuta_plugin_handle_set_can_load (AnjutaPluginHandle *plugin_handle,
668 gboolean can_load)
670 g_return_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle));
671 plugin_handle->priv->can_load = can_load;
674 void
675 anjuta_plugin_handle_set_checked (AnjutaPluginHandle *plugin_handle,
676 gboolean checked)
678 g_return_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle));
679 plugin_handle->priv->checked = checked;
682 void
683 anjuta_plugin_handle_set_resolve_pass (AnjutaPluginHandle *plugin_handle,
684 gboolean resolve_pass)
686 g_return_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle));
687 plugin_handle->priv->resolve_pass = resolve_pass;
690 static gboolean
691 g_hashtable_foreach_true (gpointer key, gpointer value, gpointer user_data)
693 return TRUE;
696 void
697 anjuta_plugin_handle_unresolve_dependencies (AnjutaPluginHandle *plugin_handle)
699 AnjutaPluginHandlePriv *priv;
701 g_return_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle));
702 priv = plugin_handle->priv;
704 g_hash_table_foreach_remove (priv->dependencies, g_hashtable_foreach_true,
705 NULL);
706 g_hash_table_foreach_remove (priv->dependents, g_hashtable_foreach_true,
707 NULL);
708 priv->can_load = TRUE;
709 priv->resolve_pass = -1;