46
45
public class PluginManager
48
public static readonly string DefaultPluginIcon = "package";
48
/// The default icon for addins that don't supply one.
50
public static string DefaultPluginIcon {
50
const string PluginsDirectory = "plugins";
51
const string ApplicationDirectory = "docky";
52
const string DefaultAddinsDirectory = "addins";
56
public static Dictionary<Addin, Dictionary<string, string>> AddinMetadata { get; private set; }
54
58
const string IPExtensionPath = "/Docky/ItemProvider";
55
59
const string ConfigExtensionPath = "/Docky/Configuration";
60
64
/// Directory where Docky saves its Mono.Addins repository cache.
62
public static string UserPluginsDirectory {
64
string userData = Environment.GetFolderPath (Environment.SpecialFolder.LocalApplicationData);
65
return Path.Combine (Path.Combine (userData, ApplicationDirectory), PluginsDirectory);
66
public static GLib.File UserPluginsDirectory {
67
get { return DockServices.Paths.UserDataFolder.GetChild ("plugins"); }
69
public static string UserAddinInstallationDirectory {
70
get { return Path.Combine (UserPluginsDirectory, DefaultAddinsDirectory); }
71
/// Directory where Docky saves Addin files.
73
public static GLib.File UserAddinInstallationDirectory {
74
get { return UserPluginsDirectory.GetChild ("addins"); }
74
78
/// Performs plugin system initialization. Should be called before this
75
79
/// class or any Mono.Addins class is used. The ordering is very delicate.
79
83
// Initialize Mono.Addins.
81
AddinManager.Initialize (UserPluginsDirectory);
85
AddinManager.Initialize (UserPluginsDirectory.Path);
82
86
} catch (InvalidOperationException e) {
83
87
Log<PluginManager>.Error ("AddinManager.Initialize: {0}", e.Message);
84
88
Log<PluginManager>.Warn ("Rebuild Addin.Registry and reinitialize AddinManager");
85
89
AddinManager.Registry.Rebuild (null);
86
90
AddinManager.Shutdown ();
87
AddinManager.Initialize (UserPluginsDirectory);
91
AddinManager.Initialize (UserPluginsDirectory.Path);
90
94
AddinManager.Registry.Update (null);
96
// parse the addin config files for extended metadata
97
AddinMetadata = new Dictionary<Addin, Dictionary<string, string>> ();
98
DockServices.System.RunOnThread (() => {
99
AllAddins.ToList ().ForEach (a => ParseAddinConfig (a));
92
102
// Add feedback when addin is loaded or unloaded
93
103
AddinManager.AddinLoaded += AddinManagerAddinLoaded;
94
104
AddinManager.AddinUnloaded += AddinManagerAddinUnloaded;
121
134
Log<PluginManager>.Info ("Unloaded \"{0}\".", addin.Name);
138
/// Look up an addin by supplying the Addin ID.
140
/// <param name="id">
141
/// A <see cref="System.String"/>
144
/// A <see cref="Addin"/>
124
146
public static Addin AddinFromID (string id)
126
148
return AddinManager.Registry.GetAddin (id);
152
/// Enable the addin by supplying the Addin ID.
154
/// <param name="addin">
155
/// A <see cref="Addin"/>
158
/// A <see cref="AbstractDockItemProvider"/>
129
160
public static AbstractDockItemProvider Enable (Addin addin)
131
162
addin.Enabled = true;
132
163
return ItemProviderFromAddin (addin.Id);
167
/// Enable the addin by supplying the <see cref="AbstractDockItemProvider"/>.
169
/// <param name="id">
170
/// A <see cref="System.String"/>
173
/// A <see cref="AbstractDockItemProvider"/>
135
175
public static AbstractDockItemProvider Enable (string id)
137
177
return Enable (AddinFromID (id));
181
/// Disable the Addin by supplying the <see cref="Addin"/>.
183
/// <param name="addin">
184
/// A <see cref="Addin"/>
140
186
public static void Disable (Addin addin)
142
188
addin.Enabled = false;
192
/// Disable the addin by supplying the Addin ID.
194
/// <param name="id">
195
/// A <see cref="System.String"/>
145
197
public static void Disable (string id)
147
199
Disable (AddinFromID (id));
203
/// Disable an addin by supplying the <see cref="AbstractDockItemProvider"/>.
205
/// <param name="provider">
206
/// A <see cref="AbstractDockItemProvider"/>
150
208
public static void Disable (AbstractDockItemProvider provider)
152
210
Disable (AddinIDFromProvider (provider));
214
/// All addins in the Addins registry.
155
216
public static IEnumerable<Addin> AllAddins {
157
218
return AddinManager.Registry.GetAddins ();
222
/// Installs all addins from the user addin directory.
161
224
public static void InstallLocalPlugins ()
163
226
IEnumerable<string> manual;
165
manual = Directory.GetFiles (UserAddinInstallationDirectory, "*.dll")
166
.Select (s => Path.GetFileName (s));
228
manual = UserAddinInstallationDirectory.GetFiles ("*.dll").Select (f => f.Basename);
168
230
manual.ToList ().ForEach (dll => Log<PluginManager>.Info ("Installing {0}", dll));
249
/// Returns the <see cref="AbstractDockItemProvider"/> from the supplied Addin ID.
251
/// <param name="addinID">
252
/// A <see cref="System.String"/>
255
/// A <see cref="AbstractDockItemProvider"/>
186
257
public static AbstractDockItemProvider ItemProviderFromAddin (string addinID)
188
259
return ObjectFromAddin<AbstractDockItemProvider> (IPExtensionPath, addinID);
263
/// Returns the <see cref="ConfigDialog"/> from the supplied Addin ID.
265
/// <param name="addinID">
266
/// A <see cref="System.String"/>
269
/// A <see cref="ConfigDialog"/>
191
271
public static ConfigDialog ConfigForAddin (string addinID)
193
273
return ObjectFromAddin<ConfigDialog> (ConfigExtensionPath, addinID);
277
/// Returns the Addin ID from an <see cref="AbstractDockItemProvider"/>.
279
/// <param name="provider">
280
/// A <see cref="AbstractDockItemProvider"/>
283
/// A <see cref="System.String"/>
196
285
public static string AddinIDFromProvider (AbstractDockItemProvider provider)
198
287
foreach (TypeExtensionNode node in AddinManager.GetExtensionNodes (IPExtensionPath)) {
216
305
/// All loaded ItemProviders.
218
307
public static IEnumerable<AbstractDockItemProvider> ItemProviders {
219
get { return AddinManager.GetExtensionObjects (IPExtensionPath).OfType<AbstractDockItemProvider> (); }
309
return AddinManager.GetExtensionObjects (IPExtensionPath).OfType<AbstractDockItemProvider> ();
222
// this will return a list of Provider IDs that are currently not used by any docks
314
/// A list of Provider IDs that are currently not used by any docks
223
316
public static IEnumerable<string> AvailableProviderIDs {
225
return AllAddins .Where (a => !a.Enabled).Select (a => Addin.GetIdName (a.Id));
318
return AllAddins.Where (a => !a.Enabled).Select (a => Addin.GetIdName (a.Id));
322
static void ParseAddinConfig (Addin addin)
324
Log<PluginManager>.Debug ("Processing config file for \"{0}\".", addin.Name);
325
Assembly addinAssembly = Assembly.LoadFile (addin.AddinFile);
327
string addinManifestName = addinAssembly.GetManifestResourceNames ().FirstOrDefault (res => res.Contains ("addin.xml"));
329
if (string.IsNullOrEmpty (addinManifestName)) {
330
Log<PluginManager>.Warn ("Could not find addin manifest for '{0}'.", addin.AddinFile);
334
using (Stream s = addinAssembly.GetManifestResourceStream (addinManifestName)) {
335
XmlDocument addinManifest = new XmlDocument ();
336
addinManifest.Load (s);
338
if (!AddinMetadata.ContainsKey (addin))
339
AddinMetadata[addin] = new Dictionary<string, string> ();
341
foreach (XmlAttribute a in addinManifest.SelectSingleNode ("/Addin").Attributes)
342
AddinMetadata [addin] [a.Name] = a.Value;
345
AddinMetadata [addin] ["AssemblyFullName"] = addinAssembly.FullName;
347
if (AddinMetadata [addin].ContainsKey ("icon") && AddinMetadata [addin] ["icon"].EndsWith ("@")) {
348
AddinMetadata [addin] ["icon"] = string.Format ("{0}{1}", AddinMetadata [addin] ["icon"], addinAssembly.FullName);