* scripts/anjuta_import.sh.in,
[anjuta-git-plugin.git] / libanjuta / anjuta-plugin-handle.c
blob0bc9547e1589d31c1d5d88e24f98e4d8ac267b0f
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 <glib/gi18n.h>
35 #include "anjuta-plugin-handle.h"
36 #include "resources.h"
37 #include "anjuta-debug.h"
39 enum
41 PROP_0,
43 PROP_ID,
44 PROP_NAME,
45 PROP_ABOUT,
46 PROP_ICON_PATH,
47 PROP_USER_ACTIVATABLE,
48 PROP_RESIDENT,
49 PROP_LANGUAGE,
50 PROP_DESCRIPTION,
51 PROP_DEPENDENCY_NAMES,
52 PROP_DEPENDENCIES,
53 PROP_DEPENDENTS,
54 PROP_INTERFACES,
55 PROP_CAN_LOAD,
56 PROP_CHECKED,
57 PROP_RESOLVE_PASS,
58 PROP_PATH
61 struct _AnjutaPluginHandlePriv
63 char *id;
64 char *name;
65 char *about;
66 char *icon_path;
67 char *path;
68 gboolean user_activatable;
69 gboolean resident;
70 char *language;
72 AnjutaPluginDescription *description;
74 /* The dependencies listed in the oaf file */
75 GList *dependency_names;
77 /* Interfaces exported by this plugin */
78 GList *interfaces;
80 /* Attributes defined for this plugin */
81 /* GHashTable *attributes; */
83 /* The keys of these tables represent the dependencies and dependents
84 * of the module. The values point back at the plugins */
85 GHashTable *dependencies;
86 GHashTable *dependents;
88 gboolean can_load;
89 gboolean checked;
91 /* The pass on which the module was resolved, or -1 if
92 * unresolved */
93 int resolve_pass;
96 static GObjectClass* parent_class = NULL;
98 static void
99 anjuta_plugin_handle_init (AnjutaPluginHandle *object)
101 object->priv = g_new0 (AnjutaPluginHandlePriv, 1);
103 object->priv->resolve_pass = -1;
105 object->priv->dependencies = g_hash_table_new (g_direct_hash,
106 g_direct_equal);
107 object->priv->dependents = g_hash_table_new (g_direct_hash,
108 g_direct_equal);
111 static void
112 anjuta_plugin_handle_finalize (GObject *object)
114 AnjutaPluginHandlePriv *priv;
116 priv = ANJUTA_PLUGIN_HANDLE (object)->priv;
118 g_free (priv->id);
119 priv->id = NULL;
120 g_free (priv->name);
121 priv->name = NULL;
122 g_free (priv->icon_path);
123 priv->icon_path = NULL;
124 g_free (priv->path);
125 priv->path = NULL;
126 g_free (priv->language);
127 priv->language = NULL;
129 g_list_foreach (priv->dependency_names, (GFunc)g_free, NULL);
130 g_list_free (priv->dependency_names);
131 priv->dependency_names = NULL;
133 g_list_foreach (priv->interfaces, (GFunc)g_free, NULL);
134 g_list_free (priv->dependency_names);
135 priv->dependency_names = NULL;
137 g_hash_table_destroy (priv->dependencies);
138 priv->dependencies = NULL;
139 g_hash_table_destroy (priv->dependents);
140 priv->dependents = NULL;
142 g_free (priv);
144 G_OBJECT_CLASS (parent_class)->finalize (object);
147 static void
148 anjuta_plugin_handle_set_property (GObject *object, guint prop_id,
149 const GValue *value, GParamSpec *pspec)
151 g_return_if_fail (ANJUTA_IS_PLUGIN_HANDLE (object));
153 switch (prop_id)
155 #if 0
156 case PROP_ID:
157 /* TODO: Add setter for "id" property here */
158 break;
159 case PROP_NAME:
160 /* TODO: Add setter for "name" property here */
161 break;
162 case PROP_ABOUT:
163 /* TODO: Add setter for "about" property here */
164 break;
165 case PROP_ICON_PATH:
166 /* TODO: Add setter for "icon-path" property here */
167 break;
168 case PROP_PATH:
169 /* TODO: Add setter for "path" property here */
170 break;
171 case PROP_USER_ACTIVATABLE:
172 /* TODO: Add setter for "user-activatable" property here */
173 break;
174 case PROP_RESIDENT:
175 /* TODO: Add setter for "resident" property here */
176 break;
177 case PROP_LANGUAGE:
178 /* TODO: Add setter for "language" property here */
179 break;
180 case PROP_DESCRIPTION:
181 /* TODO: Add setter for "description" property here */
182 break;
183 case PROP_DEPENDENCY_NAMES:
184 /* TODO: Add setter for "dependency-names" property here */
185 break;
186 case PROP_DEPENDENCIES:
187 /* TODO: Add setter for "dependencies" property here */
188 break;
189 case PROP_DEPENDENTS:
190 /* TODO: Add setter for "dependents" property here */
191 break;
192 case PROP_INTERFACES:
193 /* TODO: Add setter for "interfaces" property here */
194 break;
195 case PROP_CAN_LOAD:
196 /* TODO: Add setter for "can-load" property here */
197 break;
198 case PROP_CHECKED:
199 /* TODO: Add setter for "checked" property here */
200 break;
201 case PROP_RESOLVE_PASS:
202 /* TODO: Add setter for "resolve-pass" property here */
203 break;
204 #endif
205 default:
206 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
207 break;
211 static void
212 anjuta_plugin_handle_get_property (GObject *object, guint prop_id,
213 GValue *value, GParamSpec *pspec)
215 AnjutaPluginHandlePriv *priv;
217 g_return_if_fail (ANJUTA_IS_PLUGIN_HANDLE (object));
218 priv = ANJUTA_PLUGIN_HANDLE (object)->priv;
219 switch (prop_id)
221 case PROP_ID:
222 g_value_set_string (value, priv->id);
223 break;
224 case PROP_NAME:
225 g_value_set_string (value, priv->name);
226 break;
227 case PROP_ABOUT:
228 g_value_set_string (value, priv->about);
229 break;
230 case PROP_ICON_PATH:
231 g_value_set_string (value, priv->icon_path);
232 break;
233 case PROP_PATH:
234 g_value_set_string (value, priv->path);
235 break;
236 case PROP_USER_ACTIVATABLE:
237 g_value_set_boolean (value, priv->user_activatable);
238 break;
239 case PROP_RESIDENT:
240 g_value_set_boolean (value, priv->resident);
241 break;
242 case PROP_LANGUAGE:
243 g_value_set_string (value, priv->language);
244 break;
245 case PROP_DESCRIPTION:
246 g_value_set_pointer (value, priv->description);
247 break;
248 case PROP_DEPENDENCY_NAMES:
249 g_value_set_pointer (value, priv->dependency_names);
250 break;
251 case PROP_DEPENDENCIES:
252 g_value_set_pointer (value, priv->dependencies);
253 break;
254 case PROP_DEPENDENTS:
255 g_value_set_pointer (value, priv->dependents);
256 break;
257 case PROP_INTERFACES:
258 g_value_set_pointer (value, priv->interfaces);
259 break;
260 case PROP_CAN_LOAD:
261 g_value_set_boolean (value, priv->can_load);
262 break;
263 case PROP_CHECKED:
264 g_value_set_boolean (value, priv->checked);
265 break;
266 case PROP_RESOLVE_PASS:
267 g_value_set_int (value, priv->resolve_pass);
268 break;
269 default:
270 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
271 break;
275 static void
276 anjuta_plugin_handle_class_init (AnjutaPluginHandleClass *klass)
278 GObjectClass* object_class = G_OBJECT_CLASS (klass);
279 parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
281 object_class->finalize = anjuta_plugin_handle_finalize;
282 object_class->set_property = anjuta_plugin_handle_set_property;
283 object_class->get_property = anjuta_plugin_handle_get_property;
285 g_object_class_install_property (object_class,
286 PROP_ID,
287 g_param_spec_string ("id",
288 "ID",
289 "Unique plugin ID",
290 NULL,
291 G_PARAM_READABLE));
293 g_object_class_install_property (object_class,
294 PROP_NAME,
295 g_param_spec_string ("name",
296 "Name",
297 "Plugin name",
298 NULL,
299 G_PARAM_READABLE));
301 g_object_class_install_property (object_class,
302 PROP_ABOUT,
303 g_param_spec_string ("about",
304 "About Plugin",
305 "About description of the plugin",
306 NULL,
307 G_PARAM_READABLE));
309 g_object_class_install_property (object_class,
310 PROP_ICON_PATH,
311 g_param_spec_string ("icon-path",
312 "Icon Path",
313 "Icon path of the plugin",
314 NULL,
315 G_PARAM_READABLE));
317 g_object_class_install_property (object_class,
318 PROP_PATH,
319 g_param_spec_string ("path",
320 "Path",
321 "Path of the plugin",
322 NULL,
323 G_PARAM_READABLE));
325 g_object_class_install_property (object_class,
326 PROP_USER_ACTIVATABLE,
327 g_param_spec_boolean ("user-activatable",
328 "User Activatable",
329 "If the plugin is user activatable",
330 FALSE,
331 G_PARAM_READABLE));
333 g_object_class_install_property (object_class,
334 PROP_RESIDENT,
335 g_param_spec_boolean ("resident",
336 "Resident",
337 "If the plugin cannot be unloaded",
338 FALSE,
339 G_PARAM_READABLE));
341 g_object_class_install_property (object_class,
342 PROP_LANGUAGE,
343 g_param_spec_string ("language",
344 "Language",
345 "Language used to write the plugin",
346 NULL,
347 G_PARAM_READABLE));
349 g_object_class_install_property (object_class,
350 PROP_DESCRIPTION,
351 g_param_spec_pointer ("description",
352 "Description",
353 "Plugin description",
354 G_PARAM_READABLE));
356 g_object_class_install_property (object_class,
357 PROP_DEPENDENCY_NAMES,
358 g_param_spec_pointer ("dependency-names",
359 "Dependency names",
360 "Plugin dependency names listed in oaf file",
361 G_PARAM_READABLE));
363 g_object_class_install_property (object_class,
364 PROP_DEPENDENCIES,
365 g_param_spec_pointer ("dependencies",
366 "Dependencies",
367 "Plugin dependencies",
368 G_PARAM_READABLE));
370 g_object_class_install_property (object_class,
371 PROP_DEPENDENTS,
372 g_param_spec_pointer ("dependents",
373 "Dependents",
374 "Plugin dependents",
375 G_PARAM_READABLE));
377 g_object_class_install_property (object_class,
378 PROP_INTERFACES,
379 g_param_spec_pointer ("interfaces",
380 "Interfaces",
381 "Interfaces exported by the plugin",
382 G_PARAM_READABLE));
384 g_object_class_install_property (object_class,
385 PROP_CAN_LOAD,
386 g_param_spec_boolean ("can-load",
387 "Can Load",
388 "If the plugin can be loaded",
389 FALSE,
390 G_PARAM_READABLE));
392 g_object_class_install_property (object_class,
393 PROP_CHECKED,
394 g_param_spec_boolean ("checked",
395 "Checked",
396 "If the plugin is checked in UI",
397 FALSE,
398 G_PARAM_READABLE));
400 g_object_class_install_property (object_class,
401 PROP_RESOLVE_PASS,
402 g_param_spec_int ("resolve-pass",
403 "Resolve Pass",
404 "Dependency resolution pass",
405 G_MININT, /* TODO: Adjust minimum property value */
406 G_MAXINT, /* TODO: Adjust maximum property value */
408 G_PARAM_READABLE));
411 GType
412 anjuta_plugin_handle_get_type (void)
414 static GType our_type = 0;
416 if(our_type == 0)
418 static const GTypeInfo our_info =
420 sizeof (AnjutaPluginHandleClass), /* class_size */
421 (GBaseInitFunc) NULL, /* base_init */
422 (GBaseFinalizeFunc) NULL, /* base_finalize */
423 (GClassInitFunc) anjuta_plugin_handle_class_init, /* class_init */
424 (GClassFinalizeFunc) NULL, /* class_finalize */
425 NULL /* class_data */,
426 sizeof (AnjutaPluginHandle), /* instance_size */
427 0, /* n_preallocs */
428 (GInstanceInitFunc) anjuta_plugin_handle_init, /* instance_init */
429 NULL /* value_table */
432 our_type = g_type_register_static (G_TYPE_OBJECT, "AnjutaPluginHandle",
433 &our_info, 0);
436 return our_type;
440 static char *
441 get_icon_path (char *icon_name)
443 char *ret;
445 if (g_path_is_absolute (icon_name)) {
446 ret = g_strdup (icon_name);
447 } else {
448 ret = anjuta_res_get_pixmap_file (icon_name);
451 return ret;
454 static GList *
455 property_to_list (const char *value)
457 GList *l = NULL;
458 char **split_str;
459 char **p;
461 split_str = g_strsplit (value, ",", -1);
462 for (p = split_str; *p != NULL; p++) {
463 l = g_list_prepend (l, g_strdup (g_strstrip (*p)));
465 g_strfreev (split_str);
466 return l;
469 AnjutaPluginHandle*
470 anjuta_plugin_handle_new (const gchar *plugin_desc_path)
472 AnjutaPluginHandle *plugin_handle;
473 AnjutaPluginDescription *desc;
474 char *str;
475 gchar *contents;
476 gboolean success = TRUE;
478 /* Load file content */
479 if (g_file_get_contents (plugin_desc_path, &contents, NULL, NULL)) {
481 desc = anjuta_plugin_description_new_from_string (contents, NULL);
482 g_free (contents);
483 if (!desc) {
484 g_warning ("Bad plugin file: %s\n", plugin_desc_path);
485 return NULL;
488 else
490 return NULL;
493 plugin_handle = g_object_new (ANJUTA_TYPE_PLUGIN_HANDLE, NULL);
495 /* Initialize plugin handle */
496 plugin_handle->priv->description = desc;
497 plugin_handle->priv->user_activatable = TRUE;
498 plugin_handle->priv->resident = TRUE;
499 plugin_handle->priv->path = g_path_get_dirname (plugin_desc_path);
501 if (anjuta_plugin_description_get_string (desc, "Anjuta Plugin",
502 "Location", &str)) {
503 plugin_handle->priv->id = str;
504 } else {
505 g_warning ("Couldn't find 'Location'");
506 success = FALSE;
509 if (anjuta_plugin_description_get_locale_string (desc, "Anjuta Plugin",
510 "Name", &str)) {
511 plugin_handle->priv->name = str;
512 } else {
513 g_warning ("couldn't find 'Name' attribute.");
514 success = FALSE;
517 if (anjuta_plugin_description_get_locale_string (desc, "Anjuta Plugin",
518 "Description", &str)) {
519 plugin_handle->priv->about = str;
520 } else {
521 g_warning ("Couldn't find 'Description' attribute.");
522 success = FALSE;
525 if (anjuta_plugin_description_get_string (desc, "Anjuta Plugin",
526 "Icon", &str)) {
527 plugin_handle->priv->icon_path = get_icon_path (str);
528 g_free (str);
531 if (anjuta_plugin_description_get_string (desc, "Anjuta Plugin",
532 "Dependencies",
533 &str)) {
534 plugin_handle->priv->dependency_names = property_to_list (str);
535 g_free (str);
538 if (anjuta_plugin_description_get_string (desc, "Anjuta Plugin",
539 "Interfaces",
540 &str)) {
541 plugin_handle->priv->interfaces = property_to_list (str);
542 g_free (str);
545 if (anjuta_plugin_description_get_string (desc, "Anjuta Plugin",
546 "UserActivatable", &str)) {
547 if (str && strcasecmp (str, "no") == 0)
549 plugin_handle->priv->user_activatable = FALSE;
551 DEBUG_PRINT ("Plugin '%s' is not user activatable",
552 plugin_handle->priv->name?
553 plugin_handle->priv->name : "Unknown");
556 g_free (str);
559 if (anjuta_plugin_description_get_string (desc, "Anjuta Plugin",
560 "Resident", &str)) {
561 if (str && strcasecmp (str, "no") == 0)
563 plugin_handle->priv->resident = FALSE;
565 g_free (str);
568 if (anjuta_plugin_description_get_string (desc, "Anjuta Plugin",
569 "Language", &str)) {
570 plugin_handle->priv->language = str;
573 if (!success) {
574 g_object_unref (plugin_handle);
575 plugin_handle = NULL;
578 return plugin_handle;
581 const char*
582 anjuta_plugin_handle_get_id (AnjutaPluginHandle *plugin_handle)
584 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle), NULL);
585 return plugin_handle->priv->id;
588 const char*
589 anjuta_plugin_handle_get_name (AnjutaPluginHandle *plugin_handle)
591 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle), NULL);
592 return plugin_handle->priv->name;
595 const char*
596 anjuta_plugin_handle_get_about (AnjutaPluginHandle *plugin_handle)
598 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle), NULL);
599 return _(plugin_handle->priv->about);
602 const char*
603 anjuta_plugin_handle_get_icon_path (AnjutaPluginHandle *plugin_handle)
605 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle), NULL);
606 return plugin_handle->priv->icon_path;
609 const char*
610 anjuta_plugin_handle_get_path (AnjutaPluginHandle *plugin_handle)
612 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle), NULL);
613 return plugin_handle->priv->path;
616 gboolean
617 anjuta_plugin_handle_get_user_activatable (AnjutaPluginHandle *plugin_handle)
619 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle), FALSE);
620 return plugin_handle->priv->user_activatable;
623 gboolean
624 anjuta_plugin_handle_get_resident (AnjutaPluginHandle *plugin_handle)
626 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle), FALSE);
627 return plugin_handle->priv->resident;
630 const char*
631 anjuta_plugin_handle_get_language (AnjutaPluginHandle *plugin_handle)
633 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle), NULL);
634 return plugin_handle->priv->language;
637 AnjutaPluginDescription*
638 anjuta_plugin_handle_get_description (AnjutaPluginHandle *plugin_handle)
640 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle), NULL);
641 return plugin_handle->priv->description;
644 GList*
645 anjuta_plugin_handle_get_dependency_names (AnjutaPluginHandle *plugin_handle)
647 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle), NULL);
648 return plugin_handle->priv->dependency_names;
651 GHashTable*
652 anjuta_plugin_handle_get_dependencies (AnjutaPluginHandle *plugin_handle)
654 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle), NULL);
655 return plugin_handle->priv->dependencies;
658 GHashTable*
659 anjuta_plugin_handle_get_dependents (AnjutaPluginHandle *plugin_handle)
661 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle), NULL);
662 return plugin_handle->priv->dependents;
665 GList*
666 anjuta_plugin_handle_get_interfaces (AnjutaPluginHandle *plugin_handle)
668 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle), NULL);
669 return plugin_handle->priv->interfaces;
672 gboolean
673 anjuta_plugin_handle_get_can_load (AnjutaPluginHandle *plugin_handle)
675 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle), FALSE);
676 return plugin_handle->priv->can_load;
679 gboolean
680 anjuta_plugin_handle_get_checked (AnjutaPluginHandle *plugin_handle)
682 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle), FALSE);
683 return plugin_handle->priv->checked;
686 gint
687 anjuta_plugin_handle_get_resolve_pass (AnjutaPluginHandle *plugin_handle)
689 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle), 0);
690 return plugin_handle->priv->resolve_pass;
693 void
694 anjuta_plugin_handle_set_can_load (AnjutaPluginHandle *plugin_handle,
695 gboolean can_load)
697 g_return_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle));
698 plugin_handle->priv->can_load = can_load;
701 void
702 anjuta_plugin_handle_set_checked (AnjutaPluginHandle *plugin_handle,
703 gboolean checked)
705 g_return_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle));
706 plugin_handle->priv->checked = checked;
709 void
710 anjuta_plugin_handle_set_resolve_pass (AnjutaPluginHandle *plugin_handle,
711 gboolean resolve_pass)
713 g_return_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle));
714 plugin_handle->priv->resolve_pass = resolve_pass;
717 static gboolean
718 g_hashtable_foreach_true (gpointer key, gpointer value, gpointer user_data)
720 return TRUE;
723 void
724 anjuta_plugin_handle_unresolve_dependencies (AnjutaPluginHandle *plugin_handle)
726 AnjutaPluginHandlePriv *priv;
728 g_return_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle));
729 priv = plugin_handle->priv;
731 g_hash_table_foreach_remove (priv->dependencies, g_hashtable_foreach_true,
732 NULL);
733 g_hash_table_foreach_remove (priv->dependents, g_hashtable_foreach_true,
734 NULL);
735 priv->can_load = TRUE;
736 priv->resolve_pass = -1;