1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
3 * anjuta-plugin-handle.c
4 * Copyright (C) Naba Kumar <naba@gnome.org>
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
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.
34 #include <glib/gi18n.h>
35 #include "anjuta-plugin-handle.h"
36 #include "resources.h"
37 #include "anjuta-debug.h"
47 PROP_USER_ACTIVATABLE
,
51 PROP_DEPENDENCY_NAMES
,
61 struct _AnjutaPluginHandlePriv
68 gboolean user_activatable
;
72 AnjutaPluginDescription
*description
;
74 /* The dependencies listed in the oaf file */
75 GList
*dependency_names
;
77 /* Interfaces exported by this plugin */
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
;
91 /* The pass on which the module was resolved, or -1 if
96 static GObjectClass
* parent_class
= NULL
;
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
,
107 object
->priv
->dependents
= g_hash_table_new (g_direct_hash
,
112 anjuta_plugin_handle_finalize (GObject
*object
)
114 AnjutaPluginHandlePriv
*priv
;
116 priv
= ANJUTA_PLUGIN_HANDLE (object
)->priv
;
122 g_free (priv
->icon_path
);
123 priv
->icon_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
;
144 G_OBJECT_CLASS (parent_class
)->finalize (object
);
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
));
157 /* TODO: Add setter for "id" property here */
160 /* TODO: Add setter for "name" property here */
163 /* TODO: Add setter for "about" property here */
166 /* TODO: Add setter for "icon-path" property here */
169 /* TODO: Add setter for "path" property here */
171 case PROP_USER_ACTIVATABLE
:
172 /* TODO: Add setter for "user-activatable" property here */
175 /* TODO: Add setter for "resident" property here */
178 /* TODO: Add setter for "language" property here */
180 case PROP_DESCRIPTION
:
181 /* TODO: Add setter for "description" property here */
183 case PROP_DEPENDENCY_NAMES
:
184 /* TODO: Add setter for "dependency-names" property here */
186 case PROP_DEPENDENCIES
:
187 /* TODO: Add setter for "dependencies" property here */
189 case PROP_DEPENDENTS
:
190 /* TODO: Add setter for "dependents" property here */
192 case PROP_INTERFACES
:
193 /* TODO: Add setter for "interfaces" property here */
196 /* TODO: Add setter for "can-load" property here */
199 /* TODO: Add setter for "checked" property here */
201 case PROP_RESOLVE_PASS
:
202 /* TODO: Add setter for "resolve-pass" property here */
206 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
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
;
222 g_value_set_string (value
, priv
->id
);
225 g_value_set_string (value
, priv
->name
);
228 g_value_set_string (value
, priv
->about
);
231 g_value_set_string (value
, priv
->icon_path
);
234 g_value_set_string (value
, priv
->path
);
236 case PROP_USER_ACTIVATABLE
:
237 g_value_set_boolean (value
, priv
->user_activatable
);
240 g_value_set_boolean (value
, priv
->resident
);
243 g_value_set_string (value
, priv
->language
);
245 case PROP_DESCRIPTION
:
246 g_value_set_pointer (value
, priv
->description
);
248 case PROP_DEPENDENCY_NAMES
:
249 g_value_set_pointer (value
, priv
->dependency_names
);
251 case PROP_DEPENDENCIES
:
252 g_value_set_pointer (value
, priv
->dependencies
);
254 case PROP_DEPENDENTS
:
255 g_value_set_pointer (value
, priv
->dependents
);
257 case PROP_INTERFACES
:
258 g_value_set_pointer (value
, priv
->interfaces
);
261 g_value_set_boolean (value
, priv
->can_load
);
264 g_value_set_boolean (value
, priv
->checked
);
266 case PROP_RESOLVE_PASS
:
267 g_value_set_int (value
, priv
->resolve_pass
);
270 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
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
,
287 g_param_spec_string ("id",
293 g_object_class_install_property (object_class
,
295 g_param_spec_string ("name",
301 g_object_class_install_property (object_class
,
303 g_param_spec_string ("about",
305 "About description of the plugin",
309 g_object_class_install_property (object_class
,
311 g_param_spec_string ("icon-path",
313 "Icon path of the plugin",
317 g_object_class_install_property (object_class
,
319 g_param_spec_string ("path",
321 "Path of the plugin",
325 g_object_class_install_property (object_class
,
326 PROP_USER_ACTIVATABLE
,
327 g_param_spec_boolean ("user-activatable",
329 "If the plugin is user activatable",
333 g_object_class_install_property (object_class
,
335 g_param_spec_boolean ("resident",
337 "If the plugin cannot be unloaded",
341 g_object_class_install_property (object_class
,
343 g_param_spec_string ("language",
345 "Language used to write the plugin",
349 g_object_class_install_property (object_class
,
351 g_param_spec_pointer ("description",
353 "Plugin description",
356 g_object_class_install_property (object_class
,
357 PROP_DEPENDENCY_NAMES
,
358 g_param_spec_pointer ("dependency-names",
360 "Plugin dependency names listed in oaf file",
363 g_object_class_install_property (object_class
,
365 g_param_spec_pointer ("dependencies",
367 "Plugin dependencies",
370 g_object_class_install_property (object_class
,
372 g_param_spec_pointer ("dependents",
377 g_object_class_install_property (object_class
,
379 g_param_spec_pointer ("interfaces",
381 "Interfaces exported by the plugin",
384 g_object_class_install_property (object_class
,
386 g_param_spec_boolean ("can-load",
388 "If the plugin can be loaded",
392 g_object_class_install_property (object_class
,
394 g_param_spec_boolean ("checked",
396 "If the plugin is checked in UI",
400 g_object_class_install_property (object_class
,
402 g_param_spec_int ("resolve-pass",
404 "Dependency resolution pass",
405 G_MININT
, /* TODO: Adjust minimum property value */
406 G_MAXINT
, /* TODO: Adjust maximum property value */
412 anjuta_plugin_handle_get_type (void)
414 static GType 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 */
428 (GInstanceInitFunc
) anjuta_plugin_handle_init
, /* instance_init */
429 NULL
/* value_table */
432 our_type
= g_type_register_static (G_TYPE_OBJECT
, "AnjutaPluginHandle",
441 get_icon_path (char *icon_name
)
445 if (g_path_is_absolute (icon_name
)) {
446 ret
= g_strdup (icon_name
);
448 ret
= anjuta_res_get_pixmap_file (icon_name
);
455 property_to_list (const char *value
)
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
);
470 anjuta_plugin_handle_new (const gchar
*plugin_desc_path
)
472 AnjutaPluginHandle
*plugin_handle
;
473 AnjutaPluginDescription
*desc
;
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
);
484 g_warning ("Bad plugin file: %s\n", plugin_desc_path
);
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",
503 plugin_handle
->priv
->id
= str
;
505 g_warning ("Couldn't find 'Location'");
509 if (anjuta_plugin_description_get_locale_string (desc
, "Anjuta Plugin",
511 plugin_handle
->priv
->name
= str
;
513 g_warning ("couldn't find 'Name' attribute.");
517 if (anjuta_plugin_description_get_locale_string (desc
, "Anjuta Plugin",
518 "Description", &str
)) {
519 plugin_handle
->priv
->about
= str
;
521 g_warning ("Couldn't find 'Description' attribute.");
525 if (anjuta_plugin_description_get_string (desc
, "Anjuta Plugin",
527 plugin_handle
->priv
->icon_path
= get_icon_path (str
);
531 if (anjuta_plugin_description_get_string (desc
, "Anjuta Plugin",
534 plugin_handle
->priv
->dependency_names
= property_to_list (str
);
538 if (anjuta_plugin_description_get_string (desc
, "Anjuta Plugin",
541 plugin_handle
->priv
->interfaces
= property_to_list (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");
559 if (anjuta_plugin_description_get_string (desc
, "Anjuta Plugin",
561 if (str
&& strcasecmp (str
, "no") == 0)
563 plugin_handle
->priv
->resident
= FALSE
;
568 if (anjuta_plugin_description_get_string (desc
, "Anjuta Plugin",
570 plugin_handle
->priv
->language
= str
;
574 g_object_unref (plugin_handle
);
575 plugin_handle
= NULL
;
578 return plugin_handle
;
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
;
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
;
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
);
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
694 anjuta_plugin_handle_set_can_load (AnjutaPluginHandle
*plugin_handle
,
697 g_return_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle
));
698 plugin_handle
->priv
->can_load
= can_load
;
702 anjuta_plugin_handle_set_checked (AnjutaPluginHandle
*plugin_handle
,
705 g_return_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle
));
706 plugin_handle
->priv
->checked
= checked
;
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
;
718 g_hashtable_foreach_true (gpointer key
, gpointer value
, gpointer user_data
)
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
,
733 g_hash_table_foreach_remove (priv
->dependents
, g_hashtable_foreach_true
,
735 priv
->can_load
= TRUE
;
736 priv
->resolve_pass
= -1;