[geary/mjog/user-plugins: 6/26] Plugins: Support loading optional plugins



commit 0c526f66448360f6c4aa737d0e4aefd61d2c0feb
Author: Michael Gratton <mike vee net>
Date:   Mon Mar 2 12:08:31 2020 +1100

    Plugins: Support loading optional plugins
    
    Add optional-plugins GSetting, automatically load any plugins specified
    there at startup, and allow getting, loading and unloading optional
    plugins via Application.PluginManager.

 desktop/org.gnome.Geary.gschema.xml                |  6 +++
 .../application/application-configuration.vala     | 15 ++++++
 .../application/application-plugin-manager.vala    | 61 ++++++++++++++++++++++
 3 files changed, 82 insertions(+)
---
diff --git a/desktop/org.gnome.Geary.gschema.xml b/desktop/org.gnome.Geary.gschema.xml
index e23e26a9..ac477a43 100644
--- a/desktop/org.gnome.Geary.gschema.xml
+++ b/desktop/org.gnome.Geary.gschema.xml
@@ -141,6 +141,12 @@
         be displayed.</description>
     </key>
 
+    <key name="optional-plugins" type="as">
+      <default>[]</default>
+      <summary>List of optional plugins</summary>
+      <description>Plugins listed here will be loaded on startup.</description>
+    </key>
+
     <key name="migrated-config" type="b">
         <default>false</default>
         <summary>Whether we migrated the old settings</summary>
diff --git a/src/client/application/application-configuration.vala 
b/src/client/application/application-configuration.vala
index 6cce6a7d..170c98ee 100644
--- a/src/client/application/application-configuration.vala
+++ b/src/client/application/application-configuration.vala
@@ -25,6 +25,7 @@ public class Application.Configuration : Geary.BaseObject {
     public const string FOLDER_LIST_PANE_POSITION_VERTICAL_KEY = "folder-list-pane-position-vertical";
     public const string FORMATTING_TOOLBAR_VISIBLE = "formatting-toolbar-visible";
     public const string MESSAGES_PANE_POSITION_KEY = "messages-pane-position";
+    public const string OPTIONAL_PLUGINS = "optional-plugins";
     public const string SEARCH_STRATEGY_KEY = "search-strategy";
     public const string SINGLE_KEY_SHORTCUTS = "single-key-shortcuts";
     public const string SPELL_CHECK_LANGUAGES = "spell-check-languages";
@@ -204,6 +205,20 @@ public class Application.Configuration : Geary.BaseObject {
         this.settings.set_value(COMPOSER_WINDOW_SIZE_KEY, value);
     }
 
+    /**
+     * Returns list of optional plugins to load by default
+     */
+    public string[] get_optional_plugins() {
+        return this.settings.get_strv(OPTIONAL_PLUGINS);
+    }
+
+    /**
+     * Sets the list of optional plugins to load by default
+     */
+    public void set_optional_plugins(string[] value) {
+        this.settings.set_strv(OPTIONAL_PLUGINS, value);
+    }
+
     /**
      * Returns enabled spell checker languages.
      *
diff --git a/src/client/application/application-plugin-manager.vala 
b/src/client/application/application-plugin-manager.vala
index ffcc256d..fd2c7caf 100644
--- a/src/client/application/application-plugin-manager.vala
+++ b/src/client/application/application-plugin-manager.vala
@@ -47,6 +47,7 @@ public class Application.PluginManager : GLib.Object {
                 }
             });
 
+        string[] optional_names = application.config.get_optional_plugins();
         foreach (Peas.PluginInfo info in this.engine.get_plugin_list()) {
             string name = info.get_module_name();
             try {
@@ -55,6 +56,9 @@ public class Application.PluginManager : GLib.Object {
                         info.get_module_dir().has_prefix(builtin_path)) {
                         debug("Loading built-in plugin: %s", name);
                         this.engine.load_plugin(info);
+                    } else if (name in optional_names) {
+                        debug("Loading optional plugin: %s", name);
+                        this.engine.load_plugin(info);
                     }
                 }
             } catch (GLib.Error err) {
@@ -63,4 +67,61 @@ public class Application.PluginManager : GLib.Object {
         }
     }
 
+    public Gee.List<Peas.PluginInfo> get_optional_plugins() {
+        var plugins = new Gee.LinkedList<Peas.PluginInfo>();
+        foreach (Peas.PluginInfo plugin in this.engine.get_plugin_list()) {
+            try {
+                plugin.is_available();
+                if (!plugin.is_builtin()) {
+                    plugins.add(plugin);
+                }
+            } catch (GLib.Error err) {
+                warning(
+                    "Plugin %s not available: %s",
+                    plugin.get_module_name(), err.message
+                );
+            }
+        }
+        return plugins;
+    }
+
+    public bool load_optional(Peas.PluginInfo plugin) throws GLib.Error {
+        bool loaded = false;
+        if (plugin.is_available() &&
+            !plugin.is_loaded() &&
+            !plugin.is_builtin()) {
+            this.engine.load_plugin(plugin);
+            loaded = true;
+            string name = plugin.get_module_name();
+            string[] optional_names =
+                this.application.config.get_optional_plugins();
+            if (!(name in optional_names)) {
+                optional_names += name;
+                this.application.config.set_optional_plugins(optional_names);
+            }
+        }
+        return loaded;
+    }
+
+    public bool unload_optional(Peas.PluginInfo plugin) throws GLib.Error {
+        bool unloaded = false;
+        if (plugin.is_available() &&
+            plugin.is_loaded() &&
+            !plugin.is_builtin()) {
+            this.engine.unload_plugin(plugin);
+            unloaded = true;
+            string name = plugin.get_module_name();
+            string[] old_names =
+                this.application.config.get_optional_plugins();
+            string[] new_names = new string[0];
+            for (int i = 0; i < old_names.length; i++) {
+                if (old_names[i] != name) {
+                    new_names += old_names[i];
+                }
+            }
+            this.application.config.set_optional_plugins(new_names);
+        }
+        return unloaded;
+    }
+
 }


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