F-Spot plug-ins
- From: Stephane Delcroix <stephane delcroix org>
- To: F-Spot list <f-spot-list gnome org>
- Subject: F-Spot plug-ins
- Date: Tue, 20 Jun 2006 09:16:03 +0200
Hi everyone,
I'm quite proud to give you this patch, adding support for loading
plug-ins into F-Spot. I'll submit it to b.g.o. soon.
For now, all Plugins in all .dll in $HOME/.gnome2/f-spot/plugins are
loaded, but I plan to write another plugin to enable them at will.
The patch include Thomas's solution to #344534, so you can compile
plug-ins from outside the source tree using:
mcs -target:library -pkg:f-spot MyPlugin.cs
Find also attached below 2 plugins, one displaying a dialog about
plugins, and a first Export Plug-in, for sending mail (the export code
is just a cut and paste from F-Spot core code).
Those 2 plugins compile with:
mcs -target:library -pkg:f-spot -pkg:gnome-sharp-2.0 DialogPlugin.cs
mcs -target:library -pkg:f-spot -pkg:gnome-sharp-2.0 SendMailPlugin.cs
It's a first and very early version, so write a lot of comments about
it...
rgds,
Stephane
Index: Makefile.am
===================================================================
RCS file: /cvs/gnome/f-spot/Makefile.am,v
retrieving revision 1.13
diff -u -p -r1.13 Makefile.am
--- Makefile.am 17 Feb 2006 17:02:32 -0000 1.13
+++ Makefile.am 19 Jun 2006 15:54:03 -0000
@@ -17,6 +17,9 @@ desktop_in_files= \
desktop_files=$(desktop_in_files:.desktop.in=.desktop)
@INTLTOOL_DESKTOP_RULE@
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = f-spot.pc
+
Applicationsdir = $(datadir)/applications
Applications_DATA = $(desktop_files)
@@ -30,6 +33,7 @@ EXTRA_DIST = \
intltool-extract.in \
intltool-merge.in \
intltool-update.in \
+ f-spot.pc.in \
f-spot.spec \
$(desktop_in_files) \
$(desktop_files)
Index: configure.in
===================================================================
RCS file: /cvs/gnome/f-spot/configure.in,v
retrieving revision 1.102
diff -u -p -r1.102 configure.in
--- configure.in 24 May 2006 15:44:42 -0000 1.102
+++ configure.in 19 Jun 2006 15:54:03 -0000
@@ -182,6 +182,7 @@ po/Makefile.in
src/Defines.cs
src/f-spot.exe.config
src/Makefile
+f-spot.pc
f-spot.spec
f-spot.desktop.in
])
Index: src/Global.cs
===================================================================
RCS file: /cvs/gnome/f-spot/src/Global.cs,v
retrieving revision 1.8
diff -u -p -r1.8 Global.cs
--- src/Global.cs 22 Mar 2006 19:14:41 -0000 1.8
+++ src/Global.cs 19 Jun 2006 15:54:03 -0000
@@ -18,6 +18,12 @@ namespace FSpot {
}
}
+ public static string PluginsDirectory {
+ get {
+ return System.IO.Path.Combine (BaseDirectory, "plugins");
+ }
+ }
+
public static void ModifyColors (Gtk.Widget widget)
{
try {
Index: src/MainWindow.cs
===================================================================
RCS file: /cvs/gnome/f-spot/src/MainWindow.cs,v
retrieving revision 1.298
diff -u -p -r1.298 MainWindow.cs
--- src/MainWindow.cs 9 Jun 2006 23:24:57 -0000 1.298
+++ src/MainWindow.cs 19 Jun 2006 15:54:05 -0000
@@ -44,6 +44,7 @@ public class MainWindow {
[Glade.Widget] MenuItem rename_version_menu_item;
[Glade.Widget] MenuItem export;
+ [Glade.Widget] MenuItem export_menu_item;
[Glade.Widget] MenuItem print;
[Glade.Widget] MenuItem send_mail;
@@ -107,6 +108,8 @@ public class MainWindow {
PhotoVersionMenu versions_submenu;
+ ExportMenu export_submenu;
+
Gtk.ToggleButton browse_button;
Gtk.ToggleButton edit_button;
@@ -376,6 +379,10 @@ public class MainWindow {
// When the icon_view is loaded, set it's initial scroll position
icon_view.SizeAllocated += HandleIconViewReady;
+System.Console.WriteLine("###############################################");
+FSpot.Plugins.Plugger plugger = new FSpot.Plugins.Plugger();
+System.Console.WriteLine("###############################################");
+
UpdateToolbar ();
}
@@ -1463,7 +1470,8 @@ public class MainWindow {
"Joshua Tauberer",
"Joerg Buesse",
"Jakub Steiner",
- "Xavier Bouchoux"
+ "Xavier Bouchoux",
+ "Stephane Delcroix"
};
// Translators should localize the following string
@@ -2495,6 +2503,9 @@ public class MainWindow {
version_menu_item.Submenu = versions_submenu;
}
+ export_submenu = new ExportMenu ();
+ export_menu_item.Submenu = export_submenu;
+
set_as_background.Sensitive = single_active;
adjust_color.Sensitive = single_active;
adjust_time.Sensitive = active_selection;
@@ -2905,4 +2916,12 @@ public class MainWindow {
{
toolTips.SetTip (widget, tip, null);
}
+
+ //
+ //Hooks for plugin
+ //
+ public void HandleExportWithPlugin (FSpot.Plugins.ExportPlugin ex_plugin) {
+ ex_plugin.DoExport(new FSpot.PhotoArray (SelectedPhotos ()));
+ }
+
}
Index: src/Makefile.am
===================================================================
RCS file: /cvs/gnome/f-spot/src/Makefile.am,v
retrieving revision 1.63
diff -u -p -r1.63 Makefile.am
--- src/Makefile.am 26 Apr 2006 20:31:07 -0000 1.63
+++ src/Makefile.am 19 Jun 2006 15:54:06 -0000
@@ -25,6 +25,7 @@ F_SPOT_CSDISTFILES = \
$(srcdir)/DirectoryCollection.cs \
$(srcdir)/ExceptionDialog.cs \
$(srcdir)/Exif.cs \
+ $(srcdir)/ExportMenu.cs \
$(srcdir)/FlickrExport.cs \
$(srcdir)/FlickrRemote.cs \
$(srcdir)/FileImportBackend.cs \
@@ -79,6 +80,7 @@ F_SPOT_CSDISTFILES = \
$(srcdir)/PixbufUtils.cs \
$(srcdir)/PixbufCache.cs \
$(srcdir)/PixelBuffer.cs \
+ $(srcdir)/Plugins.cs \
$(srcdir)/PreferenceDialog.cs \
$(srcdir)/Preferences.cs \
$(srcdir)/PreviewPopup.cs \
Index: src/f-spot.glade
===================================================================
RCS file: /cvs/gnome/f-spot/src/f-spot.glade,v
retrieving revision 1.164
diff -u -p -r1.164 f-spot.glade
--- src/f-spot.glade 6 Jun 2006 18:09:47 -0000 1.164
+++ src/f-spot.glade 19 Jun 2006 15:54:20 -0000
@@ -7250,6 +7250,20 @@ Photo Details</property>
<signal name="activate" handler="HandleExportToCD" last_modification_time="Wed, 12 Jan 2005 22:49:52 GMT"/>
</widget>
</child>
+
+ <child>
+ <widget class="GtkSeparatorMenuItem" id="separator116">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="export_menu_item">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Export plugins</property>
+ <property name="use_underline">True</property>
+ </widget>
+ </child>
</widget>
</child>
</widget>
@@ -7272,7 +7286,7 @@ Photo Details</property>
<signal name="activate" handler="HandleSendMailCommand" last_modification_time="Mon, 07 Jun 2004 22:31:01 GMT"/>
<child internal-child="image">
- <widget class="GtkImage" id="image40">
+ <widget class="GtkImage" id="image43">
<property name="visible">True</property>
<property name="stock">gnome-stock-mail-fwd</property>
<property name="icon_size">1</property>
@@ -7297,8 +7311,8 @@ Photo Details</property>
<property name="label" translatable="yes">_Close</property>
<property name="use_underline">True</property>
<signal name="activate" handler="HandleCloseCommand" last_modification_time="Tue, 09 Dec 2003 20:59:54 GMT"/>
- <accelerator key="q" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<accelerator key="w" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+ <accelerator key="q" modifiers="GDK_CONTROL_MASK" signal="activate"/>
</widget>
</child>
</widget>
@@ -7635,7 +7649,7 @@ Photo Details</property>
<property name="visible">True</property>
<property name="label" translatable="yes">_Folder</property>
<property name="use_underline">True</property>
- <property name="active">False</property>
+ <property name="active">True</property>
<property name="group">month</property>
<signal name="activate" handler="HandleArrangeByDirectory" last_modification_time="Fri, 20 Aug 2004 22:26:32 GMT"/>
</widget>
--- /dev/null 2006-06-19 09:02:49.376262000 +0200
+++ src/Plugins.cs 2006-06-19 17:38:29.000000000 +0200
@@ -0,0 +1,120 @@
+/*
+ * Plugins.cs
+ *
+ * Authors:
+ * Stephane Delcroix <stephane delcroix org>
+ *
+ * Copyright (C) 2006 Stephane Delcroix
+ *
+ */
+
+
+using System;
+using System.Reflection;
+
+using System.Collections;
+
+using FSpot;
+
+namespace FSpot.Plugins {
+
+ public class Plugger {
+ private static System.Collections.Hashtable plugins = new System.Collections.Hashtable();
+
+ public static string [] PluginsList {
+ get {
+ string [] list = new String[plugins.Count];
+ plugins.Keys.CopyTo(list,0);
+ return list;
+ }
+ }
+
+ public static string [] LoadedPlugins (System.Type type) {
+ ArrayList loadedplugins = new ArrayList();
+ foreach (string plugin in PluginsList){
+ if ( ((Plugin)plugins[plugin]).IsLoaded && (plugins[plugin]).GetType().IsSubclassOf(type))
+ loadedplugins.Add(plugin);
+ }
+ return (string [])loadedplugins.ToArray(typeof(System.String));
+ }
+
+ public static string [] LoadedPlugins() { return LoadedPlugins(typeof(FSpot.Plugins.Plugin)); }
+
+ public static Plugin Plugin(string ShortName)
+ {
+ return (Plugin)plugins[ShortName];
+ }
+
+ public Plugger ()
+ {
+ LoadPluginsFromDirectory(FSpot.Global.PluginsDirectory);
+ InitializePlugins(PluginsList);
+ }
+
+ public void LoadPluginsFromDirectories (string [] directories)
+ {
+ foreach ( String directory in directories )
+ LoadPluginsFromDirectory (directory);
+ }
+
+ private void LoadPluginsFromDirectory (string path)
+ {
+ foreach ( String dll in System.IO.Directory.GetFiles(path, "*.dll") )
+ LoadPluginsFromFile(dll);
+ }
+
+ private void LoadPluginsFromFile(string pluginfile)
+ {
+ Console.WriteLine ("Loading plugins from {0}...", pluginfile);
+ Assembly assembly = Assembly.LoadFile(pluginfile);
+ Type [] ts = assembly.GetTypes();
+ foreach (Type t in ts){
+ if ( t.IsSubclassOf(typeof(FSpot.Plugins.Plugin)) ){
+ Plugin plugin = (Plugin)assembly.CreateInstance(t.ToString());
+ Console.WriteLine("{0} available", t);
+ //FIXME: check if ShortName already exists in plugins[]
+ plugins [plugin.ShortName] = plugin;
+ } else
+ Console.WriteLine("{0} is NOT a Plugin", t);
+ }
+ }
+
+ public void InitializePlugins(string [] pluginslist)
+ {
+ foreach (String plugin in pluginslist) {
+ ((Plugin)plugins[plugin]).Load();
+ }
+ }
+ }
+
+ public abstract class Plugin {
+ public abstract string DisplayName { get; }
+ public virtual string ShortName { get { return DisplayName; } }
+ public abstract string Description { get; }
+ private bool Loaded = false;
+
+ public bool IsLoaded {
+ get { return Loaded; }
+ }
+
+ public Plugin ()
+ {
+ }
+
+ public void Load () {
+ PluginInitialize();
+ Loaded = true;
+ }
+
+ protected abstract void PluginInitialize();
+ }
+
+ public abstract class ExportPlugin: Plugin {
+ public abstract string MenuEntryName { get; }
+ public void HandleMenuItemActivated(object sender, EventArgs args)
+ {
+ MainWindow.Toplevel.HandleExportWithPlugin(this);
+ }
+ public abstract void DoExport(IBrowsableCollection selectedphotos);
+ }
+}
--- /dev/null 2006-06-19 09:02:49.376262000 +0200
+++ src/ExportMenu.cs 2006-06-19 16:30:49.000000000 +0200
@@ -0,0 +1,28 @@
+using Gtk;
+using GtkSharp;
+using System;
+
+namespace FSpot {
+ public class ExportMenu : Menu {
+ public ExportMenu ()
+ {
+ string [] exportplugins = FSpot.Plugins.Plugger.LoadedPlugins(typeof(FSpot.Plugins.ExportPlugin));
+
+ if ( exportplugins == null || exportplugins.Length == 0 ) {
+ MenuItem menu_item = new MenuItem ("No Export Plug-in available");
+ menu_item.Show();
+ menu_item.Sensitive = false;
+ Append(menu_item);
+ }
+ foreach (string shortname in exportplugins) {
+ FSpot.Plugins.ExportPlugin plugin = (FSpot.Plugins.ExportPlugin)FSpot.Plugins.Plugger.Plugin(shortname);
+ MenuItem menu_item = new MenuItem (plugin.MenuEntryName);
+ menu_item.Show();
+ menu_item.Sensitive = true;
+ menu_item.Activated += new EventHandler (plugin.HandleMenuItemActivated);
+
+ Append(menu_item);
+ }
+ }
+ }
+}
using System;
using FSpot;
using FSpot.Plugins;
namespace FSpot.Plugins {
public class DialogPlugin: FSpot.Plugins.Plugin
{
public override string DisplayName { get { return "Dialog Plugin"; } }
public override string ShortName { get { return "DialogPlugin"; } }
public override string Description { get { return "Warn the user about using plugins"; } }
protected override void PluginInitialize()
{
Console.WriteLine("Initializing Dialog Plugin");
String header = "Plug-ins enabled version of F-Spot";
String msg = "You are running a plug-ins enabled version of F-Spot" +
"\nPlug-ins can crash your F-Spot, delete all your images, and " +
"completely destroy your database." +
"\nYou have been warned! Don't fill any bug report " +
"regarding plug-ins";
HigMessageDialog.RunHigMessageDialog(MainWindow.Toplevel.Window,
Gtk.DialogFlags.DestroyWithParent,
Gtk.MessageType.Warning,
Gtk.ButtonsType.Ok,header,msg);
}
}
}
using System;
using FSpot;
using FSpot.Plugins;
namespace FSpot.Plugins {
public class SendMailPlugin: FSpot.Plugins.ExportPlugin
{
public override string DisplayName { get { return "Send Mail Plugin"; } }
public override string ShortName { get { return "SendMailPlugin"; } }
public override string Description { get { return "Create an e-mail with your photos attached"; } }
public override string MenuEntryName { get { return "Send Mail...";} }
protected override void PluginInitialize()
{
Console.WriteLine("Initializing Send Mail Plugin");
}
public override void DoExport (IBrowsableCollection sel_photos)
{
Photo [] photos = (Photo [])sel_photos.Items;
System.Text.StringBuilder url = new System.Text.StringBuilder ("mailto:?subject=my%20photos");
foreach (Photo p in photos) {
url.Append ("&attach=" + UriList.EscapeString (p.DefaultVersionUri.LocalPath, true, true, true));
}
Gnome.Url.Show (url.ToString ());
Console.WriteLine ("Exporting {0} pictures", sel_photos.Count);
}
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]