[ease/plugins: 7/37] Added base classes to Ease for media import.



commit 35b2a2597e73fde23c4412260374a2fb729887fa
Author: Nate Stedman <natesm gmail com>
Date:   Thu Jun 17 12:35:24 2010 -0400

    Added base classes to Ease for media import.
    
    - Based OCA import off of these.

 Makefile.am                        |    4 +
 README                             |    2 +
 configure.ac                       |    4 +-
 plugins/Makefile                   |    2 +-
 plugins/oca-dialog.vala            |  135 +++------------------
 plugins/oca-image.vala             |    5 +-
 src/ease-plugin-import-dialog.vala |  228 ++++++++++++++++++++++++++++++++++++
 src/ease-plugin-import-image.vala  |    6 +
 8 files changed, 262 insertions(+), 124 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 2564928..0a3a391 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -34,6 +34,8 @@ ease_SOURCES = \
 	src/ease-open-dialog.vala \
 	src/ease-pdf-exporter.vala \
 	src/ease-player.vala \
+	src/ease-plugin-import-dialog.vala \
+	src/ease-plugin-import-image.vala \
 	src/ease-scrollable-embed.vala \
 	src/ease-slide-actor.vala \
 	src/ease-slide-button-panel.vala \
@@ -78,6 +80,8 @@ VALAFLAGS = --pkg glib-2.0 \
 		--pkg clutter-gst-1.0\
 		--pkg json-glib-1.0\
 		--pkg libarchive\
+		--pkg libsexy\
+		--pkg rest-extras-0.6\
 		$(NULL)
 
 SUBDIRS = po
diff --git a/README b/README
index 88f8b7f..c48cbcd 100644
--- a/README
+++ b/README
@@ -21,6 +21,8 @@ As well as these dependencies:
 - gio-2.0
 - json-glib-1.0
 - libarchive
+- libsexy
+- rest-extras-0.6
 
 Remember to install the introspection packages as well, which
 look like this :
diff --git a/configure.ac b/configure.ac
index da981e9..455dedc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -27,9 +27,9 @@ GNOME_COMPILE_WARNINGS([maximum])
 GNOME_MAINTAINER_MODE_DEFINES
 
 dnl FIXME
-pkg_modules="clutter-gtk-0.10 >= 0.10 gee-1.0 >= 0.5.0 clutter-gst-1.0 >= 1.0.0 json-glib-1.0 >= 0.7.6 libarchive"
+pkg_modules="clutter-gtk-0.10 >= 0.10 gee-1.0 >= 0.5.0 clutter-gst-1.0 >= 1.0.0 json-glib-1.0 >= 0.7.6 libarchive libsexy rest-extras-0.6"
 
-EASE_PACKAGES="--pkg glib-2.0 --pkg gtk+-2.0 --pkg clutter-1.0 --pkg gdk-2.0 --pkg libxml-2.0 --pkg gee-1.0 --pkg clutter-gtk-0.10 --pkg cogl-1.0 --pkg gio-2.0 --pkg clutter-gst-1.0 --pkg libarchive"
+EASE_PACKAGES="--pkg glib-2.0 --pkg gtk+-2.0 --pkg clutter-1.0 --pkg gdk-2.0 --pkg libxml-2.0 --pkg gee-1.0 --pkg clutter-gtk-0.10 --pkg cogl-1.0 --pkg gio-2.0 --pkg clutter-gst-1.0 --pkg libarchive --pkg rest-extras-0.6 --pkg libsexy"
 
 PKG_CHECK_MODULES(EASE, [$pkg_modules])
 
diff --git a/plugins/Makefile b/plugins/Makefile
index e0f035e..5bdfb63 100644
--- a/plugins/Makefile
+++ b/plugins/Makefile
@@ -5,7 +5,7 @@ flickr:flickr.vala
 	valac $(CFLAGS) flickr.vala
 	
 oca: oca-dialog.vala oca-image.vala
-	valac -g $(OCAFLAGS) oca-dialog.vala oca-image.vala
+	valac -g $(OCAFLAGS) oca-dialog.vala oca-image.vala ../src/ease-plugin-import-dialog.vala ../src/ease-plugin-import-image.vala
 
 clean:
 	rm -rf flickr
diff --git a/plugins/oca-dialog.vala b/plugins/oca-dialog.vala
index a867f84..72f5b3d 100644
--- a/plugins/oca-dialog.vala
+++ b/plugins/oca-dialog.vala
@@ -1,18 +1,5 @@
-public class OCA.Dialog : Gtk.Dialog
-{
-	private Gtk.IconView icons;
-	private Gtk.ScrolledWindow icons_scroll;
-	private Sexy.IconEntry search;
-	private Gtk.Button button;
-	private Gtk.ProgressBar progress;
-	private Gtk.Alignment progress_align;
-	private Rest.Proxy proxy;
-	private Rest.ProxyCall call;
-	private Gtk.VBox main_vbox;
-	private Gee.LinkedList<Image?> images_list;
-	private Gtk.ListStore model;
-	private double list_size;
-	
+public class OCA.Dialog : Ease.PluginImportDialog
+{	
 	private const string REST_URL =
 		"http://www.openclipart.org/media/feed/rss/";;
 	
@@ -24,65 +11,26 @@ public class OCA.Dialog : Gtk.Dialog
 	
 	public Dialog()
 	{
-		// search field
-		search = new Sexy.IconEntry();
-		search.set_icon(ICON_POS, new Gtk.Image.from_stock("gtk-find", SIZE));
-		search.add_clear_button();
-		
-		// search button
-		button = new Gtk.Button.from_stock("gtk-find");
-		button.clicked.connect((sender) => {
-			// create the rest proxy call
-			proxy = new Rest.Proxy(REST_URL, false);
-			call = proxy.new_call();
-			call.set_function(search.text);
-			
-			// remove the icons, if needed
-			if (icons_scroll.get_parent() == main_vbox)
-			{
-				main_vbox.remove(icons_scroll);
-			}
-			
-			// add the progress
-			main_vbox.pack_end(progress_align, false, false, 0);
-			progress.pulse();
-			progress_align.show_all();
-			
-			// run the call
-			call.run_async(on_call_finish, this);
-		});
-		
-		// progress
-		progress = new Gtk.ProgressBar();
-		progress_align = new Gtk.Alignment(0, 1, 1, 0);
-		progress_align.add(progress);
-		
-		// icon view
-		icons = new Gtk.IconView();
-		icons_scroll = new Gtk.ScrolledWindow(null, null);
-		icons_scroll.add_with_viewport(icons);
-		icons_scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.ALWAYS);
-		
-		// pack search field and button
-		var hbox = new Gtk.HBox(false, 5);
-		hbox.pack_start(search, true, true, 0);
-		hbox.pack_start(button, false, false, 0);
-		
-		// pack top and bottom
-		main_vbox = new Gtk.VBox(false, 5);
-		main_vbox.pack_start(hbox, false, false, 0);
-		(get_content_area() as Gtk.Box).pack_start(main_vbox, true, true, 0);
+		base();
 	}
 	
-	private void on_call_finish(Rest.ProxyCall call)
+	protected override Rest.Proxy get_proxy()
 	{
-		// update UI
-		main_vbox.pack_start(icons_scroll, true, true, 0);
-		icons_scroll.show_all();
-		
+		return proxy = new Rest.Proxy(REST_URL, false);
+	}
+
+	protected override Rest.ProxyCall get_call()
+	{
+		call = proxy.new_call();
+		call.set_function(search.text);
+		return call;
+	}
+	
+	public override void parse_image_data(string data)
+	{	
 		Xml.Parser.init();
 		
-		Xml.Doc* doc = Xml.Parser.parse_doc(call.get_payload());
+		Xml.Doc* doc = Xml.Parser.parse_doc(data);
 		// TODO: better error handling
 		if (doc == null) return;
 		
@@ -92,10 +40,6 @@ public class OCA.Dialog : Gtk.Dialog
 		Xml.Node* channel = root->children;
 		for (; channel->name != "channel"; channel = channel->next);
 		
-		// create list and model
-		model = new Gtk.ListStore(2, typeof(Gdk.Pixbuf), typeof(string));
-		images_list = new Gee.LinkedList<Image?>();
-		
 		// loop over outermost nodes
 		for (Xml.Node* itr = channel->children;
 		     itr != null; itr = itr->next)
@@ -105,7 +49,7 @@ public class OCA.Dialog : Gtk.Dialog
 			// if the node is an item, add it
 			if (itr->name == "item")
 			{
-				OCA.Image image = OCA.Image();
+				OCA.Image image = new OCA.Image();
 				
 				for (Xml.Node* tag = itr->children;
 				     tag != null; tag = tag->next)
@@ -153,49 +97,6 @@ public class OCA.Dialog : Gtk.Dialog
 				images_list.add(image);
 			}
 		}
-		
-		// remember the list size for the progress bar
-		list_size = images_list.size;
-		
-		// clean up the XML parser
-		Xml.Parser.cleanup();
-		
-		// set icons
-		icons.set_model(model);
-		icons.text_column = Column.TEXT;
-		icons.pixbuf_column = Column.PIXBUF;
-		
-		unowned Thread thread = Thread.create(threaded_get_pixbufs, false);
-	}
-	
-	private void* threaded_get_pixbufs()
-	{
-		// get the next image
-		var image = images_list.poll_head();
-		
-		// get the pixbuf for this image
-		var pixbuf = gdk_pixbuf_from_uri(image.thumb_link == null ?
-		                                 image.file_link : 
-		                                 image.thumb_link);
-		
-		// append to the model
-		var tree_itr = Gtk.TreeIter();
-		model.append(out tree_itr);
-		model.set(tree_itr, Column.PIXBUF, pixbuf,
-		                    Column.TEXT, image.title);
-		
-		// set the progress bar
-		progress.set_fraction(1 - (images_list.size / list_size));
-		
-		// continue if there are more images
-		if (images_list.size > 0) threaded_get_pixbufs();
-		
-		// otherwise, remove the progress bar and return
-		if (progress_align.get_parent() == main_vbox)
-		{
-			main_vbox.remove(progress_align);
-		}
-		return null;
 	}
 	
 	private enum Column
diff --git a/plugins/oca-image.vala b/plugins/oca-image.vala
index ec985e2..950fc63 100644
--- a/plugins/oca-image.vala
+++ b/plugins/oca-image.vala
@@ -1,10 +1,7 @@
-public struct OCA.Image
+public class OCA.Image : Ease.PluginImportImage
 {
-	public string title;
 	public string link;
 	public string creator;
 	public string description;
 	public string license;
-	public string file_link;
-	public string thumb_link;
 }
diff --git a/src/ease-plugin-import-dialog.vala b/src/ease-plugin-import-dialog.vala
new file mode 100644
index 0000000..61ef2d7
--- /dev/null
+++ b/src/ease-plugin-import-dialog.vala
@@ -0,0 +1,228 @@
+/*  Ease, a GTK presentation application
+    Copyright (C) 2010 Nate Stedman
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * Base class for an "import media" dialog that searches a website for media.
+ */
+public abstract class Ease.PluginImportDialog : Gtk.Dialog
+{
+	/**
+	 * Primary icon view for display of results.
+	 */
+	private Gtk.IconView icons;
+	
+	/**
+	 * Scrolled window for icon view.
+	 */
+	private Gtk.ScrolledWindow icons_scroll;
+	
+	/**
+	 * Search field.
+	 */
+	protected Sexy.IconEntry search;
+	
+	/**
+	 * Search button.
+	 */
+	private Gtk.Button button;
+	
+	/**
+	 * Progress bar, displaying the percentage of images downloaded so far.
+	 */
+	private Gtk.ProgressBar progress;
+	
+	/**
+	 * Alignment placing progress bar at the bottom.
+	 */
+	private Gtk.Alignment progress_align;
+	
+	/**
+	 * REST Proxy for retrieving image data.
+	 */
+	protected Rest.Proxy proxy;
+	
+	/**
+	 * REST Call for retrieving image data.
+	 */
+	protected Rest.ProxyCall call;
+	
+	/**
+	 * Main VBox for packing widgets.
+	 */
+	private Gtk.VBox main_vbox;
+	
+	/**
+	 * Stores the images to download. As each image is downloaded, it is
+	 * removed from the list.
+	 */
+	protected Gee.LinkedList<PluginImportImage?> images_list;
+	
+	/**
+	 * ListStore for the icon view.
+	 */
+	private Gtk.ListStore model;
+	
+	/**
+	 * The total amount of images to download.
+	 */
+	private double list_size;
+	
+	public PluginImportDialog()
+	{
+		// search field
+		search = new Sexy.IconEntry();
+		search.add_clear_button();
+		
+		// search button
+		button = new Gtk.Button.from_stock("gtk-find");
+		button.clicked.connect((sender) => {
+			// create the rest proxy call
+			proxy = get_proxy();
+			call = get_call();
+			
+			// remove the icons, if needed
+			if (icons_scroll.get_parent() == main_vbox)
+			{
+				main_vbox.remove(icons_scroll);
+			}
+			
+			// add the progress
+			main_vbox.pack_end(progress_align, false, false, 0);
+			progress.pulse();
+			progress_align.show_all();
+			
+			// run the call
+			call.run_async(on_call_finish, this);
+		});
+		
+		// progress
+		progress = new Gtk.ProgressBar();
+		progress_align = new Gtk.Alignment(0, 1, 1, 0);
+		progress_align.add(progress);
+		
+		// icon view
+		icons = new Gtk.IconView();
+		icons_scroll = new Gtk.ScrolledWindow(null, null);
+		icons_scroll.add_with_viewport(icons);
+		icons_scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.ALWAYS);
+		
+		// pack search field and button
+		var hbox = new Gtk.HBox(false, 5);
+		hbox.pack_start(search, true, true, 0);
+		hbox.pack_start(button, false, false, 0);
+		
+		// pack top and bottom
+		main_vbox = new Gtk.VBox(false, 5);
+		main_vbox.pack_start(hbox, false, false, 0);
+		(get_content_area() as Gtk.Box).pack_start(main_vbox, true, true, 0);
+	}
+	
+	protected abstract void parse_image_data(string data);
+	protected abstract Rest.Proxy get_proxy();
+	protected abstract Rest.ProxyCall get_call();
+	
+	private void on_call_finish(Rest.ProxyCall call)
+	{
+		// update UI
+		main_vbox.pack_start(icons_scroll, true, true, 0);
+		icons_scroll.show_all();
+		
+		// create list and model
+		model = new Gtk.ListStore(2, typeof(Gdk.Pixbuf), typeof(string));
+		images_list = new Gee.LinkedList<PluginImportImage?>();
+		
+		// parse the image data (done by subclasses)
+		parse_image_data(call.get_payload());
+		
+		// remember the list size for the progress bar
+		list_size = images_list.size;
+		
+		// set icons
+		icons.set_model(model);
+		icons.text_column = Column.TEXT;
+		icons.pixbuf_column = Column.PIXBUF;
+		
+		Thread.create(threaded_get_pixbufs, false);
+	}
+	
+	private void* threaded_get_pixbufs()
+	{
+		// get the next image
+		var image = images_list.poll_head();
+		
+		// get the pixbuf for this image
+		var pixbuf = gdk_pixbuf_from_uri(image.thumb_link == null ?
+		                                 image.file_link : 
+		                                 image.thumb_link);
+		
+		// append to the model
+		var tree_itr = Gtk.TreeIter();
+		model.append(out tree_itr);
+		model.set(tree_itr, Column.PIXBUF, pixbuf,
+		                    Column.TEXT, image.title);
+		
+		// set the progress bar
+		progress.set_fraction(1 - (images_list.size / list_size));
+		
+		// continue if there are more images
+		if (images_list.size > 0) threaded_get_pixbufs();
+		
+		// otherwise, remove the progress bar and return
+		if (progress_align.get_parent() == main_vbox)
+		{
+			main_vbox.remove(progress_align);
+		}
+		return null;
+	}
+	
+	/**
+	 * Loads and returns a pixbuf from a URI. Best used threaded, to prevent 
+	 * lock up.
+	 *
+	 * @param uri The URI to load from.
+	 */
+	private Gdk.Pixbuf? gdk_pixbuf_from_uri (string uri) {
+
+		File file = File.new_for_uri (uri);
+		FileInputStream filestream;
+		try {
+			filestream = file.read (null);
+		} catch (Error e) {
+			filestream = null;
+			error ("Couldn't read distant file : %s", e.message);
+		}
+		assert (filestream != null);
+		Gdk.Pixbuf pix;
+		try {
+			pix = new Gdk.Pixbuf.from_stream_at_scale (filestream,
+														   200,
+														   200,
+														   true,
+														   null);
+		} catch (Error e) {
+			error ("Couldn't create pixbuf from file: %s", e.message);
+			pix = null;
+		}
+		return pix;
+	}
+	
+	private enum Column
+	{
+		PIXBUF = 0,
+		TEXT = 1
+	}
+}
diff --git a/src/ease-plugin-import-image.vala b/src/ease-plugin-import-image.vala
new file mode 100644
index 0000000..d1037da
--- /dev/null
+++ b/src/ease-plugin-import-image.vala
@@ -0,0 +1,6 @@
+public class Ease.PluginImportImage
+{
+	public string title;
+	public string file_link;
+	public string thumb_link;
+}



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