[ease] Added support for embedding PDF documents.



commit 2128be52d14ef51f54eac101244fd77bbba1d903
Author: Nate Stedman <natesm gmail com>
Date:   Thu Aug 19 16:43:53 2010 -0400

    Added support for embedding PDF documents.
    
    - PdfActor/PdfElement pair
    - (simple) inspector widget
    - Works with Cairo, not so much with HTML export

 configure.ac                     |   38 +++++++------
 data/ui/editor-window.ui         |    8 +++
 data/ui/inspector-element-pdf.ui |   60 ++++++++++++++++++++
 ease-core/Makefile.am            |    2 +
 ease-core/ease-pdf-actor.vala    |   89 ++++++++++++++++++++++++++++++
 ease-core/ease-pdf-element.vala  |  113 ++++++++++++++++++++++++++++++++++++++
 ease-core/ease-slide.vala        |   32 ++++++-----
 ease-core/ease-theme.vala        |    3 +
 ease/ease-editor-window.vala     |   53 ++++++++++++++++++
 po/POTFILES.in                   |    3 +
 po/POTFILES.skip                 |    2 +
 11 files changed, 371 insertions(+), 32 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 72398b0..c751144 100644
--- a/configure.ac
+++ b/configure.ac
@@ -44,26 +44,28 @@ GNOME_COMPILE_WARNINGS([maximum])
 GNOME_MAINTAINER_MODE_DEFINES
 
 dnl packages
-pkg_modules=" \
-	gee-1.0 \
-	clutter-gtk-0.10 >= 0.10 \
-	libarchive \
-	json-glib-1.0 >= 0.7.6\
-	clutter-gst-1.0 \
-	gmodule-2.0 \
-	unique-1.0"
-
-EASE_PACKAGES=" \
-	--pkg gee-1.0 \
-	--pkg clutter-gtk-0.10 \
-	--pkg libarchive \
-	--pkg json-glib-1.0 \
-    --pkg clutter-gst-1.0 \
-	--pkg gmodule-2.0 \
-	--pkg unique-1.0"
-
+pkg_modules="\
+ clutter-gst-1.0\
+ clutter-gtk-0.10 >= 0.10\
+ gee-1.0\
+ gmodule-2.0\
+ json-glib-1.0 >= 0.7.6\
+ libarchive\
+ poppler-glib\
+ unique-1.0"
+ 
 PKG_CHECK_MODULES(EASE, [$pkg_modules])
 
+EASE_PACKAGES="\
+ --pkg clutter-gst-1.0\
+ --pkg clutter-gtk-0.10\
+ --pkg gee-1.0\
+ --pkg gmodule-2.0\
+ --pkg json-glib-1.0\
+ --pkg libarchive\
+ --pkg poppler-glib\
+ --pkg unique-1.0"
+
 AC_SUBST(EASE_CFLAGS)
 AC_SUBST(EASE_LIBS)
 AC_SUBST(EASE_PACKAGES)
diff --git a/data/ui/editor-window.ui b/data/ui/editor-window.ui
index 3948ed5..0fcfc95 100644
--- a/data/ui/editor-window.ui
+++ b/data/ui/editor-window.ui
@@ -239,6 +239,14 @@
                   </object>
                 </child>
                 <child>
+                  <object class="GtkMenuItem" id="Insert PDF">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">_PDF Document</property>
+                    <property name="use_underline">True</property>
+                    <signal name="activate" handler="ease_editor_window_insert_pdf"/>
+                  </object>
+                </child>
+                <child>
                   <object class="GtkSeparatorMenuItem" id="menuitem3">
                     <property name="visible">True</property>
                   </object>
diff --git a/data/ui/inspector-element-pdf.ui b/data/ui/inspector-element-pdf.ui
new file mode 100644
index 0000000..8ab4d4a
--- /dev/null
+++ b/data/ui/inspector-element-pdf.ui
@@ -0,0 +1,60 @@
+<?xml version="1.0"?>
+<interface>
+  <requires lib="gtk+" version="2.16"/>
+  <!-- interface-naming-policy project-wide -->
+  <object class="GtkAlignment" id="root">
+    <property name="visible">True</property>
+    <property name="top_padding">4</property>
+    <property name="bottom_padding">4</property>
+    <property name="left_padding">4</property>
+    <property name="right_padding">4</property>
+    <child>
+      <object class="GtkVBox" id="vbox1">
+        <property name="visible">True</property>
+        <property name="spacing">8</property>
+        <child>
+          <object class="GtkVBox" id="vbox2">
+            <property name="visible">True</property>
+            <property name="spacing">4</property>
+            <child>
+              <object class="GtkLabel" id="Displayed Page">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">Displayed Page</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkHScale" id="disp-page">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="update_policy">discontinuous</property>
+                <property name="adjustment">adjustment1</property>
+                <property name="digits">0</property>
+                <property name="value_pos">left</property>
+              </object>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </object>
+  <object class="GtkAdjustment" id="adjustment1">
+    <property name="upper">1</property>
+    <property name="step_increment">1</property>
+    <property name="page_increment">1</property>
+    <property name="page_size">1</property>
+  </object>
+</interface>
diff --git a/ease-core/Makefile.am b/ease-core/Makefile.am
index af45981..3f3eaa4 100644
--- a/ease-core/Makefile.am
+++ b/ease-core/Makefile.am
@@ -22,6 +22,8 @@ libease_core_0_3_la_SOURCES = \
 	ease-image.vala \
 	ease-iterable-models.vala \
 	ease-media-element.vala \
+	ease-pdf-actor.vala \
+	ease-pdf-element.vala \
 	ease-shape-element.vala \
 	ease-slide.vala \
 	ease-temp.vala \
diff --git a/ease-core/ease-pdf-actor.vala b/ease-core/ease-pdf-actor.vala
new file mode 100644
index 0000000..bb34234
--- /dev/null
+++ b/ease-core/ease-pdf-actor.vala
@@ -0,0 +1,89 @@
+/*  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/>.
+*/
+
+/**
+ * Actor displaying a { link PdfElement}.
+ */
+public class Ease.PdfActor : Actor
+{
+	private Clutter.CairoTexture texture;
+	private int current_page;
+	private Poppler.Document doc;
+	
+	/**
+	 * Instantiates a new PdfActor from an Element.
+	 *
+	 * @param e The represented element.
+	 * @param c The context of this Actor (Presentation, Sidebar, Editor)
+	 */
+	public PdfActor(PdfElement e, ActorContext c)
+	{
+		base(e, c);
+		
+		contents = new Clutter.Group();
+		contents.width = e.width;
+		contents.height = e.height;
+		x = e.x;
+		y = e.y;
+		add_actor(contents);
+		
+		current_page = e.default_page;
+		doc = e.pdf_doc;
+		draw_page();
+		
+		e.notify["default-page"].connect((obj, pspec) => {
+			current_page = e.default_page;
+			draw_page();
+		});
+	}
+	
+	private void draw_page()
+	{	
+		// get the current page
+		var page = doc.get_page(current_page);
+		double width = 0, height = 0;
+		page.get_size(out width, out height);
+		
+		// create a texture
+		if (texture == null)
+		{
+			texture = new Clutter.CairoTexture((int)width, (int)height);
+			(contents as Clutter.Group).add_actor(texture);
+			
+			texture.width = contents.width;
+			texture.height = contents.height;
+			
+			contents.notify["width"].connect((obj, pspec) => {
+				texture.width = contents.width;
+			});
+			
+			contents.notify["height"].connect((obj, pspec) => {
+				texture.height = contents.height;
+			});
+		}
+		
+		// otherwise, set the size
+		else
+		{
+			texture.set_surface_size((int)width, (int)height);
+		}
+		
+		// draw the texture
+		var cr = texture.create();
+		page.render(cr);
+	}
+}
diff --git a/ease-core/ease-pdf-element.vala b/ease-core/ease-pdf-element.vala
new file mode 100644
index 0000000..b552d57
--- /dev/null
+++ b/ease-core/ease-pdf-element.vala
@@ -0,0 +1,113 @@
+/*  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/>.
+*/
+
+/**
+ * Displays a PDF document in a presentation.
+ */
+public class Ease.PdfElement : MediaElement
+{
+	private const string UI_FILE = "inspector-element-pdf.ui";	
+	
+	/**
+	 * The page of the PDF file that is initially displayed.
+	 */
+	public int default_page { get; set; default = 0; }
+	
+	internal Poppler.Document pdf_doc;
+	
+	public PdfElement(string filename)
+	{
+		pdf_doc = new Poppler.Document.from_file(
+			Filename.to_uri(filename),
+			null);
+		signals();
+	}
+	
+	internal PdfElement.from_json(Json.Object obj)
+	{
+		base.from_json(obj);
+		default_page = obj.get_string_member(Theme.PDF_DEFAULT_PAGE).to_int();
+		
+		pdf_doc = new Poppler.Document.from_file(
+			Filename.to_uri(full_filename),
+			null);
+	}	
+	
+	public override Actor actor(ActorContext c)
+	{
+		return new PdfActor(this, c);
+	}
+	
+	public override Json.Object to_json()
+	{
+		var obj = base.to_json();
+		obj.set_string_member(Theme.PDF_DEFAULT_PAGE, default_page.to_string());
+		return obj;
+	}
+	
+	public override string html_render(HTMLExporter exporter)
+	{
+		return "<!-- PDFs not supported in HTML yet -->";
+	}
+	
+	public override void cairo_render(Cairo.Context context) throws Error
+	{
+		// get the current page
+		var page = pdf_doc.get_page(default_page);
+		
+		// scale the context
+		double w = 0, h = 0;
+		page.get_size(out w, out h);
+		context.scale(width / w, height / h);
+		
+		// render
+		page.render(context);
+	}
+	
+	public override Gtk.Widget inspector_widget()
+	{
+		var builder = new Gtk.Builder();
+		try
+		{
+			builder.add_from_file(data_path(Path.build_filename(Temp.UI_DIR,
+				                                                UI_FILE)));
+		}
+		catch (Error e) { error("Error loading UI: %s", e.message); }
+		
+		var scale = builder.get_object("disp-page") as Gtk.HScale;
+		scale.adjustment.upper = pdf_doc.get_n_pages();
+		
+		// format the scale value's display
+		scale.format_value.connect((s, value) => {
+			return "%i".printf((int)value + 1);
+		});
+		
+		// connect the slider's changed signal
+		scale.value_changed.connect(() => {
+			// create an undo acton
+			var action = new UndoAction(this, "default-page");
+			
+			default_page = (int)scale.adjustment.value;
+			
+			// emit the undoaction
+			undo(action);
+		});
+		
+		// return the root widget
+		return builder.get_object("root") as Gtk.Widget;
+	}
+}
diff --git a/ease-core/ease-slide.vala b/ease-core/ease-slide.vala
index 184f8e8..4b496c9 100644
--- a/ease-core/ease-slide.vala
+++ b/ease-core/ease-slide.vala
@@ -27,6 +27,7 @@ public class Ease.Slide : GLib.Object, UndoSource
 	public const string IMAGE_TYPE = "EaseImageElement";
 	public const string SHAPE_TYPE = "EaseShapeElement";
 	public const string VIDEO_TYPE = "EaseVideoElement";
+	public const string PDF_TYPE = "EasePdfElement";
 
 	/**
 	 * The { link Element}s contained by this Slide
@@ -292,22 +293,25 @@ public class Ease.Slide : GLib.Object, UndoSource
 			var type = node.get_string_member(Theme.ELEMENT_TYPE);
 			Element e;
 			
-			if (type == IMAGE_TYPE)
+			switch (type)
 			{
-				e = new ImageElement.from_json(node);
-			}
-			else if (type == SHAPE_TYPE)
-			{
-				e = new ShapeElement.from_json(node);
-			}
-			else if (type == VIDEO_TYPE)
-			{
-				e = new VideoElement.from_json(node);
-			}
-			else
-			{
-				e = new TextElement.from_json(node);
+				case IMAGE_TYPE:
+					e = new ImageElement.from_json(node);
+					break;
+				case SHAPE_TYPE:
+					e = new ShapeElement.from_json(node);
+					break;
+				case VIDEO_TYPE:
+					e = new VideoElement.from_json(node);
+					break;
+				case PDF_TYPE:
+					e = new PdfElement.from_json(node);
+					break;
+				default: // text element, probably plugins later...
+					e = new TextElement.from_json(node);
+					break;
 			}
+			
 			e.element_type = type;
 			append(e);
 		}
diff --git a/ease-core/ease-theme.vala b/ease-core/ease-theme.vala
index 19b3020..d2ddca4 100644
--- a/ease-core/ease-theme.vala
+++ b/ease-core/ease-theme.vala
@@ -99,6 +99,9 @@ public class Ease.Theme : GLib.Object
 	// shape properties
 	public const string SHAPE_TYPE = "shape-type";
 	
+	// pdf properties
+	public const string PDF_DEFAULT_PAGE = "pdf-default-page";
+	
 	// gradient types
 	public const string GRAD_LINEAR = "linear";
 	public const string GRAD_LINEAR_MIRRORED = "linear-mirrored";
diff --git a/ease/ease-editor-window.vala b/ease/ease-editor-window.vala
index ef38f6a..92206ce 100644
--- a/ease/ease-editor-window.vala
+++ b/ease/ease-editor-window.vala
@@ -500,6 +500,59 @@ internal class Ease.EditorWindow : Gtk.Window
 	}
 	
 	[CCode (instance_pos = -1)]
+	internal void insert_pdf(Gtk.Widget sender)
+	{
+		var filename = Dialog.open_ext(_("Insert PDF Document"),
+		                               this, (dialog) => {
+			// add a filter for pdf files
+			var filter = new Gtk.FileFilter();
+			filter.add_pattern("*.pdf");
+			filter.add_pattern("*.PDF");
+			filter.set_name(_("PDF Documents"));
+			dialog.add_filter(filter);
+			
+			// add a filter for all files
+			filter = new Gtk.FileFilter();
+			filter.set_name(_("All Files"));
+			filter.add_pattern("*");
+			dialog.add_filter(filter);
+		});
+
+		if (filename != null)
+		{
+			try
+			{
+				var e = new PdfElement(filename);
+				var doc = new Poppler.Document.from_file(
+					Filename.to_uri(filename), null);
+				var page = doc.get_page(0);
+				
+				// set the size and position of the element
+				double width = 0, height = 0;
+				page.get_size(out width, out height);
+				
+				e.width = (float)width;
+				e.height = (float)height;
+				e.x = slide.width / 2 - e.width / 2;
+				e.y = slide.height / 2 - e.height / 2;
+				
+				e.element_type = Slide.PDF_TYPE;
+				e.identifier = Theme.CUSTOM_MEDIA;
+				e.filename = document.add_media_file(filename);
+				e.source_filename = filename;
+				
+				// add the element
+				slide.append(e);
+				embed.select_element(e);
+			}
+			catch (Error e)
+			{
+				error_dialog(_("Error Inserting PDF"), e.message);
+			}
+		}
+	}
+	
+	[CCode (instance_pos = -1)]
 	internal void on_insert_rectangle(Gtk.Widget sender)
 	{
 		var rect = new ShapeElement(ShapeType.RECTANGLE);
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 6e14e79..f23ff00 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -22,6 +22,8 @@ ease-core/ease-image-element.vala
 ease-core/ease-image.vala
 ease-core/ease-iterable-models.vala
 ease-core/ease-media-element.vala
+ease-core/ease-pdf-actor.vala
+ease-core/ease-pdf-element.vala
 ease-core/ease-shape-element.vala
 ease-core/ease-slide.vala
 ease-core/ease-temp.vala
@@ -63,6 +65,7 @@ data/ui/background.ui
 data/ui/editor-window.ui
 data/ui/inspector-element-image.ui
 data/ui/inspector-element-none.ui
+data/ui/inspector-element-pdf.ui
 data/ui/inspector-element-shape.ui
 data/ui/inspector-element-text.ui
 data/ui/inspector-element-video.ui
diff --git a/po/POTFILES.skip b/po/POTFILES.skip
index e0b8b42..9d0fb63 100644
--- a/po/POTFILES.skip
+++ b/po/POTFILES.skip
@@ -18,6 +18,8 @@ ease-core/ease-image.c
 ease-core/ease-image-element.c
 ease-core/ease-iterable-models.c
 ease-core/ease-media-element.c
+ease-core/ease-pdf-actor.c
+ease-core/ease-pdf-element.c
 ease-core/ease-shape-element.c
 ease-core/ease-slide.c
 ease-core/ease-temp.c



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