1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
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-profile
23 * @short_description: Profile is a collection of plugins
24 * @see_also: #AnjutaProfileManager, #AnjutaPlugin
25 * @stability: Unstable
26 * @include: libanjuta/anjuta-profile.h
28 * A anjuta profile contains the list of all plugins used in one Anjuta session.
29 * It is possible to add and remove plugins,
30 * check if one is included or get the whole list. The plugins list can be saved
31 * into a xml file and loaded from it.
33 * A profile in an Anjuta session includes plugins from up to 3 different xml
37 * <term>$prefix/share/anjuta/profiles/default.profile</term>
40 * This contains the system plugins. It is loaded in every profile and
41 * contains mandatory plugins for Anjuta. These plugins cannot be
47 * <term>$project_dir/$project_name.anjuta</term>
50 * This contains the project plugins. It lists mandatory plugins for the
51 * project. This file is version controlled and distributed with the source
52 * code. Every user working on the project uses the same one. If there
53 * is no project loaded, no project plugins are loaded.
58 * <term>$project_dir/.anjuta/default.profile</term>
61 * This contains the user plugins. This is the only list of plugins
62 * which is updated when the user add or remove one plugin.
63 * If there is no project loaded, the user home directory is used
64 * instead of the project directory but this list is used only in this case.
65 * There is no global user plugins list.
72 #include <glib/gi18n.h>
75 #include <libxml/parser.h>
76 #include <libxml/tree.h>
78 #include "anjuta-profile.h"
79 #include "anjuta-marshal.h"
80 #include "anjuta-debug.h"
99 struct _AnjutaProfilePriv
102 AnjutaPluginManager
*plugin_manager
;
104 GHashTable
*plugins_hash
;
105 GHashTable
*plugins_to_exclude_from_sync
;
109 static GObjectClass
* parent_class
= NULL
;
110 static guint profile_signals
[LAST_SIGNAL
] = { 0 };
113 anjuta_profile_error_quark (void)
115 static GQuark quark
= 0;
118 quark
= g_quark_from_static_string ("anjuta-profile-quark");
125 anjuta_profile_init (AnjutaProfile
*object
)
127 object
->priv
= g_new0 (AnjutaProfilePriv
, 1);
128 object
->priv
->plugins_hash
= g_hash_table_new (g_direct_hash
,
130 object
->priv
->plugins_to_exclude_from_sync
=
131 g_hash_table_new (g_direct_hash
, g_direct_equal
);
135 anjuta_profile_finalize (GObject
*object
)
137 AnjutaProfilePriv
*priv
= ANJUTA_PROFILE (object
)->priv
;
140 g_list_free (priv
->plugins
);
141 g_hash_table_destroy (priv
->plugins_hash
);
142 g_hash_table_destroy (priv
->plugins_to_exclude_from_sync
);
144 G_OBJECT_CLASS (parent_class
)->finalize (object
);
148 anjuta_profile_set_property (GObject
*object
, guint prop_id
,
149 const GValue
*value
, GParamSpec
*pspec
)
151 AnjutaProfilePriv
*priv
= ANJUTA_PROFILE (object
)->priv
;
153 g_return_if_fail (ANJUTA_IS_PROFILE (object
));
157 case PROP_PLUGIN_MANAGER
:
158 priv
->plugin_manager
= g_value_get_object (value
);
160 case PROP_PROFILE_NAME
:
161 g_return_if_fail (g_value_get_string (value
) != NULL
);
163 priv
->name
= g_strdup (g_value_get_string (value
));
165 case PROP_PROFILE_PLUGINS
:
167 g_list_free (priv
->plugins
);
168 if (g_value_get_pointer (value
))
169 priv
->plugins
= g_list_copy (g_value_get_pointer (value
));
171 priv
->plugins
= NULL
;
175 g_object_unref (priv
->sync_file
);
176 priv
->sync_file
= g_value_dup_object (value
);
179 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
185 anjuta_profile_get_property (GObject
*object
, guint prop_id
,
186 GValue
*value
, GParamSpec
*pspec
)
188 AnjutaProfilePriv
*priv
= ANJUTA_PROFILE (object
)->priv
;
190 g_return_if_fail (ANJUTA_IS_PROFILE (object
));
194 case PROP_PLUGIN_MANAGER
:
195 g_value_set_object (value
, priv
->plugin_manager
);
197 case PROP_PROFILE_NAME
:
198 g_value_set_string (value
, priv
->name
);
200 case PROP_PROFILE_PLUGINS
:
201 g_value_set_pointer (value
, priv
->plugins
);
204 g_value_set_object (value
, priv
->sync_file
);
207 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
213 anjuta_profile_plugin_added (AnjutaProfile
*self
,
214 AnjutaPluginDescription
*plugin
)
219 anjuta_profile_plugin_removed (AnjutaProfile
*self
,
220 AnjutaPluginDescription
*plugin
)
225 anjuta_profile_changed (AnjutaProfile
*self
, GList
*plugins
)
227 GError
*error
= NULL
;
228 anjuta_profile_sync (self
, &error
);
231 g_warning ("Failed to synchronize plugins profile '%s': %s",
232 self
->priv
->name
, error
->message
);
233 g_error_free (error
);
238 anjuta_profile_class_init (AnjutaProfileClass
*klass
)
240 GObjectClass
* object_class
= G_OBJECT_CLASS (klass
);
241 parent_class
= G_OBJECT_CLASS (g_type_class_peek_parent (klass
));
243 object_class
->finalize
= anjuta_profile_finalize
;
244 object_class
->set_property
= anjuta_profile_set_property
;
245 object_class
->get_property
= anjuta_profile_get_property
;
247 klass
->plugin_added
= anjuta_profile_plugin_added
;
248 klass
->plugin_removed
= anjuta_profile_plugin_removed
;
249 klass
->changed
= anjuta_profile_changed
;
251 g_object_class_install_property (object_class
,
253 g_param_spec_object ("plugin-manager",
255 _("The plugin manager to use for resolving plugins"),
256 ANJUTA_TYPE_PLUGIN_MANAGER
,
260 g_object_class_install_property (object_class
,
262 g_param_spec_string ("profile-name",
264 _("Name of the plugin profile"),
269 g_object_class_install_property (object_class
,
270 PROP_PROFILE_PLUGINS
,
271 g_param_spec_pointer ("plugins",
272 _("Profile Plugins"),
273 _("List of plugins for this profile"),
277 g_object_class_install_property (object_class
,
279 g_param_spec_object ("sync-file",
280 _("Synchronization file"),
281 _("File to syncronize the profile XML"),
288 * AnjutaProfile::plugin-added:
289 * @profile: a #AnjutaProfile object.
290 * @plugin: the new plugin as a #AnjutaPluginDescription.
292 * Emitted when a plugin is added in the list.
294 profile_signals
[PLUGIN_ADDED
] =
295 g_signal_new ("plugin-added",
296 G_OBJECT_CLASS_TYPE (klass
),
298 G_STRUCT_OFFSET (AnjutaProfileClass
, plugin_added
),
300 anjuta_cclosure_marshal_VOID__POINTER
,
305 * AnjutaProfile::plugin-removed:
306 * @profile: a #AnjutaProfile object.
307 * @plugin: the removed plugin as a #AnjutaPluginDescription.
309 * Emitted when a plugin is removed from the list.
311 profile_signals
[PLUGIN_REMOVED
] =
312 g_signal_new ("plugin-removed",
313 G_OBJECT_CLASS_TYPE (klass
),
315 G_STRUCT_OFFSET (AnjutaProfileClass
, plugin_removed
),
317 anjuta_cclosure_marshal_VOID__POINTER
,
322 * AnjutaProfile::changed:
323 * @profile: a #AnjutaProfile object.
324 * @plugin_list: the new plugins list.
326 * Emitted when a plugin is added or removed from the list.
328 profile_signals
[CHANGED
] =
329 g_signal_new ("changed",
330 G_OBJECT_CLASS_TYPE (klass
),
332 G_STRUCT_OFFSET (AnjutaProfileClass
, changed
),
334 anjuta_cclosure_marshal_VOID__POINTER
,
340 anjuta_profile_get_type (void)
342 static GType our_type
= 0;
346 static const GTypeInfo our_info
=
348 sizeof (AnjutaProfileClass
), /* class_size */
349 (GBaseInitFunc
) NULL
, /* base_init */
350 (GBaseFinalizeFunc
) NULL
, /* base_finalize */
351 (GClassInitFunc
) anjuta_profile_class_init
, /* class_init */
352 (GClassFinalizeFunc
) NULL
, /* class_finalize */
353 NULL
/* class_data */,
354 sizeof (AnjutaProfile
), /* instance_size */
356 (GInstanceInitFunc
) anjuta_profile_init
, /* instance_init */
357 NULL
/* value_table */
360 our_type
= g_type_register_static (G_TYPE_OBJECT
, "AnjutaProfile",
368 * anjuta_profile_new:
369 * @name: the new profile name.
370 * @plugin_manager: the #AnjutaPluginManager used by this profile.
372 * Create a new profile.
374 * Return value: the new #AnjutaProfile object.
377 anjuta_profile_new (const gchar
* name
, AnjutaPluginManager
*plugin_manager
)
380 profile
= g_object_new (ANJUTA_TYPE_PROFILE
, "profile-name", name
,
381 "plugin-manager", plugin_manager
, NULL
);
382 return ANJUTA_PROFILE (profile
);
386 * anjuta_profile_get_name:
387 * @profile: a #AnjutaProfile object.
389 * Get the profile name.
391 * Return value: the profile name.
394 anjuta_profile_get_name (AnjutaProfile
*profile
)
396 AnjutaProfilePriv
*priv
;
397 g_return_val_if_fail (ANJUTA_IS_PROFILE (profile
), NULL
);
398 priv
= ANJUTA_PROFILE (profile
)->priv
;
403 * anjuta_profile_add_plugin:
404 * @profile: a #AnjutaProfile object.
405 * @plugin: a #AnjutaPluginDescription.
407 * Add one plugin into the profile plugin list.
410 anjuta_profile_add_plugin (AnjutaProfile
*profile
,
411 AnjutaPluginDescription
*plugin
)
413 AnjutaProfilePriv
*priv
;
414 g_return_if_fail (ANJUTA_IS_PROFILE (profile
));
415 g_return_if_fail (plugin
!= NULL
);
416 priv
= ANJUTA_PROFILE (profile
)->priv
;
417 if (priv
->plugins
== NULL
|| g_list_find (priv
->plugins
, plugin
) == NULL
)
419 priv
->plugins
= g_list_prepend (priv
->plugins
, plugin
);
420 g_signal_emit_by_name (profile
, "plugin-added", plugin
);
421 g_signal_emit_by_name (profile
, "changed", priv
->plugins
);
426 * anjuta_profile_remove_plugin:
427 * @profile: a #AnjutaProfile object.
428 * @plugin: a #AnjutaPluginDescription.
430 * Remove one plugin from the profile plugin list.
433 anjuta_profile_remove_plugin (AnjutaProfile
*profile
,
434 AnjutaPluginDescription
*plugin
)
436 AnjutaProfilePriv
*priv
;
437 g_return_if_fail (ANJUTA_IS_PROFILE (profile
));
438 g_return_if_fail (plugin
!= NULL
);
439 priv
= ANJUTA_PROFILE (profile
)->priv
;
440 if (priv
->plugins
&& g_list_find (priv
->plugins
, plugin
) != NULL
)
442 priv
->plugins
= g_list_remove (priv
->plugins
, plugin
);
443 g_signal_emit_by_name (profile
, "plugin-removed", plugin
);
444 g_signal_emit_by_name (profile
, "changed", priv
->plugins
);
449 * anjuta_profile_has_plugin:
450 * @profile: a #AnjutaProfile object
451 * @plugin: a #AnjutaPluginDescription
453 * Check if a plugin is included in the profile plugin list.
455 * Return value: TRUE if the plugin is included in the list.
458 anjuta_profile_has_plugin (AnjutaProfile
*profile
,
459 AnjutaPluginDescription
*plugin
)
461 AnjutaProfilePriv
*priv
;
462 g_return_val_if_fail (ANJUTA_IS_PROFILE (profile
), FALSE
);
463 g_return_val_if_fail (plugin
!= NULL
, FALSE
);
464 priv
= ANJUTA_PROFILE (profile
)->priv
;
465 return (priv
->plugins
!= NULL
&&
466 g_list_find (priv
->plugins
, plugin
) != NULL
);
470 * anjuta_profile_get_plugins:
471 * @profile: a #AnjutaProfile object.
473 * Get the profile current plugins list.
475 * Return value: the plugins list.
478 anjuta_profile_get_plugins (AnjutaProfile
*profile
)
480 AnjutaProfilePriv
*priv
;
481 g_return_val_if_fail (ANJUTA_IS_PROFILE (profile
), FALSE
);
482 priv
= ANJUTA_PROFILE (profile
)->priv
;
483 return priv
->plugins
;
487 anjuta_profile_select_plugins (AnjutaProfile
*profile
,
490 GList
*selected_plugins
= NULL
;
491 GList
*node
= descs_list
;
492 AnjutaProfilePriv
*priv
;
494 priv
= profile
->priv
;
498 GList
*descs
= node
->data
;
499 if (g_list_length (descs
) == 1)
501 selected_plugins
= g_list_prepend (selected_plugins
, descs
->data
);
505 AnjutaPluginDescription
* d
;
506 d
= anjuta_plugin_manager_select (priv
->plugin_manager
,
507 _("Select a plugin"),
508 _("Please select a plugin from the list"),
511 selected_plugins
= g_list_prepend (selected_plugins
, d
);
513 node
= g_list_next (node
);
515 return g_list_reverse (selected_plugins
);
519 anjuta_profile_read_plugins_from_xml (AnjutaProfile
*profile
,
526 GList
*descs_list
= NULL
;
527 GList
*not_found_names
= NULL
;
528 GList
*not_found_urls
= NULL
;
529 gboolean parse_error
;
532 if (!g_file_load_contents (file
, NULL
, &read_buf
, &size
, NULL
, error
))
539 xml_doc
= xmlParseMemory (read_buf
, size
);
545 xml_root
= xmlDocGetRootElement(xml_doc
);
548 xmlStrEqual(xml_root
->name
, (const xmlChar
*)"anjuta"))
553 for (xml_node
= xml_root
->xmlChildrenNode
; xml_node
; xml_node
= xml_node
->next
)
555 GList
*groups
= NULL
;
556 GList
*attribs
= NULL
;
557 GList
*values
= NULL
;
558 xmlChar
*name
, *url
, *mandatory_text
;
559 xmlNodePtr xml_require_node
;
562 if (!xml_node
->name
||
563 !xmlStrEqual (xml_node
->name
, (const xmlChar
*)"plugin"))
568 name
= xmlGetProp (xml_node
, (const xmlChar
*)"name");
569 url
= xmlGetProp (xml_node
, (const xmlChar
*)"url");
571 /* Ensure that both name is given */
574 g_warning ("XML error: Plugin name should be present in plugin tag");
579 url
= xmlCharStrdup ("http://anjuta.org/plugins/");
581 /* Check if the plugin is mandatory */
582 mandatory_text
= xmlGetProp (xml_node
, (const xmlChar
*)"mandatory");
583 mandatory
= mandatory_text
&& (xmlStrcasecmp (mandatory_text
, (const xmlChar
*)"yes") == 0);
584 xmlFree(mandatory_text
);
586 /* For all plugin attribute conditions */
587 for (xml_require_node
= xml_node
->xmlChildrenNode
;
589 xml_require_node
= xml_require_node
->next
)
595 if (!xml_require_node
->name
||
596 !xmlStrEqual (xml_require_node
->name
,
597 (const xmlChar
*)"require"))
601 group
= xmlGetProp (xml_require_node
,
602 (const xmlChar
*)"group");
603 attrib
= xmlGetProp(xml_require_node
,
604 (const xmlChar
*)"attribute");
605 value
= xmlGetProp(xml_require_node
,
606 (const xmlChar
*)"value");
608 if (group
&& attrib
&& value
)
610 groups
= g_list_prepend (groups
, group
);
611 attribs
= g_list_prepend (attribs
, attrib
);
612 values
= g_list_prepend (values
, value
);
616 if (group
) xmlFree (group
);
617 if (attrib
) xmlFree (attrib
);
618 if (value
) xmlFree (value
);
620 g_warning ("XML parse error: group, attribute and value should be defined in require");
627 if (g_list_length (groups
) == 0)
630 g_warning ("XML Error: No attributes to match given");
637 anjuta_plugin_manager_list_query (profile
->priv
->plugin_manager
,
643 descs_list
= g_list_prepend (descs_list
, plugin_descs
);
647 not_found_names
= g_list_prepend (not_found_names
, g_strdup ((const gchar
*)name
));
648 not_found_urls
= g_list_prepend (not_found_urls
, g_strdup ((const gchar
*)url
));
652 g_list_foreach (groups
, (GFunc
)xmlFree
, NULL
);
653 g_list_foreach (attribs
, (GFunc
)xmlFree
, NULL
);
654 g_list_foreach (values
, (GFunc
)xmlFree
, NULL
);
655 g_list_free (groups
);
656 g_list_free (attribs
);
657 g_list_free (values
);
667 /* Error during parsing */
668 gchar
*uri
= g_file_get_uri (file
);
670 g_set_error (error
, ANJUTA_PROFILE_ERROR
,
671 ANJUTA_PROFILE_ERROR_URI_READ_FAILED
,
672 _("Failed to read '%s': XML parse error. "
673 "Invalid or corrupted Anjuta plugins profile."),
677 g_list_foreach (descs_list
, (GFunc
)g_list_free
, NULL
);
678 g_list_free (descs_list
);
681 else if (not_found_names
)
684 * FIXME: Present a nice dialog box to promt the user to download
685 * the plugin from corresponding URLs, install them and proceed.
687 GList
*node_name
, *node_url
;
688 GString
*mesg
= g_string_new ("");
689 gchar
*uri
= g_file_get_uri (file
);
691 not_found_names
= g_list_reverse (not_found_names
);
692 not_found_urls
= g_list_reverse (not_found_urls
);
694 node_name
= not_found_names
;
695 node_url
= not_found_urls
;
698 /* <Pluginname>: Install it from <some location on the web> */
699 g_string_append_printf (mesg
, _("%s: Install it from '%s'\n"),
700 (char *)node_name
->data
,
701 (char*)node_url
->data
);
702 node_name
= g_list_next (node_name
);
703 node_url
= g_list_next (node_url
);
705 g_set_error (error
, ANJUTA_PROFILE_ERROR
,
706 ANJUTA_PROFILE_ERROR_URI_READ_FAILED
,
707 _("Failed to read '%s': Following mandatory plugins are missing:\n%s"),
710 g_string_free (mesg
, TRUE
);
712 g_list_foreach (descs_list
, (GFunc
)g_list_free
, NULL
);
713 g_list_free (descs_list
);
716 g_list_foreach (not_found_names
, (GFunc
)g_free
, NULL
);
717 g_list_free (not_found_names
);
718 g_list_foreach (not_found_urls
, (GFunc
)g_free
, NULL
);
719 g_list_free (not_found_urls
);
725 * anjuta_profile_add_plugins_from_xml:
726 * @profile: a #AnjutaProfile object.
727 * @profile_xml_file: xml file containing plugin list.
728 * @exclude_from_sync: TRUE if these plugins shouldn't be saved in user session.
729 * @error: error propagation and reporting.
731 * Add all plugins inscribed in the xml file into the profile plugin list.
733 * Return value: TRUE on success, FALSE otherwise.
736 anjuta_profile_add_plugins_from_xml (AnjutaProfile
*profile
,
737 GFile
* profile_xml_file
,
738 gboolean exclude_from_sync
,
741 AnjutaProfilePriv
*priv
;
742 GList
*descs_list
= NULL
;
744 g_return_val_if_fail (ANJUTA_IS_PROFILE (profile
), FALSE
);
746 priv
= profile
->priv
;
747 descs_list
= anjuta_profile_read_plugins_from_xml (profile
, profile_xml_file
, error
);
751 GList
*selected_plugins
= NULL
;
754 /* Now everything okay. Select the plugins */
755 descs_list
= g_list_reverse (descs_list
);
757 anjuta_profile_select_plugins (profile
, descs_list
);
758 g_list_foreach (descs_list
, (GFunc
)g_list_free
, NULL
);
759 g_list_free (descs_list
);
761 node
= selected_plugins
;
764 if (exclude_from_sync
)
766 g_hash_table_insert (priv
->plugins_to_exclude_from_sync
,
767 node
->data
, node
->data
);
770 /* Insure no duplicate plugins are added */
771 if (g_hash_table_lookup (priv
->plugins_hash
, node
->data
) == NULL
)
773 priv
->plugins
= g_list_append (priv
->plugins
, node
->data
);
774 g_hash_table_insert (priv
->plugins_hash
,
775 node
->data
, node
->data
);
777 node
= g_list_next (node
);
779 g_list_free (selected_plugins
);
782 return descs_list
!= NULL
;
786 * anjuta_profile_to_xml :
787 * @profile: a #AnjutaProfile object.
789 * Return a string in xml format containing the list of saved plugins.
791 * Return value: a newly-allocated string that must be freed with g_free().
794 anjuta_profile_to_xml (AnjutaProfile
*profile
)
798 AnjutaProfilePriv
*priv
;
800 g_return_val_if_fail (ANJUTA_IS_PROFILE (profile
), FALSE
);
801 priv
= profile
->priv
;
803 str
= g_string_new ("<?xml version=\"1.0\"?>\n<anjuta>\n");
804 for (node
= priv
->plugins
; node
!= NULL
; node
= g_list_next (node
))
806 AnjutaPluginDescription
*desc
;
807 gboolean user_activatable
= TRUE
;
808 gchar
*name
= NULL
, *plugin_id
= NULL
;
810 if (g_hash_table_lookup (priv
->plugins_to_exclude_from_sync
, node
->data
))
812 /* Do not save plugin in the exclude list */
816 desc
= (AnjutaPluginDescription
*)node
->data
;
817 if (anjuta_plugin_description_get_boolean (desc
, "Anjuta Plugin",
818 "UserActivatable", &user_activatable
)
819 && !user_activatable
)
821 /* Do not save plugins that are auto activated */
825 /* Do not use the _locale_ version because it's not in UI */
826 anjuta_plugin_description_get_string (desc
, "Anjuta Plugin",
828 DEBUG_PRINT("Saving plugin: %s", name
);
830 name
= g_strdup ("Unknown");
832 if (anjuta_plugin_description_get_string (desc
, "Anjuta Plugin",
833 "Location", &plugin_id
))
835 g_string_append (str
, " <plugin name=\"");
836 g_string_append (str
, name
);
837 g_string_append (str
, "\" mandatory=\"no\">\n");
838 g_string_append (str
, " <require group=\"Anjuta Plugin\"\n");
839 g_string_append (str
, " attribute=\"Location\"\n");
840 g_string_append (str
, " value=\"");
841 g_string_append (str
, plugin_id
);
842 g_string_append (str
, "\"/>\n");
843 g_string_append (str
, " </plugin>\n");
849 g_string_append (str
, "</anjuta>\n");
851 return g_string_free (str
, FALSE
);
855 * anjuta_profile_set_sync_file:
856 * @profile: a #AnjutaProfile object.
857 * @sync_file: file used to save profile.
859 * Define the file used to save plugins list.
863 anjuta_profile_set_sync_file (AnjutaProfile
*profile
, GFile
*sync_file
)
865 AnjutaProfilePriv
*priv
;
867 g_return_if_fail (ANJUTA_IS_PROFILE (profile
));
869 priv
= profile
->priv
;
872 g_object_unref (priv
->sync_file
);
873 priv
->sync_file
= sync_file
;
874 if (priv
->sync_file
);
875 g_object_ref (priv
->sync_file
);
879 * anjuta_profile_sync:
880 * @profile: a #AnjutaProfile object.
881 * @error: error propagation and reporting.
883 * Save the current plugins list in the xml file set with anjuta_profile_set_sync_file().
885 * Return value: TRUE on success, FALSE otherwise.
888 anjuta_profile_sync (AnjutaProfile
*profile
, GError
**error
)
892 AnjutaProfilePriv
*priv
;
893 GError
* file_error
= NULL
;
895 g_return_val_if_fail (ANJUTA_IS_PROFILE (profile
), FALSE
);
896 priv
= profile
->priv
;
898 if (!priv
->sync_file
)
901 xml_buffer
= anjuta_profile_to_xml (profile
);
902 ok
= g_file_replace_contents (priv
->sync_file
, xml_buffer
, strlen(xml_buffer
),
903 NULL
, FALSE
, G_FILE_CREATE_NONE
,
904 NULL
, NULL
, &file_error
);
905 if (!ok
&& g_error_matches (file_error
, G_IO_ERROR
, G_IO_ERROR_NOT_FOUND
))
907 /* Try to create parent directory */
908 GFile
* parent
= g_file_get_parent (priv
->sync_file
);
909 if (g_file_make_directory (parent
, NULL
, NULL
))
911 g_clear_error (&file_error
);
912 ok
= g_file_replace_contents (priv
->sync_file
, xml_buffer
, strlen(xml_buffer
),
913 NULL
, FALSE
, G_FILE_CREATE_NONE
,
914 NULL
, NULL
, &file_error
);
916 g_object_unref (parent
);
919 if (file_error
!= NULL
) g_propagate_error (error
, file_error
);