[anjuta] libanjuta: Always keep plugins in the system profile



commit 3fa86a67974e2ecfb6f7419f0585ba0815561c8b
Author: Sébastien Granjoux <seb sfo free fr>
Date:   Tue May 28 21:21:44 2013 +0200

    libanjuta: Always keep plugins in the system profile
    
    Previously the core plugins listed in /usr/share/anjuta/profiles/default.profile
    were added to every new profile. Now these plugins are put in a special system
    profile whose plugins are never deactivated.

 libanjuta/anjuta-plugin-handle.c   |   32 +++++++++++
 libanjuta/anjuta-plugin-handle.h   |    3 +
 libanjuta/anjuta-profile-manager.c |  106 ++++++++++++++----------------------
 libanjuta/anjuta-profile.c         |   12 ++++-
 libanjuta/anjuta-profile.h         |    8 +++
 plugins/project-manager/plugin.c   |   28 +---------
 src/anjuta-application.c           |   16 ++++--
 7 files changed, 110 insertions(+), 95 deletions(-)
---
diff --git a/libanjuta/anjuta-plugin-handle.c b/libanjuta/anjuta-plugin-handle.c
index 764b4d9..abc313b 100644
--- a/libanjuta/anjuta-plugin-handle.c
+++ b/libanjuta/anjuta-plugin-handle.c
@@ -53,6 +53,7 @@ enum
        PROP_DEPENDENTS,
        PROP_INTERFACES,
        PROP_CAN_LOAD,
+       PROP_CAN_UNLOAD,
        PROP_CHECKED,
        PROP_RESOLVE_PASS,
        PROP_PATH
@@ -86,6 +87,7 @@ struct _AnjutaPluginHandlePriv
        GHashTable *dependents;
        
        gboolean can_load;
+       gboolean can_unload;
        gboolean checked;
 
        /* The pass on which the module was resolved, or -1 if
@@ -101,6 +103,7 @@ anjuta_plugin_handle_init (AnjutaPluginHandle *object)
        object->priv = g_new0 (AnjutaPluginHandlePriv, 1);
 
        object->priv->resolve_pass = -1;
+       object->priv->can_unload = TRUE;
 
        object->priv->dependencies = g_hash_table_new (g_direct_hash, 
                                                                                                   
g_direct_equal);
@@ -195,6 +198,9 @@ anjuta_plugin_handle_set_property (GObject *object, guint prop_id,
        case PROP_CAN_LOAD:
                /* TODO: Add setter for "can-load" property here */
                break;
+       case PROP_CAN_UNLOAD:
+               /* TODO: Add setter for "can-unload" property here */
+               break;
        case PROP_CHECKED:
                /* TODO: Add setter for "checked" property here */
                break;
@@ -260,6 +266,9 @@ anjuta_plugin_handle_get_property (GObject *object, guint prop_id,
        case PROP_CAN_LOAD:
                g_value_set_boolean (value, priv->can_load);
                break;
+       case PROP_CAN_UNLOAD:
+               g_value_set_boolean (value, priv->can_unload);
+               break;
        case PROP_CHECKED:
                g_value_set_boolean (value, priv->checked);
                break;
@@ -390,6 +399,14 @@ anjuta_plugin_handle_class_init (AnjutaPluginHandleClass *klass)
                                                               G_PARAM_READABLE));
 
        g_object_class_install_property (object_class,
+                                        PROP_CAN_UNLOAD,
+                                        g_param_spec_boolean ("can-unload",
+                                                              "Can UnLoad",
+                                                              "If the plugin can be unloaded",
+                                                              TRUE,
+                                                              G_PARAM_READABLE));
+
+       g_object_class_install_property (object_class,
                                         PROP_CHECKED,
                                         g_param_spec_boolean ("checked",
                                                               "Checked",
@@ -674,6 +691,13 @@ anjuta_plugin_handle_get_can_load (AnjutaPluginHandle *plugin_handle)
 }
 
 gboolean
+anjuta_plugin_handle_get_can_unload (AnjutaPluginHandle *plugin_handle)
+{
+       g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle), FALSE);
+       return plugin_handle->priv->can_unload;
+}
+
+gboolean
 anjuta_plugin_handle_get_checked (AnjutaPluginHandle *plugin_handle)
 {
        g_return_val_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle), FALSE);
@@ -696,6 +720,14 @@ anjuta_plugin_handle_set_can_load (AnjutaPluginHandle *plugin_handle,
 }
 
 void
+anjuta_plugin_handle_set_can_unload (AnjutaPluginHandle *plugin_handle,
+                                                                  gboolean can_unload)
+{
+       g_return_if_fail (ANJUTA_IS_PLUGIN_HANDLE (plugin_handle));
+       plugin_handle->priv->can_unload = can_unload;
+}
+
+void
 anjuta_plugin_handle_set_checked (AnjutaPluginHandle *plugin_handle,
                                                                  gboolean checked)
 {
diff --git a/libanjuta/anjuta-plugin-handle.h b/libanjuta/anjuta-plugin-handle.h
index 90d4dd5..c545c31 100644
--- a/libanjuta/anjuta-plugin-handle.h
+++ b/libanjuta/anjuta-plugin-handle.h
@@ -64,10 +64,13 @@ GHashTable* anjuta_plugin_handle_get_dependencies (AnjutaPluginHandle *plugin_ha
 GHashTable* anjuta_plugin_handle_get_dependents (AnjutaPluginHandle *plugin_handle);
 GList* anjuta_plugin_handle_get_interfaces (AnjutaPluginHandle *plugin_handle);
 gboolean anjuta_plugin_handle_get_can_load (AnjutaPluginHandle *plugin_handle);
+gboolean anjuta_plugin_handle_get_can_unload (AnjutaPluginHandle *plugin_handle);
 gboolean anjuta_plugin_handle_get_checked (AnjutaPluginHandle *plugin_handle);
 gint anjuta_plugin_handle_get_resolve_pass (AnjutaPluginHandle *plugin_handle);
 void anjuta_plugin_handle_set_can_load (AnjutaPluginHandle *plugin_handle,
                                                                                gboolean can_load);
+void anjuta_plugin_handle_set_can_unload (AnjutaPluginHandle *plugin_handle,
+                                          gboolean can_unload);
 void anjuta_plugin_handle_set_checked (AnjutaPluginHandle *plugin_handle,
                                                                           gboolean checked);
 void anjuta_plugin_handle_set_resolve_pass (AnjutaPluginHandle *plugin_handle,
diff --git a/libanjuta/anjuta-profile-manager.c b/libanjuta/anjuta-profile-manager.c
index 35768de..bac1992 100644
--- a/libanjuta/anjuta-profile-manager.c
+++ b/libanjuta/anjuta-profile-manager.c
@@ -25,10 +25,11 @@
  * @stability: Unstable
  * @include: libanjuta/anjuta-profile-manager.h
  * 
- * Anjuta uses up to two profiles. A "no project" profile is used when no
- * project is loaded a project profile when one is loaded.
+ * Anjuta uses up to three profiles. A system profile which contains mandatory
+ * plugins which are never unloaded. A user profile is used when no project is
+ * loaded and a project profile when one is loaded.
  * If a second project is loaded, it is loaded in another instance of Anjuta.
- * When a project is closed, Anjuta goes back to the "no project" profile.
+ * When a project is closed, Anjuta goes back to the user profile.
  *
  * The profile manager can be in a frozen state where you can push or 
  * pop a profile from the stack without triggering a change of the profile.
@@ -240,15 +241,35 @@ anjuta_profile_manager_new (AnjutaPluginManager *plugin_manager)
 }
 
 static gboolean
-anjuta_profile_manager_load_profile (AnjutaProfileManager *profile_manager,
-                                                                        AnjutaProfile *profile,
-                                                                        AnjutaProfile *previous_profile,
-                                                                        GError **error)
+anjuta_profile_manager_load_profiles (AnjutaProfileManager *profile_manager)
 {
-       if (previous_profile != NULL) anjuta_profile_unload (previous_profile);
-       anjuta_profile_load (profile);
+       AnjutaProfileManagerPriv *priv;
+       gboolean loaded = FALSE;
+
+       priv = profile_manager->priv;
+
+       /* If there is no freeze load profile now */
+       while ((priv->freeze_count <= 0) && (priv->profiles_queue != NULL))
+       {
+               AnjutaProfile *previous_profile = NULL;
+               GList *node;
+
+               /* We need to load each profile one by one because a "system" profile
+                * contains plugins which are never unloaded. */
+               if (priv->profiles)
+                       previous_profile = priv->profiles->data;
+               node = g_list_last (priv->profiles_queue);
+               priv->profiles_queue = g_list_remove_link (priv->profiles_queue, node);
+               priv->profiles = g_list_concat (node, priv->profiles);
+
+               /* Load profile. Note that loading a profile can trigger the load of
+                * additional profile. Typically loading the default profile will
+                * trigger the load of the last project profile. */
+               if (previous_profile != NULL) anjuta_profile_unload (previous_profile);
+               loaded = anjuta_profile_load (ANJUTA_PROFILE (node->data));
+       }
 
-       return TRUE;
+       return loaded;
 }
 
 static gboolean
@@ -259,29 +280,11 @@ anjuta_profile_manager_queue_profile (AnjutaProfileManager *profile_manager,
        AnjutaProfileManagerPriv *priv;
        
        priv = profile_manager->priv;
-       priv->profiles_queue = g_list_prepend (priv->profiles_queue,
-                                                                                       profile);
+
+       priv->profiles_queue = g_list_prepend (priv->profiles_queue, profile);
+
        /* If there is no freeze load profile now */
-       if (priv->freeze_count <= 0)
-       {
-               AnjutaProfile *previous_profile = NULL;
-               
-               if (priv->profiles)
-                       previous_profile = priv->profiles->data;
-               
-               /* Push queued profiles in stack */
-               priv->profiles = g_list_concat (priv->profiles_queue, priv->profiles);
-               priv->profiles_queue = NULL;
-               
-               return anjuta_profile_manager_load_profile (profile_manager,
-                                                                               ANJUTA_PROFILE 
(priv->profiles->data),
-                                                                                                       
previous_profile,
-                                                                                                       
error);
-       }
-       else
-       {
-               return FALSE;
-       }
+       return anjuta_profile_manager_load_profiles (profile_manager);
 }
 
 /**
@@ -356,20 +359,13 @@ anjuta_profile_manager_pop (AnjutaProfileManager *profile_manager,
                                                           profile);
                
                /* Restore the next profile in the stack */
+               anjuta_profile_unload (profile);
+               g_object_unref (profile);
                if (priv->profiles)
                {
-                       return anjuta_profile_manager_load_profile (profile_manager,
-                                                                       ANJUTA_PROFILE (priv->profiles->data),
-                                                                                                             
  profile,
-                                                                                                             
  error);
-               }
-               else
-               {
-                       return anjuta_profile_manager_load_profile (profile_manager,
-                                                                                                             
  NULL, profile,
-                                                                                                             
  error);
+                       return anjuta_profile_load (ANJUTA_PROFILE (priv->profiles->data));
                }
-               g_object_unref (profile);
+               return TRUE;
        }
 
        return FALSE;
@@ -416,28 +412,8 @@ anjuta_profile_manager_thaw (AnjutaProfileManager *profile_manager,
 
        if (priv->freeze_count > 0)
                priv->freeze_count--;
-       
-       if (priv->freeze_count <= 0 && priv->profiles_queue)
-       {
-               AnjutaProfile *previous_profile = NULL;
-               
-               if (priv->profiles)
-                       previous_profile = priv->profiles->data;
-               
-               /* Push queued profiles in stack */
-               priv->profiles = g_list_concat (priv->profiles_queue, priv->profiles);
-               priv->profiles_queue = NULL;
-               
-               /* Load the profile */
-               return anjuta_profile_manager_load_profile (profile_manager,
-                                                                               ANJUTA_PROFILE 
(priv->profiles->data),
-                                                                                                       
previous_profile,
-                                                                                                       
error);
-       }
-       else
-       {
-               return FALSE;
-       }
+
+       return anjuta_profile_manager_load_profiles (profile_manager);
 }
 
 /**
diff --git a/libanjuta/anjuta-profile.c b/libanjuta/anjuta-profile.c
index 2627cf9..0fa83d9 100644
--- a/libanjuta/anjuta-profile.c
+++ b/libanjuta/anjuta-profile.c
@@ -1039,7 +1039,8 @@ anjuta_profile_load (AnjutaProfile *profile)
        while (node)
        {
                AnjutaPluginHandle *handle = (AnjutaPluginHandle *)node->data;
-               if (!g_hash_table_lookup (plugins_to_activate_hash, handle))
+               if (!g_hash_table_lookup (plugins_to_activate_hash, handle) &&
+                   anjuta_plugin_handle_get_can_unload (handle))
                {
                        plugins_to_deactivate = g_list_prepend (plugins_to_deactivate,
                                                                                                        
handle);
@@ -1083,6 +1084,15 @@ anjuta_profile_load (AnjutaProfile *profile)
                                                                                                
plugins_to_activate);
        }
 
+       /* For system profile, marks its plugin to keep them activated */
+       if (strcmp (priv->name, ANJUTA_SYSTEM_PROFILE_NAME) == 0)
+       {
+               for (node = g_list_first (plugins_to_activate); node != NULL; node = g_list_next (node))
+               {
+                       AnjutaPluginHandle *handle = (AnjutaPluginHandle *)node->data;
+                       anjuta_plugin_handle_set_can_unload (handle, FALSE);
+               }
+       }
        g_list_free (plugins_to_activate);
        g_list_free (active_plugins);
 
diff --git a/libanjuta/anjuta-profile.h b/libanjuta/anjuta-profile.h
index fc0d9bb..c8e6dc3 100644
--- a/libanjuta/anjuta-profile.h
+++ b/libanjuta/anjuta-profile.h
@@ -45,6 +45,14 @@ G_BEGIN_DECLS
 #define ANJUTA_PROFILE_ERROR            (anjuta_profile_error_quark())
 
 /**
+ * ANJUTA_SYSTEM_PROFILE_ERROR:
+ *
+ * Special name for a system profile. The content of such profile is never
+ * unloaded.
+ */
+#define ANJUTA_SYSTEM_PROFILE_NAME       "system"
+
+/**
  * AnjutaProfileError:
  * @ANJUTA_PROFILE_ERROR_URI_READ_FAILED: Fail to read xml plugins list file.
  * @ANJUTA_PROFILE_ERROR_URI_WRITE_FAILED: Fail to write xml plugins list file.
diff --git a/plugins/project-manager/plugin.c b/plugins/project-manager/plugin.c
index a0a510f..ceebd56 100644
--- a/plugins/project-manager/plugin.c
+++ b/plugins/project-manager/plugin.c
@@ -43,7 +43,7 @@
 #define UI_FILE PACKAGE_DATA_DIR "/ui/anjuta-project-manager.xml"
 #define PREFS_GLADE PACKAGE_DATA_DIR "/glade/anjuta-project-manager-plugin.ui"
 #define ICON_FILE "anjuta-project-manager-plugin-48.png"
-#define DEFAULT_PROFILE "file://"PACKAGE_DATA_DIR "/profiles/default.profile"
+#define DEFAULT_PROFILE "default.profile"
 #define PROJECT_PROFILE_NAME "project"
 
 #define INT_TO_GBOOLEAN(i) ((i) ? TRUE : FALSE)
@@ -1524,7 +1524,6 @@ project_manager_plugin_close (ProjectManagerPlugin *plugin)
 static gboolean
 project_manager_plugin_activate_plugin (AnjutaPlugin *plugin)
 {
-       AnjutaProfileManager *profile_manager;
        GtkWidget *scrolled_window;
        GtkWidget *view;
        static gboolean initialized = FALSE;
@@ -1630,7 +1629,6 @@ project_manager_plugin_activate_plugin (AnjutaPlugin *plugin)
                                          G_CALLBACK (on_session_save), plugin);
        g_signal_connect (G_OBJECT (plugin->shell), "load_session",
                                          G_CALLBACK (on_session_load), plugin);
-       profile_manager = anjuta_shell_get_profile_manager (plugin->shell, NULL);
 
 
        return TRUE;
@@ -1639,7 +1637,6 @@ project_manager_plugin_activate_plugin (AnjutaPlugin *plugin)
 static gboolean
 project_manager_plugin_deactivate_plugin (AnjutaPlugin *plugin)
 {
-       AnjutaProfileManager *profile_manager;
        ProjectManagerPlugin *pm_plugin;
        pm_plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (plugin);
 
@@ -1653,8 +1650,6 @@ project_manager_plugin_deactivate_plugin (AnjutaPlugin *plugin)
        if (pm_plugin->project_root_uri)
                project_manager_plugin_close (pm_plugin);
 
-       profile_manager = anjuta_shell_get_profile_manager (plugin->shell, NULL);
-
        /* Disconnect signals */
        g_signal_handlers_disconnect_by_func (G_OBJECT (plugin->shell),
                                                                                  G_CALLBACK 
(on_session_save),
@@ -2297,9 +2292,8 @@ ifile_open (IAnjutaFile *ifile, GFile* file, GError **e)
        AnjutaProfileManager *profile_manager;
        AnjutaPluginManager *plugin_manager;
        AnjutaStatus *status;
-       gchar *session_profile_path, *profile_name;
+       gchar *session_profile_path;
        GFile *session_profile;
-       GFile *default_profile;
        GFile *project_root;
        GFile *tmp;
        ProjectManagerPlugin *plugin;
@@ -2330,20 +2324,6 @@ ifile_open (IAnjutaFile *ifile, GFile* file, GError **e)
        /* Prepare profile */
        profile = anjuta_profile_new (PROJECT_PROFILE_NAME, plugin_manager);
 
-       /* System default profile */
-       default_profile = g_file_new_for_uri (DEFAULT_PROFILE);
-       anjuta_profile_add_plugins_from_xml (profile, default_profile,
-                                                                                TRUE, &error);
-       profile_name = g_file_get_basename (default_profile);
-       g_object_unref (default_profile);
-       if (error)
-       {
-               g_propagate_error (e, error);
-               g_free (profile_name);
-               g_object_unref (profile);
-
-               return;
-       }
        /* Connect to profile scoping */
        g_signal_connect (profile, "scoped", G_CALLBACK (on_profile_scoped), plugin);
        g_signal_connect (profile, "descoped", G_CALLBACK (on_profile_descoped), plugin);
@@ -2355,7 +2335,6 @@ ifile_open (IAnjutaFile *ifile, GFile* file, GError **e)
        {
                g_propagate_error (e, error);
 
-               g_free (profile_name);
                g_object_unref (profile);
 
                return;
@@ -2364,9 +2343,8 @@ ifile_open (IAnjutaFile *ifile, GFile* file, GError **e)
        /* Project session profile */
        project_root = g_file_get_parent (file);
        tmp = g_file_get_child (project_root, ".anjuta");
-       session_profile = g_file_get_child (tmp, profile_name);
+       session_profile = g_file_get_child (tmp, DEFAULT_PROFILE);
        g_object_unref (tmp);
-       g_free (profile_name);
 
        session_profile_path = g_file_get_path (session_profile);
        DEBUG_PRINT ("Loading project session profile: %s", session_profile_path);
diff --git a/src/anjuta-application.c b/src/anjuta-application.c
index 79c59b0..497dd7d 100644
--- a/src/anjuta-application.c
+++ b/src/anjuta-application.c
@@ -588,8 +588,8 @@ anjuta_application_create_window (AnjutaApplication *app)
                                                                                                          
remembered_plugins);
        g_free (remembered_plugins);
 
-       /* Prepare profile */
-       profile = anjuta_profile_new (USER_PROFILE_NAME, plugin_manager);
+       /* Prepare system profile */
+       profile = anjuta_profile_new (ANJUTA_SYSTEM_PROFILE_NAME, plugin_manager);
        session_profile = g_file_new_for_uri (DEFAULT_PROFILE);
        anjuta_profile_add_plugins_from_xml (profile, session_profile,
                                                                                 TRUE, &error);
@@ -600,8 +600,17 @@ anjuta_application_create_window (AnjutaApplication *app)
                error = NULL;
        }
        g_object_unref (session_profile);
+       anjuta_profile_manager_freeze (profile_manager);
+       anjuta_profile_manager_push (profile_manager, profile, &error);
+       if (error)
+       {
+               anjuta_util_dialog_error (GTK_WINDOW (win), "%s", error->message);
+               g_error_free (error);
+               error = NULL;
+       }
 
-       /* Load user session profile */
+       /* Prepare user profile */
+       profile = anjuta_profile_new (USER_PROFILE_NAME, plugin_manager);
        profile_name = g_path_get_basename (DEFAULT_PROFILE);
        session_profile = anjuta_util_get_user_cache_file (profile_name, NULL);
        if (g_file_query_exists (session_profile, NULL))
@@ -620,7 +629,6 @@ anjuta_application_create_window (AnjutaApplication *app)
        g_free (profile_name);
 
        /* Load profile */
-       anjuta_profile_manager_freeze (profile_manager);
        anjuta_profile_manager_push (profile_manager, profile, &error);
        if (error)
        {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]