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 "anjuta-plugin-handle.h"
35 #include "resources.h"
36 #include "anjuta-debug.h"
46 PROP_USER_ACTIVATABLE
,
50 PROP_DEPENDENCY_NAMES
,
60 struct _AnjutaPluginHandlePriv
67 gboolean user_activatable
;
71 AnjutaPluginDescription
*description
;
73 /* The dependencies listed in the oaf file */
74 GList
*dependency_names
;
76 /* Interfaces exported by this plugin */
79 /* Attributes defined for this plugin */
80 /* GHashTable *attributes; */
82 /* The keys of these tables represent the dependencies and dependents
83 * of the module. The values point back at the plugins */
84 GHashTable
*dependencies
;
85 GHashTable
*dependents
;
90 /* The pass on which the module was resolved, or -1 if
95 static GObjectClass
* parent_class
= NULL
;
98 anjuta_plugin_handle_init (AnjutaPluginHandle
*object
)
100 object
->priv
= g_new0 (AnjutaPluginHandlePriv
, 1);
102 object
->priv
->resolve_pass
= -1;
104 object
->priv
->dependencies
= g_hash_table_new (g_direct_hash
,
106 object
->priv
->dependents
= g_hash_table_new (g_direct_hash
,
111 anjuta_plugin_handle_finalize (GObject
*object
)
113 AnjutaPluginHandlePriv
*priv
;
115 priv
= ANJUTA_PLUGIN_HANDLE (object
)->priv
;
121 g_free (priv
->icon_path
);
122 priv
->icon_path
= NULL
;
125 g_free (priv
->language
);
126 priv
->language
= NULL
;
128 g_list_foreach (priv
->dependency_names
, (GFunc
)g_free
, NULL
);
129 g_list_free (priv
->dependency_names
);
130 priv
->dependency_names
= NULL
;
132 g_list_foreach (priv
->interfaces
, (GFunc
)g_free
, NULL
);
133 g_list_free (priv
->dependency_names
);
134 priv
->dependency_names
= NULL
;
136 g_hash_table_destroy (priv
->dependencies
);
137 priv
->dependencies
= NULL
;
138 g_hash_table_destroy (priv
->dependents
);
139 priv
->dependents
= NULL
;
143 G_OBJECT_CLASS (parent_class
)->finalize (object
);
147 anjuta_plugin_handle_set_property (GObject
*object
, guint prop_id
,
148 const GValue
*value
, GParamSpec
*pspec
)
150 g_return_if_fail (ANJUTA_IS_PLUGIN_HANDLE (object
));
156 /* TODO: Add setter for "id" property here */
159 /* TODO: Add setter for "name" property here */
162 /* TODO: Add setter for "about" property here */
165 /* TODO: Add setter for "icon-path" property here */
168 /* TODO: Add setter for "path" property here */
170 case PROP_USER_ACTIVATABLE
:
171 /* TODO: Add setter for "user-activatable" property here */
174 /* TODO: Add setter for "resident" property here */
177 /* TODO: Add setter for "language" property here */
179 case PROP_DESCRIPTION
:
180 /* TODO: Add setter for "description" property here */
182 case PROP_DEPENDENCY_NAMES
:
183 /* TODO: Add setter for "dependency-names" property here */
185 case PROP_DEPENDENCIES
:
186 /* TODO: Add setter for "dependencies" property here */
188 case PROP_DEPENDENTS
:
189 /* TODO: Add setter for "dependents" property here */
191 case PROP_INTERFACES
:
192 /* TODO: Add setter for "interfaces" property here */
195 /* TODO: Add setter for "can-load" property here */
198 /* TODO: Add setter for "checked" property here */
200 case PROP_RESOLVE_PASS
:
201 /* TODO: Add setter for "resolve-pass" property here */
205 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
211 anjuta_plugin_handle_get_property (GObject
*object
, guint prop_id
,
212 GValue
*value
, GParamSpec
*pspec
)
214 AnjutaPluginHandlePriv
*priv
;
216 g_return_if_fail (ANJUTA_IS_PLUGIN_HANDLE (object
));
217 priv
= ANJUTA_PLUGIN_HANDLE (object
)->priv
;
221 g_value_set_string (value
, priv
->id
);
224 g_value_set_string (value
, priv
->name
);
227 g_value_set_string (value
, priv
->about
);
230 g_value_set_string (value
, priv
->icon_path
);
233 g_value_set_string (value
, priv
->path
);
235 case PROP_USER_ACTIVATABLE
:
236 g_value_set_boolean (value
, priv
->user_activatable
);
239 g_value_set_boolean (value
, priv
->resident
);
242 g_value_set_string (value
, priv
->language
);
244 case PROP_DESCRIPTION
:
245 g_value_set_pointer (value
, priv
->description
);
247 case PROP_DEPENDENCY_NAMES
:
248 g_value_set_pointer (value
, priv
->dependency_names
);
250 case PROP_DEPENDENCIES
:
251 g_value_set_pointer (value
, priv
->dependencies
);
253 case PROP_DEPENDENTS
:
254 g_value_set_pointer (value
, priv
->dependents
);
256 case PROP_INTERFACES
:
257 g_value_set_pointer (value
, priv
->interfaces
);
260 g_value_set_boolean (value
, priv
->can_load
);
263 g_value_set_boolean (value
, priv
->checked
);
265 case PROP_RESOLVE_PASS
:
266 g_value_set_int (value
, priv
->resolve_pass
);
269 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
275 anjuta_plugin_handle_class_init (AnjutaPluginHandleClass
*klass
)
277 GObjectClass
* object_class
= G_OBJECT_CLASS (klass
);
278 parent_class
= G_OBJECT_CLASS (g_type_class_peek_parent (klass
));
280 object_class
->finalize
= anjuta_plugin_handle_finalize
;
281 object_class
->set_property
= anjuta_plugin_handle_set_property
;
282 object_class
->get_property
= anjuta_plugin_handle_get_property
;
284 g_object_class_install_property (object_class
,
286 g_param_spec_string ("id",
292 g_object_class_install_property (object_class
,
294 g_param_spec_string ("name",
300 g_object_class_install_property (object_class
,
302 g_param_spec_string ("about",
304 "About description of the plugin",
308 g_object_class_install_property (object_class
,
310 g_param_spec_string ("icon-path",
312 "Icon path of the plugin",
316 g_object_class_install_property (object_class
,
318 g_param_spec_string ("path",
320 "Path of the plugin",
324 g_object_class_install_property (object_class
,
325 PROP_USER_ACTIVATABLE
,
326 g_param_spec_boolean ("user-activatable",
328 "If the plugin is user activatable",
332 g_object_class_install_property (object_class
,
334 g_param_spec_boolean ("resident",
336 "If the plugin cannot be unloaded",
340 g_object_class_install_property (object_class
,
342 g_param_spec_string ("language",
344 "Language used to write the plugin",
348 g_object_class_install_property (object_class
,
350 g_param_spec_pointer ("description",
352 "Plugin description",
355 g_object_class_install_property (object_class
,
356 PROP_DEPENDENCY_NAMES
,
357 g_param_spec_pointer ("dependency-names",
359 "Plugin dependency names listed in oaf file",
362 g_object_class_install_property (object_class
,
364 g_param_spec_pointer ("dependencies",
366 "Plugin dependencies",
369 g_object_class_install_property (object_class
,
371 g_param_spec_pointer ("dependents",
376 g_object_class_install_property (object_class
,
378 g_param_spec_pointer ("interfaces",
380 "Interfaces exported by the plugin",
383 g_object_class_install_property (object_class
,
385 g_param_spec_boolean ("can-load",
387 "If the plugin can be loaded",
391 g_object_class_install_property (object_class
,
393 g_param_spec_boolean ("checked",
395 "If the plugin is checked in UI",
399 g_object_class_install_property (object_class
,
401 g_param_spec_int ("resolve-pass",
403 "Dependency resolution pass",
404 G_MININT
, /* TODO: Adjust minimum property value */
405 G_MAXINT
, /* TODO: Adjust maximum property value */
411 anjuta_plugin_handle_get_type (void)
413 static GType our_type
= 0;
417 static const GTypeInfo our_info
=
419 sizeof (AnjutaPluginHandleClass
), /* class_size */
420 (GBaseInitFunc
) NULL
, /* base_init */
421 (GBaseFinalizeFunc
) NULL
, /* base_finalize */
422 (GClassInitFunc
) anjuta_plugin_handle_class_init
, /* class_init */
423 (GClassFinalizeFunc
) NULL
, /* class_finalize */
424 NULL
/* class_data */,
425 sizeof (AnjutaPluginHandle
), /* instance_size */
427 (GInstanceInitFunc
) anjuta_plugin_handle_init
, /* instance_init */
428 NULL
/* value_table */
431 our_type
= g_type_register_static (G_TYPE_OBJECT
, "AnjutaPluginHandle",
440 get_icon_path (char *icon_name
)
444 if (g_path_is_absolute (icon_name
)) {
445 ret
= g_strdup (icon_name
);
447 ret
= anjuta_res_get_pixmap_file (icon_name
);
454 property_to_list (const char *value
)
460 split_str
= g_strsplit (value
, ",", -1);
461 for (p
= split_str
; *p
!= NULL
; p
++) {
462 l
= g_list_prepend (l
, g_strdup (g_strstrip (*p
)));
464 g_strfreev (split_str
);
469 anjuta_plugin_handle_new (const gchar
*plugin_desc_path
)
471 AnjutaPluginHandle
*plugin_handle
;
472 AnjutaPluginDescription
*desc
;
475 gboolean success
= TRUE
;
477 /* Load file content */
478 if (g_file_get_contents (plugin_desc_path
, &contents
, NULL
, NULL
)) {
480 desc
= anjuta_plugin_description_new_from_string (contents
, NULL
);
483 g_warning ("Bad plugin file: %s\n", plugin_desc_path
);
492 plugin_handle
= g_object_new (ANJUTA_TYPE_PLUGIN_HANDLE
, NULL
);
494 /* Initialize plugin handle */
495 plugin_handle
->priv
->description
= desc
;
496 plugin_handle
->priv
->user_activatable
= TRUE
;
497 plugin_handle
->priv
->resident
= TRUE
;
498 plugin_handle
->priv
->path
= g_path_get_dirname (plugin_desc_path
);
500 if (anjuta_plugin_description_get_string (desc
, "Anjuta Plugin",
502 plugin_handle
->priv
->id
= str
;
504 g_warning ("Couldn't find 'Location'");
508 if (anjuta_plugin_description_get_string (desc
, "Anjuta Plugin",
510 plugin_handle
->priv
->name
= str
;
512 g_warning ("couldn't find 'Name' attribute.");
516 if (anjuta_plugin_description_get_string (desc
, "Anjuta Plugin",
517 "Description", &str
)) {
518 plugin_handle
->priv
->about
= str
;
520 g_warning ("Couldn't find 'Description' attribute.");
524 if (anjuta_plugin_description_get_string (desc
, "Anjuta Plugin",
526 plugin_handle
->priv
->icon_path
= get_icon_path (str
);
530 if (anjuta_plugin_description_get_string (desc
, "Anjuta Plugin",
533 plugin_handle
->priv
->dependency_names
= property_to_list (str
);
537 if (anjuta_plugin_description_get_string (desc
, "Anjuta Plugin",
540 plugin_handle
->priv
->interfaces
= property_to_list (str
);
544 if (anjuta_plugin_description_get_string (desc
, "Anjuta Plugin",
545 "UserActivatable", &str
)) {
546 if (str
&& strcasecmp (str
, "no") == 0)
548 plugin_handle
->priv
->user_activatable
= FALSE
;
550 DEBUG_PRINT ("Plugin '%s' is not user activatable",
551 plugin_handle->priv->name?
552 plugin_handle->priv->name : "Unknown");
558 if (anjuta_plugin_description_get_string (desc
, "Anjuta Plugin",
560 if (str
&& strcasecmp (str
, "no") == 0)
562 plugin_handle
->priv
->resident
= FALSE
;
567 if (anjuta_plugin_description_get_string (desc
, "Anjuta Plugin",
569 plugin_handle
->priv
->language
= str
;
573 g_object_unref (plugin_handle
);
574 plugin_handle
= NULL
;
577 return plugin_handle
;
581 anjuta_plugin_handle_get_id (AnjutaPluginHandle
*plugin_handle
)
583 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle
), NULL
);
584 return plugin_handle
->priv
->id
;
588 anjuta_plugin_handle_get_name (AnjutaPluginHandle
*plugin_handle
)
590 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle
), NULL
);
591 return plugin_handle
->priv
->name
;
595 anjuta_plugin_handle_get_about (AnjutaPluginHandle
*plugin_handle
)
597 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle
), NULL
);
598 return plugin_handle
->priv
->about
;
602 anjuta_plugin_handle_get_icon_path (AnjutaPluginHandle
*plugin_handle
)
604 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle
), NULL
);
605 return plugin_handle
->priv
->icon_path
;
609 anjuta_plugin_handle_get_path (AnjutaPluginHandle
*plugin_handle
)
611 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle
), NULL
);
612 return plugin_handle
->priv
->path
;
616 anjuta_plugin_handle_get_user_activatable (AnjutaPluginHandle
*plugin_handle
)
618 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle
), FALSE
);
619 return plugin_handle
->priv
->user_activatable
;
623 anjuta_plugin_handle_get_resident (AnjutaPluginHandle
*plugin_handle
)
625 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle
), FALSE
);
626 return plugin_handle
->priv
->resident
;
630 anjuta_plugin_handle_get_language (AnjutaPluginHandle
*plugin_handle
)
632 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle
), NULL
);
633 return plugin_handle
->priv
->language
;
636 AnjutaPluginDescription
*
637 anjuta_plugin_handle_get_description (AnjutaPluginHandle
*plugin_handle
)
639 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle
), NULL
);
640 return plugin_handle
->priv
->description
;
644 anjuta_plugin_handle_get_dependency_names (AnjutaPluginHandle
*plugin_handle
)
646 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle
), NULL
);
647 return plugin_handle
->priv
->dependency_names
;
651 anjuta_plugin_handle_get_dependencies (AnjutaPluginHandle
*plugin_handle
)
653 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle
), NULL
);
654 return plugin_handle
->priv
->dependencies
;
658 anjuta_plugin_handle_get_dependents (AnjutaPluginHandle
*plugin_handle
)
660 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle
), NULL
);
661 return plugin_handle
->priv
->dependents
;
665 anjuta_plugin_handle_get_interfaces (AnjutaPluginHandle
*plugin_handle
)
667 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle
), NULL
);
668 return plugin_handle
->priv
->interfaces
;
672 anjuta_plugin_handle_get_can_load (AnjutaPluginHandle
*plugin_handle
)
674 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle
), FALSE
);
675 return plugin_handle
->priv
->can_load
;
679 anjuta_plugin_handle_get_checked (AnjutaPluginHandle
*plugin_handle
)
681 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle
), FALSE
);
682 return plugin_handle
->priv
->checked
;
686 anjuta_plugin_handle_get_resolve_pass (AnjutaPluginHandle
*plugin_handle
)
688 g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle
), 0);
689 return plugin_handle
->priv
->resolve_pass
;
693 anjuta_plugin_handle_set_can_load (AnjutaPluginHandle
*plugin_handle
,
696 g_return_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle
));
697 plugin_handle
->priv
->can_load
= can_load
;
701 anjuta_plugin_handle_set_checked (AnjutaPluginHandle
*plugin_handle
,
704 g_return_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle
));
705 plugin_handle
->priv
->checked
= checked
;
709 anjuta_plugin_handle_set_resolve_pass (AnjutaPluginHandle
*plugin_handle
,
710 gboolean resolve_pass
)
712 g_return_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle
));
713 plugin_handle
->priv
->resolve_pass
= resolve_pass
;
717 g_hashtable_foreach_true (gpointer key
, gpointer value
, gpointer user_data
)
723 anjuta_plugin_handle_unresolve_dependencies (AnjutaPluginHandle
*plugin_handle
)
725 AnjutaPluginHandlePriv
*priv
;
727 g_return_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle
));
728 priv
= plugin_handle
->priv
;
730 g_hash_table_foreach_remove (priv
->dependencies
, g_hashtable_foreach_true
,
732 g_hash_table_foreach_remove (priv
->dependents
, g_hashtable_foreach_true
,
734 priv
->can_load
= TRUE
;
735 priv
->resolve_pass
= -1;