[ease/themes] [themes] Themes persist when documents are saved



commit 208073dfc955107a77cff75ea4cad9536f854c64
Author: Nate Stedman <natesm gmail com>
Date:   Fri Jul 23 19:47:33 2010 -0400

    [themes] Themes persist when documents are saved
    
    - A document's theme is archived when the document is saved
    - This theme is restored when loading
    - Fixed bugs in saving and extraction code
    - Added recursive_directory utility function.

 src/ease-document.vala    |    2 +-
 src/ease-json-parser.vala |   10 ++++++
 src/ease-temp.vala        |   68 ++++++++++++++++-----------------------------
 src/ease-theme.vala       |    7 ++--
 src/ease-utilities.vala   |   62 +++++++++++++++++++++++++++++++++++++++++
 5 files changed, 101 insertions(+), 48 deletions(-)
---
diff --git a/src/ease-document.vala b/src/ease-document.vala
index 9e1f680..cec3a96 100644
--- a/src/ease-document.vala
+++ b/src/ease-document.vala
@@ -36,7 +36,7 @@ public class Ease.Document : SlideSet
 	/**
 	 * Path of the Document's { link Theme} data files.
 	 */
-	private const string THEME_PATH = "theme";
+	public const string THEME_PATH = "Theme";
 
 	/**
 	 * The { link Theme} linked to this Document.
diff --git a/src/ease-json-parser.vala b/src/ease-json-parser.vala
index 7d4c30e..ba1f8a8 100644
--- a/src/ease-json-parser.vala
+++ b/src/ease-json-parser.vala
@@ -57,6 +57,16 @@ public static class Ease.JSONParser
 			document.add_slide(document.length, parse_slide(node));
 		}
 		
+		// get the document's theme
+		var theme_path = Path.build_filename(Document.THEME_PATH,
+		                                     Theme.JSON_PATH);
+		var theme_full_path = Path.build_filename(document.path, theme_path);
+		
+		if (File.new_for_path(theme_full_path).query_exists(null))
+		{
+			document.theme = new Theme.json(theme_full_path);
+			document.theme.path = theme_full_path;
+		}
 		return document;
 	}
 	
diff --git a/src/ease-temp.vala b/src/ease-temp.vala
index 8240da3..ae5ea8b 100644
--- a/src/ease-temp.vala
+++ b/src/ease-temp.vala
@@ -144,12 +144,19 @@ public static class Ease.Temp : Object
 		{
 			var fpath = Path.build_filename(path, entry.pathname());
 			var file = GLib.File.new_for_path(fpath);
+			
 			if (Posix.S_ISDIR(entry.mode()))
 			{
 				file.make_directory_with_parents(null);
 			}
 			else
 			{
+				var parent = file.get_parent();
+				if (!parent.query_exists(null))
+				{
+					parent.make_directory_with_parents(null);
+				}
+				
 				file.create(FileCreateFlags.REPLACE_DESTINATION, null);
 				int fd = Posix.open(fpath, Posix.O_WRONLY, 0644);
 				archive.read_data_into_fd(fd);
@@ -195,55 +202,30 @@ public static class Ease.Temp : Object
 		}
 		
 		// add files
-		archive_recursive_write(archive, dir, buffer, "", temp_path);
-		
-		// close the archive
-		arc_fail(archive.close(), archive);
-	}
-	
-	private static void archive_recursive_write(Archive.Write archive,
-	                                            Dir dir,
-	                                            char[] buffer,
-	                                            string path_so_far,
-	                                            string temp_path) throws Error
-	{
-		string child_path;
-		while ((child_path = dir.read_name()) != null)
-		{
-			debug(child_path);
-			var child_full_path = Path.build_filename(temp_path, child_path);
-			
+		recursive_directory(temp_path, null, (path, full_path) => {
+			// create an archive entry for the file
 			var entry = new Archive.Entry();
-			entry.set_pathname(Path.build_path(path_so_far, child_path));
+			entry.set_pathname(path);
 			entry.set_perm(0644);
 			Posix.Stat st;
-			Posix.stat(child_full_path, out st);
+			Posix.stat(full_path, out st);
 			entry.copy_stat(st);
 			arc_fail(archive.write_header(entry), archive);
 			
-			if (FileUtils.test(child_full_path, FileTest.IS_DIR))
-			{
-				arc_fail(archive.finish_entry(), archive);
-				var child_dir = GLib.Dir.open(child_full_path, 0);
-				archive_recursive_write(archive, child_dir, buffer,
-				                        Path.build_path(path_so_far,
-				                                        child_path),
-				                        temp_path);
-			}
-			else
+			// write the file
+			var fd = Posix.open(full_path, Posix.O_RDONLY);
+			var len = Posix.read(fd, buffer, sizeof(char) * ARCHIVE_BUFFER);
+			while(len > 0)
 			{
-				// write the file
-				var fd = Posix.open(child_full_path, Posix.O_RDONLY);
-				var len = Posix.read(fd, buffer, sizeof(char) * ARCHIVE_BUFFER);
-				while(len > 0)
-				{
-					archive.write_data(buffer, len);
-					len = Posix.read(fd, buffer, sizeof(char) * ARCHIVE_BUFFER);
-				}
-				Posix.close(fd);
-				arc_fail(archive.finish_entry(), archive);
+				archive.write_data(buffer, len);
+				len = Posix.read(fd, buffer, sizeof(char) * ARCHIVE_BUFFER);
 			}
-		}
+			Posix.close(fd);
+			arc_fail(archive.finish_entry(), archive);
+		});
+		
+		// close the archive
+		arc_fail(archive.close(), archive);
 	}
 	
 	/**
@@ -260,9 +242,7 @@ public static class Ease.Temp : Object
 	 */
 	public static void clean()
 	{
-		if (dirs == null) {
-			return;
-		}
+		if (dirs == null) return;
 
 		string dir;
 		while ((dir = dirs.poll_head()) != null)
diff --git a/src/ease-theme.vala b/src/ease-theme.vala
index 4f3b973..c4dda8e 100644
--- a/src/ease-theme.vala
+++ b/src/ease-theme.vala
@@ -22,7 +22,7 @@ public class Ease.Theme : GLib.Object
 {
 	// file paths
 	private const string DEFAULTS_PATH = "theme-defaults.json";
-	private const string JSON_PATH = "Theme.json";
+	public const string JSON_PATH = "Theme.json";
 	private const string MEDIA_PATH = "Media";
 	
 	// json root elements
@@ -181,11 +181,12 @@ public class Ease.Theme : GLib.Object
 	/**
 	 * Loads a Theme from pure JSON, (no archive).
 	 *
-	 * This constructor is used to load the defaults.
+	 * This constructor is used to load the defaults. It is also used when
+	 * loading a previously saved { link Document}.
 	 *
 	 * @param json_path The path to the JSON file.
 	 */
-	private Theme.json(string json_path)
+	public Theme.json(string json_path)
 	{
 		load_from_json(json_path);
 	}
diff --git a/src/ease-utilities.vala b/src/ease-utilities.vala
index 31f8d71..ba9bb8d 100644
--- a/src/ease-utilities.vala
+++ b/src/ease-utilities.vala
@@ -86,6 +86,68 @@ namespace Ease
 		}
 		return null;
 	}
+	
+	/**
+	 * Performs a recursive iteration on a directory, with callbacks.
+	 *
+	 * The caller can provide two { link RecursiveDirAction}s: one for files,
+	 * and another for directories. These callbacks can both be null
+	 * (although if they both were, the call would do nothing). The directory
+	 * callback is executed before the recursion continues.
+	 *
+	 * The directory callback is not performed on the toplevel directory.
+	 *
+	 * @param directory The directory to iterate.
+	 * @param directory_action A { link RecursiveDirAction} to perform on all
+	 * directories.
+	 * @param file_action A { link RecursiveDirAction} to perform on all files.
+	 */
+	public void recursive_directory(string directory,
+	                                RecursiveDirAction? directory_action,
+	                                RecursiveDirAction? file_action)
+	                                throws Error
+	{
+		do_recursive_directory(directory, directory_action, file_action, "");
+	}
+	
+	/**
+	 * Used for execution of recursive_directory(). Should never be called, 
+	 * except by that function.
+	 */
+	private void do_recursive_directory(string directory,
+	                                    RecursiveDirAction? directory_action,
+	                                    RecursiveDirAction? file_action,
+	                                    string rel_path)
+	                                    throws Error
+	{
+		var dir = GLib.Dir.open(directory, 0);
+		string child_path;
+		
+		while ((child_path = dir.read_name()) != null)
+		{
+			var child_full_path = Path.build_filename(directory, child_path);
+			var child_rel_path = Path.build_filename(rel_path, child_path);
+			if (FileUtils.test(child_full_path, FileTest.IS_DIR))
+			{
+				if (directory_action != null)
+				{
+					directory_action(child_rel_path, child_full_path);
+				}
+				do_recursive_directory(child_full_path,
+				                       directory_action, file_action,
+				                       child_rel_path);
+			}
+			else // the path is a file
+			{
+				if (file_action != null)
+				{
+					file_action(child_rel_path, child_full_path);
+				}
+			}
+		}
+	}
+	
+	public delegate void RecursiveDirAction(string path, string full_path);
 
 	public double dmax(double a, double b)
 	{



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