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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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
,
59 struct _AnjutaPluginHandlePriv
65 gboolean user_activatable
;
69 AnjutaPluginDescription
*description
;
71 /* The dependencies listed in the oaf file */
72 GList
*dependency_names
;
74 /* Interfaces exported by this plugin */
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
;
88 /* The pass on which the module was resolved, or -1 if
93 static GObjectClass
* parent_class
= NULL
;
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
,
104 object
->priv
->dependents
= g_hash_table_new (g_direct_hash
,
109 anjuta_plugin_handle_finalize (GObject
*object
)
111 AnjutaPluginHandlePriv
*priv
;
113 priv
= ANJUTA_PLUGIN_HANDLE (object
)->priv
;
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
;
139 G_OBJECT_CLASS (parent_class
)->finalize (object
);
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
));
152 /* TODO: Add setter for "id" property here */
155 /* TODO: Add setter for "name" property here */
158 /* TODO: Add setter for "about" property here */
161 /* TODO: Add setter for "icon-path" property here */
163 case PROP_USER_ACTIVATABLE
:
164 /* TODO: Add setter for "user-activatable" property here */
167 /* TODO: Add setter for "resident" property here */
170 /* TODO: Add setter for "language" property here */
172 case PROP_DESCRIPTION
:
173 /* TODO: Add setter for "description" property here */
175 case PROP_DEPENDENCY_NAMES
:
176 /* TODO: Add setter for "dependency-names" property here */
178 case PROP_DEPENDENCIES
:
179 /* TODO: Add setter for "dependencies" property here */
181 case PROP_DEPENDENTS
:
182 /* TODO: Add setter for "dependents" property here */
184 case PROP_INTERFACES
:
185 /* TODO: Add setter for "interfaces" property here */
188 /* TODO: Add setter for "can-load" property here */
191 /* TODO: Add setter for "checked" property here */
193 case PROP_RESOLVE_PASS
:
194 /* TODO: Add setter for "resolve-pass" property here */
198 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
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
;
214 g_value_set_string (value
, priv
->id
);
217 g_value_set_string (value
, priv
->name
);
220 g_value_set_string (value
, priv
->about
);
223 g_value_set_string (value
, priv
->icon_path
);
225 case PROP_USER_ACTIVATABLE
:
226 g_value_set_boolean (value
, priv
->user_activatable
);
229 g_value_set_boolean (value
, priv
->resident
);
232 g_value_set_string (value
, priv
->language
);
234 case PROP_DESCRIPTION
:
235 g_value_set_pointer (value
, priv
->description
);
237 case PROP_DEPENDENCY_NAMES
:
238 g_value_set_pointer (value
, priv
->dependency_names
);
240 case PROP_DEPENDENCIES
:
241 g_value_set_pointer (value
, priv
->dependencies
);
243 case PROP_DEPENDENTS
:
244 g_value_set_pointer (value
, priv
->dependents
);
246 case PROP_INTERFACES
:
247 g_value_set_pointer (value
, priv
->interfaces
);
250 g_value_set_boolean (value
, priv
->can_load
);
253 g_value_set_boolean (value
, priv
->checked
);
255 case PROP_RESOLVE_PASS
:
256 g_value_set_int (value
, priv
->resolve_pass
);
259 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
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
,
276 g_param_spec_string ("id",
282 g_object_class_install_property (object_class
,
284 g_param_spec_string ("name",
290 g_object_class_install_property (object_class
,
292 g_param_spec_string ("about",
294 "About description of the plugin",
298 g_object_class_install_property (object_class
,
300 g_param_spec_string ("icon-path",
302 "Icon path of the plugin",
306 g_object_class_install_property (object_class
,
307 PROP_USER_ACTIVATABLE
,
308 g_param_spec_boolean ("user-activatable",
310 "If the plugin is user activatable",
314 g_object_class_install_property (object_class
,
316 g_param_spec_boolean ("resident",
318 "If the plugin cannot be unloaded",
322 g_object_class_install_property (object_class
,
324 g_param_spec_string ("language",
326 "Language used to write the plugin",
330 g_object_class_install_property (object_class
,
332 g_param_spec_pointer ("description",
334 "Plugin description",
337 g_object_class_install_property (object_class
,
338 PROP_DEPENDENCY_NAMES
,
339 g_param_spec_pointer ("dependency-names",
341 "Plugin dependency names listed in oaf file",
344 g_object_class_install_property (object_class
,
346 g_param_spec_pointer ("dependencies",
348 "Plugin dependencies",
351 g_object_class_install_property (object_class
,
353 g_param_spec_pointer ("dependents",
358 g_object_class_install_property (object_class
,
360 g_param_spec_pointer ("interfaces",
362 "Interfaces exported by the plugin",
365 g_object_class_install_property (object_class
,
367 g_param_spec_boolean ("can-load",
369 "If the plugin can be loaded",
373 g_object_class_install_property (object_class
,
375 g_param_spec_boolean ("checked",
377 "If the plugin is checked in UI",
381 g_object_class_install_property (object_class
,
383 g_param_spec_int ("resolve-pass",
385 "Dependency resolution pass",
386 G_MININT
, /* TODO: Adjust minimum property value */
387 G_MAXINT
, /* TODO: Adjust maximum property value */
393 anjuta_plugin_handle_get_type (void)
395 static GType 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 */
409 (GInstanceInitFunc
) anjuta_plugin_handle_init
, /* instance_init */
410 NULL
/* value_table */
413 our_type
= g_type_register_static (G_TYPE_OBJECT
, "AnjutaPluginHandle",
422 get_icon_path (char *icon_name
)
426 if (g_path_is_absolute (icon_name
)) {
427 ret
= g_strdup (icon_name
);
429 ret
= anjuta_res_get_pixmap_file (icon_name
);
436 property_to_list (const char *value
)
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
);
451 anjuta_plugin_handle_new (const gchar
*plugin_desc_path
)
453 AnjutaPluginHandle
*plugin_handle
;
454 AnjutaPluginDescription
*desc
;
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
);
465 g_warning ("Bad plugin file: %s\n", plugin_desc_path
);
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",
483 plugin_handle
->priv
->id
= str
;
485 g_warning ("Couldn't find 'Location'");
489 if (anjuta_plugin_description_get_string (desc
, "Anjuta Plugin",
491 plugin_handle
->priv
->name
= str
;
493 g_warning ("couldn't find 'Name' attribute.");
497 if (anjuta_plugin_description_get_string (desc
, "Anjuta Plugin",
498 "Description", &str
)) {
499 plugin_handle
->priv
->about
= str
;
501 g_warning ("Couldn't find 'Description' attribute.");
505 if (anjuta_plugin_description_get_string (desc
, "Anjuta Plugin",
507 plugin_handle
->priv
->icon_path
= get_icon_path (str
);
511 if (anjuta_plugin_description_get_string (desc
, "Anjuta Plugin",
514 plugin_handle
->priv
->dependency_names
= property_to_list (str
);
518 if (anjuta_plugin_description_get_string (desc
, "Anjuta Plugin",
521 plugin_handle
->priv
->interfaces
= property_to_list (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");
539 if (anjuta_plugin_description_get_string (desc
, "Anjuta Plugin",
541 if (str
&& strcasecmp (str
, "no") == 0)
543 plugin_handle
->priv
->resident
= FALSE
;
548 if (anjuta_plugin_description_get_string (desc
, "Anjuta Plugin",
550 plugin_handle
->priv
->language
= str
;
554 g_object_unref (plugin_handle
);
555 plugin_handle
= NULL
;
558 return plugin_handle
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
667 anjuta_plugin_handle_set_can_load (AnjutaPluginHandle
*plugin_handle
,
670 g_return_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle
));
671 plugin_handle
->priv
->can_load
= can_load
;
675 anjuta_plugin_handle_set_checked (AnjutaPluginHandle
*plugin_handle
,
678 g_return_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle
));
679 plugin_handle
->priv
->checked
= checked
;
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
;
691 g_hashtable_foreach_true (gpointer key
, gpointer value
, gpointer user_data
)
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
,
706 g_hash_table_foreach_remove (priv
->dependents
, g_hashtable_foreach_true
,
708 priv
->can_load
= TRUE
;
709 priv
->resolve_pass
= -1;