[f-spot] Rewrite import to be more sane.



commit 6a1e5614951acf1b0d493028339231b1434a3a0e
Author: Ruben Vermeersch <ruben savanne be>
Date:   Sat May 15 20:43:57 2010 +0200

    Rewrite import to be more sane.
    
    Now it only imports when you click Import. Much more sane and I have the
    impression that it's a bit faster too.
    
    Still leaks quite a bit (fixing that is the next task) and certainly not
    the definitive solution.
    
    All of import needs to be replaced and modernized.

 src/CameraFileSelectionDialog.cs     |   17 ++-
 src/Core/App.cs                      |    4 +-
 src/FileImportBackend.cs             |  193 +++++++++++-----------------
 src/ImportBackend.cs                 |    8 +-
 src/ImportCommand.cs                 |  237 ++++++++++++++--------------------
 src/MainWindow.cs                    |    8 +-
 src/Makefile.am                      |    2 +
 src/PhotoList.cs                     |    6 +
 src/Utils/RecursiveFileEnumerator.cs |   52 ++++++++
 src/XmpTagsImporter.cs               |    7 +-
 10 files changed, 256 insertions(+), 278 deletions(-)
---
diff --git a/src/CameraFileSelectionDialog.cs b/src/CameraFileSelectionDialog.cs
index d1a135e..d1c3387 100644
--- a/src/CameraFileSelectionDialog.cs
+++ b/src/CameraFileSelectionDialog.cs
@@ -10,6 +10,7 @@
 
 using System;
 using System.IO;
+using System.Collections.Generic;
 using Gdk;
 using Gtk;
 using Glade;
@@ -41,7 +42,7 @@ namespace FSpot {
 		ThreadProgressDialog progress_dialog;
 		System.Collections.ArrayList index_list;
 		
-		string[] saved_files;
+		Uri[] saved_files;
 		Tag[] selected_tags;
 		
 		System.Threading.Thread command_thread;
@@ -213,7 +214,7 @@ namespace FSpot {
 		private void Download ()
 		{
 			lock (camera) {
-				System.Collections.ArrayList saved = new System.Collections.ArrayList ();
+				List<Uri> saved = new List<Uri> ();
 					
 				for (int i = 0; i < index_list.Count; i++) {
 					try {
@@ -225,7 +226,7 @@ namespace FSpot {
 						SaveResult result = SaveFile ((int)(index_list [i]));
 
 						if (!result.IsDuplicate)
-						 	saved.Add (result.Path);
+						 	saved.Add (UriUtils.PathToFileUri(result.Path));
 
 						progress_dialog.Fraction = (i + 1)/(double)index_list.Count;
 					}
@@ -239,7 +240,7 @@ namespace FSpot {
 					}
 				}
 					
-				saved_files = (string []) saved.ToArray (typeof (string));
+				saved_files = saved.ToArray ();
 					
 				progress_dialog.SetProperties (Catalog.GetString ("Download Complete"), Gtk.Stock.Ok, Catalog.GetString ("Done Copying Files"), 1.0);
 			}
@@ -276,10 +277,10 @@ namespace FSpot {
 
 				return new SaveResult (path, true);
 			} else {
-				string dest = FileImportBackend.ChooseLocation (path);
-				System.IO.File.Move (path, dest);
+				Uri dest = FileImportBackend.ChooseLocation (UriUtils.PathToFileUri (path));
+				System.IO.File.Move (path, dest.AbsolutePath);
 
-				return new SaveResult (dest, false);
+				return new SaveResult (dest.AbsolutePath, false);
 			}
 		}
 
@@ -305,7 +306,7 @@ namespace FSpot {
 		private int ImportFiles ()
 		{
 			ImportCommand command = new ImportCommand (null);
-			return command.ImportFromPaths (db.Photos, saved_files, selected_tags);
+			return command.ImportFromUris (db.Photos, saved_files, selected_tags);
 		}
 		
 		public Tag[] Tags {
diff --git a/src/Core/App.cs b/src/Core/App.cs
index d82f4b6..883ee80 100644
--- a/src/Core/App.cs
+++ b/src/Core/App.cs
@@ -204,10 +204,8 @@ namespace FSpot
 			Organizer.Window.Present ();
 			if (path != null && path.StartsWith ("gphoto2:"))
 				Organizer.ImportCamera (path);
-			else if (path != null && path.StartsWith ("file:"))
-				Organizer.ImportFile (Uri.UnescapeDataString ((new Uri(path)).AbsolutePath));
 			else
-				Organizer.ImportFile (path);
+				Organizer.ImportFile (path == null ? null : new Uri(path));
 		}
 
 		void HandleOrganize ()
diff --git a/src/FileImportBackend.cs b/src/FileImportBackend.cs
index b737975..5be6ad4 100644
--- a/src/FileImportBackend.cs
+++ b/src/FileImportBackend.cs
@@ -23,94 +23,56 @@ public class FileImportBackend : ImportBackend {
 	bool recurse;
 	bool copy;
 	bool detect_duplicates;
-	string [] base_paths;
+	Uri [] base_paths;
 	Tag [] tags;
 	Gtk.Window parent;
 
+	bool cancel = false;
 	int count;
 	int duplicate_count;
 	XmpTagsImporter xmptags;
 
-	ArrayList import_info;
+	List<IBrowsableItem> import_info;
 	Stack directories;
 
-	private class ImportInfo {
-		string original_path;
-		public string destination_path;
-		public Photo Photo;
-	       
-		public string OriginalPath {
-			get { return original_path; }
-		}
-		
-		public string DestinationPath {
-			get { return destination_path; }
-			set { destination_path = value; }
-		}
-		
-		public ImportInfo (string original)
+	private class ImportInfo : IBrowsableItem {
+		public ImportInfo (Uri original)
 		{
-			original_path = original;
-		        destination_path = null;
-			Photo = null;
-		}
-	}
-	
-	private void AddPath (string path)
-	{
-		if (FSpot.ImageFile.HasLoader (path))
-			import_info.Add (new ImportInfo (path));
-	}
-
-	private void GetListing (System.IO.DirectoryInfo info)
-	{
-		try {
-			GetListing (info, info.GetFiles (), recurse);
-		} catch (System.UnauthorizedAccessException) {
-			System.Console.WriteLine ("Unable to access directory {0}", info.FullName);
-		} catch (System.Exception e) {
-			System.Console.WriteLine ("{0}", e.ToString ());
+			DefaultVersionUri = original;
+			try {
+				using (FSpot.ImageFile img = FSpot.ImageFile.Create (original)) {
+					Time = img.Date;
+				}
+			} catch (Exception) {
+				Time = DateTime.Now;
+			}
 		}
-	}
 
-	private void GetListing (System.IO.DirectoryInfo dirinfo, System.IO.FileInfo [] files, bool recurse)
-	{
-		Log.Debug ("Scanning {0} for new photos", dirinfo.FullName);
-		List<Uri> existing_entries = new List<Uri> ();
+		public System.Uri DefaultVersionUri { get; private set; }
+		public System.Uri DestinationUri { get; set; }
 
-		foreach (Photo p in store.Query (new Uri (dirinfo.FullName + "/")))
-			foreach (uint id in p.VersionIds)
-				existing_entries.Add (p.VersionUri (id));
+		public System.DateTime Time { get; private set; }
+        
+		public Tag [] Tags { get { throw new NotImplementedException (); } }
+		public string Description { get { throw new NotImplementedException (); } }
+		public string Name { get { throw new NotImplementedException (); } }
+		public uint Rating { get { return 0; } }
 
-		foreach (System.IO.FileInfo f in files)
-			if (! existing_entries.Contains (UriUtils.PathToFileUri (f.FullName)) && !f.Name.StartsWith (".")) {
-				AddPath (f.FullName);
-			}
-
-		if (recurse) {
-			foreach (System.IO.DirectoryInfo d in dirinfo.GetDirectories ()){
-				if (!d.Name.StartsWith ("."))
-					GetListing (d);
-			}
-		}
+		internal Photo Photo { get; set; }
 	}
 
-	public override int Prepare ()
+	public override List<IBrowsableItem> Prepare ()
 	{
 		if (import_info != null)
 			throw new ImportException ("Busy");
 
-		import_info = new ArrayList ();
-
-		foreach (string path in base_paths) {
-			try {	
-				if (System.IO.Directory.Exists (path))
-					GetListing (new System.IO.DirectoryInfo (path));
-				else if (System.IO.File.Exists (path))
-					GetListing (new System.IO.DirectoryInfo (System.IO.Path.GetDirectoryName (path)), 
-						    new System.IO.FileInfo [] { new System.IO.FileInfo (path)}, false);
-			} catch (Exception e) {
-				System.Console.WriteLine (e.ToString ());
+		import_info = new List<IBrowsableItem> ();
+
+		foreach (Uri uri in base_paths) {
+			var enumerator = new RecursiveFileEnumerator (uri, recurse);
+			foreach (var file in enumerator) {
+				if (FSpot.ImageFile.HasLoader (file.Uri))
+					import_info.Add (new ImportInfo (file.Uri));
 			}
 		}	
 
@@ -120,10 +82,11 @@ public class FileImportBackend : ImportBackend {
 		roll = rolls.Create ();
 		Photo.ResetMD5Cache ();
 
-		return import_info.Count;
+		return import_info;
 	}
+	
 
-	public static string UniqueName (string path, string filename)
+	static Uri UniqueName (string path, string filename)
 	{
 		int i = 1;
 		string dest = System.IO.Path.Combine (path, filename);
@@ -137,19 +100,20 @@ public class FileImportBackend : ImportBackend {
 			dest = System.IO.Path.Combine (path, numbered_name);
 		}
 		
-		return dest;
+		return new Uri ("file://"+dest);
 	}
 	
-	public static string ChooseLocation (string path)
+	public static Uri ChooseLocation (Uri uri)
 	{
-		return ChooseLocation (path, null);
+		return ChooseLocation (uri, null);
 	}
 
-	public static string ChooseLocation (string path, Stack created_directories)
+	private static Uri ChooseLocation (Uri uri, Stack created_directories)
 	{
-		string name = System.IO.Path.GetFileName (path);
+		var segments = uri.Segments;
+		string name = segments [segments.Length - 1];
 		DateTime time;
-		using (FSpot.ImageFile img = FSpot.ImageFile.Create (path)) {
+		using (FSpot.ImageFile img = FSpot.ImageFile.Create (uri)) {
 			time = img.Date;
 		}
 
@@ -185,10 +149,10 @@ public class FileImportBackend : ImportBackend {
 		}
 
 		// If the destination we'd like to use is the file itself return that
-		if (Path.Combine (dest_dir, name) == path)
-			return path;
+		if ("file://" + Path.Combine (dest_dir, name) == uri.ToString ())
+			return uri;
 		 
-		string dest = UniqueName (dest_dir, name);
+		Uri dest = UniqueName (dest_dir, name);
 		
 		return dest;
 	}
@@ -210,50 +174,40 @@ public class FileImportBackend : ImportBackend {
 		bool needs_commit = false;
 		bool abort = false;
 		try {
-			string destination = info.OriginalPath;
+			Uri destination = info.DefaultVersionUri;
 			if (copy)
-				destination = ChooseLocation (info.OriginalPath, directories);
+				destination = ChooseLocation (info.DefaultVersionUri, directories);
 
 			// Don't copy if we are already home
-			if (info.OriginalPath == destination) {
-				info.DestinationPath = destination;
+			if (info.DefaultVersionUri == destination) {
+				info.DestinationUri = destination;
 
 				if (detect_duplicates)
-					photo = store.CheckForDuplicate (UriUtils.PathToFileUri (destination));
+					photo = store.CheckForDuplicate (destination);
 
 				if (photo == null)
-					photo = store.Create (UriUtils.PathToFileUri (info.DestinationPath), roll.Id);
+					photo = store.Create (info.DestinationUri, roll.Id);
 				else
 				 	is_duplicate = true;
 			} else {
-				System.IO.File.Copy (info.OriginalPath, destination);
-				System.IO.File.SetAttributes (destination, System.IO.FileAttributes.Normal);
-				info.DestinationPath = destination;
+				var file = GLib.FileFactory.NewForUri (info.DefaultVersionUri);
+				var new_file = GLib.FileFactory.NewForUri (destination);
+				file.Copy (new_file, GLib.FileCopyFlags.AllMetadata, null, null);
+				info.DestinationUri = destination;
 
 				if (detect_duplicates)
-				 	photo = store.CheckForDuplicate (UriUtils.PathToFileUri (destination));
+					photo = store.CheckForDuplicate (destination);
 
 				if (photo == null)
 				{
-					photo = store.Create (UriUtils.PathToFileUri (info.DestinationPath),
-					                      UriUtils.PathToFileUri (info.OriginalPath),
+					photo = store.Create (info.DestinationUri,
+					                      info.DefaultVersionUri,
 					                      roll.Id);
-				 	
-
-					try {
-						File.SetAttributes (destination, File.GetAttributes (info.DestinationPath) & ~FileAttributes.ReadOnly);
-						DateTime create = File.GetCreationTime (info.OriginalPath);
-						File.SetCreationTime (info.DestinationPath, create);
-						DateTime mod = File.GetLastWriteTime (info.OriginalPath);
-						File.SetLastWriteTime (info.DestinationPath, mod);
-					} catch (IOException) {
-						// we don't want an exception here to be fatal.
-					}
 				}
 				else
 				{
 					is_duplicate = true; 
-					System.IO.File.Delete (destination);
+					new_file.Delete (null);
 				}
 			} 
 
@@ -266,15 +220,15 @@ public class FileImportBackend : ImportBackend {
 					needs_commit = true;
 				}
 
-				needs_commit |= xmptags.Import (photo, info.DestinationPath, info.OriginalPath);
+				needs_commit |= xmptags.Import (photo, info.DestinationUri, info.DefaultVersionUri);
 
 				if (needs_commit)
 					store.Commit(photo);
 
-				info.Photo = photo;
+                info.Photo = photo;
 			}
 		} catch (System.Exception e) {
-			System.Console.WriteLine ("Error importing {0}{2}{1}", info.OriginalPath, e.ToString (), Environment.NewLine);
+			System.Console.WriteLine ("Error importing {0}{2}{1}", info.DestinationUri.ToString (), e.ToString (), Environment.NewLine);
 			photo = null;
 
 			HigMessageDialog errordialog = new HigMessageDialog (parent,
@@ -282,7 +236,7 @@ public class FileImportBackend : ImportBackend {
 									     Gtk.MessageType.Error,
 									     Gtk.ButtonsType.Cancel,
 									     Catalog.GetString ("Import error"),
-									     String.Format(Catalog.GetString ("Error importing {0}{2}{2}{1}"), info.OriginalPath, e.Message, Environment.NewLine ));
+									     String.Format(Catalog.GetString ("Error importing {0}{2}{2}{1}"), info.DefaultVersionUri.ToString (), e.Message, Environment.NewLine ));
 			errordialog.AddButton (Catalog.GetString ("Skip"), Gtk.ResponseType.Reject, false);
 			ResponseType response = (ResponseType) errordialog.Run ();
 			errordialog.Destroy ();
@@ -293,10 +247,14 @@ public class FileImportBackend : ImportBackend {
 		this.count ++;
 
 		if (is_duplicate)
-		 	this.duplicate_count ++;
+			this.duplicate_count ++;
 
 		status_info = new StepStatusInfo (photo, this.count, is_duplicate);
 
+		if (cancel) {
+			abort = true;
+		}
+
 		return (!abort && count != import_info.Count);
 	}
 
@@ -305,13 +263,16 @@ public class FileImportBackend : ImportBackend {
 		if (import_info == null)
 			throw new ImportException ("Not doing anything");
 
-		foreach (ImportInfo info in import_info) {
+		foreach (var item in import_info) {
+            ImportInfo info = item as ImportInfo;
 			
-			if (info.OriginalPath != info.DestinationPath) {
+			if (info.DefaultVersionUri != info.DestinationUri && info.DestinationUri != null) {
 				try {
-					System.IO.File.Delete (info.DestinationPath);
+					var file = GLib.FileFactory.NewForUri (info.DestinationUri);
+					if (file.QueryExists (null))
+						file.Delete (null);
 				} catch (System.ArgumentNullException) {
-					// Do nothing, since if DestinationPath == null, we do not have to remove it
+					// Do nothing, since if DestinationUri == null, we do not have to remove it
 				} catch (System.Exception e) {
 					System.Console.WriteLine (e);
 				}
@@ -354,17 +315,17 @@ public class FileImportBackend : ImportBackend {
 		Photo.ResetMD5Cache ();
 
 		if (count == duplicate_count)
-		 	rolls.Remove (roll);
+			rolls.Remove (roll);
 
 		count = duplicate_count = 0;
 		//rolls.EndImport();    // Clean up the imported session.
 	}
 
-	public FileImportBackend (PhotoStore store, string [] base_paths, bool recurse, Gtk.Window parent) : this (store, base_paths, false, recurse, false, null, parent) {}
+	public FileImportBackend (PhotoStore store, Uri [] base_paths, bool recurse, Gtk.Window parent) : this (store, base_paths, false, recurse, false, null, parent) {}
 
-	public FileImportBackend (PhotoStore store, string [] base_paths, bool copy, bool recurse, Tag [] tags, Gtk.Window parent) : this (store, base_paths, copy, recurse, false, null, parent) {}
+	public FileImportBackend (PhotoStore store, Uri [] base_paths, bool copy, bool recurse, Tag [] tags, Gtk.Window parent) : this (store, base_paths, copy, recurse, false, null, parent) {}
 
-	public FileImportBackend (PhotoStore store, string [] base_paths, bool copy, bool recurse, bool detect_duplicates, Tag [] tags, Gtk.Window parent)
+	public FileImportBackend (PhotoStore store, Uri [] base_paths, bool copy, bool recurse, bool detect_duplicates, Tag [] tags, Gtk.Window parent)
 	{
 		this.store = store;
 		this.copy = copy;
diff --git a/src/ImportBackend.cs b/src/ImportBackend.cs
index d50891e..ed51b6b 100644
--- a/src/ImportBackend.cs
+++ b/src/ImportBackend.cs
@@ -1,10 +1,10 @@
 using FSpot;
-using Gdk;
+using System.Collections.Generic;
 
 public abstract class ImportBackend {
-	// Prepare for importing; returns the number of pictures available.
-	// If it returns zero, you should not call Step(), Cancel() or Finish() until you call Prepare() again.
-	public abstract int Prepare ();
+	// Prepare for importing; returns the items that should be imported
+	// If it returns an empty list, you should not call Step(), Cancel() or Finish() until you call Prepare() again.
+	public abstract List<IBrowsableItem> Prepare ();
 
 	// Import one picture.  Returns false when done; then you have to call Finish().
 	public abstract bool Step (out StepStatusInfo import_info);
diff --git a/src/ImportCommand.cs b/src/ImportCommand.cs
index 6df8822..307010f 100644
--- a/src/ImportCommand.cs
+++ b/src/ImportCommand.cs
@@ -58,11 +58,11 @@ public class ImportCommand : GladeDialog
 
 	internal class VfsSource : ImportSource
 	{
-		public string uri;
+		public Uri uri;
 
-		public VfsSource (string uri)
+		public VfsSource (Uri uri)
 		{ 
-			string [] components = uri.Split (new char [] { '/' });
+			string [] components = uri.Segments;
 			this.Name = components [components.Length - 1];
 			if (this.Name == String.Empty)
 				this.Name = components [components.Length - 2];
@@ -72,11 +72,6 @@ public class ImportCommand : GladeDialog
 			this.Icon = GtkUtil.TryLoadIcon (FSpot.Global.IconTheme, "stock_folder", 32, (Gtk.IconLookupFlags)0);
 		}
 
-		public virtual bool Contains (string path)
-		{
-			return false;
-		}
-
 		protected VfsSource () {}
 	}
 
@@ -96,7 +91,7 @@ public class ImportCommand : GladeDialog
 				System.Console.WriteLine (e);
 			}
 
-			uri = mount_point;
+			uri = mount.Root.Uri;
 			
 			
 			if (this.IsIPodPhoto)
@@ -207,7 +202,7 @@ public class ImportCommand : GladeDialog
 						if (handle.StartsWith ("disk:")) {
 							string path = handle.Substring ("disk:".Length);
 
-							if (FindItemPosition (path) != -1)
+							if (FindItemPosition (UriUtils.PathToFileUri (path)) != -1)
 								continue;
 						}
 			
@@ -251,14 +246,14 @@ public class ImportCommand : GladeDialog
 			return -1;
 		}
 		
-		public int FindItemPosition (string path)
+		public int FindItemPosition (Uri uri)
 		{
 			Gtk.Widget [] children = this.Children;
-			System.Console.WriteLine ("looking for {0}", path);
+			System.Console.WriteLine ("looking for {0}", uri);
 			for (int i = 0; i < children.Length; i++) {
 				if (children [i] is SourceItem) {
 					VfsSource vfs = ((SourceItem)(children [i])).Source as VfsSource;
-					if (vfs != null && (vfs.uri == path || path == (vfs.uri + "/dcim")))
+					if (vfs != null && (vfs.uri == uri || uri.ToString () == (vfs.uri + "/dcim")))
 						return i;
 				}
 			}
@@ -301,10 +296,7 @@ public class ImportCommand : GladeDialog
 
 	string loading_string;
 
-	string import_path;
-	public string ImportPath {
-		get { return import_path; }
-	}
+	public Uri ImportUri { get; private set; }
 	
 	private SourceItem Source {
 		set {
@@ -315,26 +307,22 @@ public class ImportCommand : GladeDialog
 			
 			this.Cancel ();
 			this.copy = copy_check.Active;
-			AllowFinish = false;
-
-			System.Console.WriteLine ("item {0}", item);
 
 			if (!item.Sensitive)
 				return;
 
 			if (item.Source is BrowseSource) {
-				string path = ChoosePath ();
+				Uri uri = ChooseUri ();
 				
-				if (path != null) {
-					SourceItem path_item = new SourceItem (new VfsSource (path));
-					menu.Prepend (path_item);
-					path_item.ShowAll ();
-					//option.SetHistory (0);
-					SetImportPath (path);
+				if (uri != null) {
+					SourceItem uri_item = new SourceItem (new VfsSource (uri));
+					menu.Prepend (uri_item);
+					uri_item.ShowAll ();
+					ImportUri = uri;
 				}
 			} else if (item.Source is VfsSource) {
 				VfsSource vfs = item.Source as VfsSource;
-				SetImportPath (vfs.uri);
+				ImportUri = vfs.uri;
 			} else if (item.Source is CameraSource) {
 				CameraSource csource = item.Source as CameraSource;
 				string port = "gphoto2:" + csource.Port;
@@ -352,7 +340,7 @@ public class ImportCommand : GladeDialog
 		main_window = mw;
 		step = new FSpot.Delay (new GLib.IdleHandler (Step));
 		idle_start = new FSpot.Delay (new IdleHandler (Start));
-		loading_string = Catalog.GetString ("Loading {0} of {1}");
+		loading_string = Catalog.GetString ("Importing {0} of {1}");
 	}
 
 	private void HandleDialogResponse (object obj, ResponseArgs args)
@@ -362,6 +350,23 @@ public class ImportCommand : GladeDialog
 			this.Dialog.Destroy ();
 			return;
 		}
+
+		AllowFinish = false;
+		OptionsEnabled = false;
+		if (total > 0) {
+			UpdateProgressBar (1, total);
+			step.Start ();
+
+			while (total > 0 && this.Step ()) {
+				System.DateTime start_time = System.DateTime.Now;
+				System.TimeSpan span = start_time - start_time;
+
+				while (Application.EventsPending () && span.TotalMilliseconds < 100) {
+					span = System.DateTime.Now - start_time;
+					Application.RunIteration ();
+				}
+			}
+		}
 	}
 
 	private void UpdateProgressBar (int count, int total)
@@ -369,6 +374,8 @@ public class ImportCommand : GladeDialog
 		if (progress_bar == null)
 			return;
 
+		if (count > 0)
+			progress_bar.Show ();
 		progress_bar.Text = String.Format (loading_string, count, total);
 		progress_bar.Fraction = (double) count / System.Math.Max (total, 1);
 	}
@@ -382,7 +389,7 @@ public class ImportCommand : GladeDialog
 
 	private bool Step ()
 	{	
-	 	StepStatusInfo status_info;		
+		StepStatusInfo status_info;		
 		bool ongoing = true;
 
 		if (importer == null)
@@ -397,15 +404,6 @@ public class ImportCommand : GladeDialog
 			return false;
 		}
 
-		if (!status_info.IsDuplicate && (status_info.Photo == null)) {
-			Console.WriteLine ("Could not import file");
-		} else {
-			//icon_scrolled.Visible = true;
-		 	if (!status_info.IsDuplicate)
-				collection.Add (status_info.Photo);
-
-		}
-		
 		if (status_info.Count < total)
 			UpdateProgressBar (status_info.Count + 1, total);
 
@@ -424,8 +422,19 @@ public class ImportCommand : GladeDialog
 	public bool AllowFinish
 	{
 		set {
-			if (this.ok_button != null)
-				this.ok_button.Sensitive = value;
+			if (ok_button != null)
+				ok_button.Sensitive = value;
+		}
+	}
+
+	public bool OptionsEnabled
+	{
+		set {
+			if (source_option_menu != null) source_option_menu.Sensitive = value;
+			if (copy_check != null) copy_check.Sensitive = value;
+			if (recurse_check != null) recurse_check.Sensitive = value;
+			if (duplicate_check != null) duplicate_check.Sensitive = value;
+			if (tagentry_box != null) tagentry_box.Sensitive = value;
 		}
 	}
 
@@ -437,13 +446,14 @@ public class ImportCommand : GladeDialog
 		this.importer = imp;
 		AllowFinish = false;
 		
-		total = importer.Prepare ();
+		var info = importer.Prepare ();
+		total = info.Count;
 
 		if (total > 0)
 			UpdateProgressBar (1, total);
 		
 		collection.Clear ();
-		collection.Capacity = total;
+		collection.AddAll (info);
 
 		while (total > 0 && this.Step ()) {
 			System.DateTime start_time = System.DateTime.Now;
@@ -480,15 +490,15 @@ public class ImportCommand : GladeDialog
 	
 	public void HandleImportBrowse (object o, EventArgs args) 
 	{
-		string path = ChoosePath ();
-		if (path != null) {
-			SetImportPath (path);
+		Uri uri = ChooseUri ();
+		if (uri != null) {
+			ImportUri = uri;
 		}
 	}
 	
-	public string ChoosePath ()
+	public Uri ChooseUri ()
 	{
-		string path = null;
+		Uri uri = null;
 
 		FileChooserDialog file_chooser =
 			new FileChooserDialog (Catalog.GetString ("Import"), this.Dialog,
@@ -498,33 +508,21 @@ public class ImportCommand : GladeDialog
 
 		file_chooser.SelectMultiple = false;
 
-		if (ImportPath != null)
-			file_chooser.SetFilename (ImportPath);
+		if (ImportUri != null)
+			file_chooser.SetCurrentFolderUri (ImportUri.ToString ());
 		else
 			file_chooser.SetFilename (FSpot.Global.HomeDirectory);
 
 		int response = file_chooser.Run ();
 
 		if ((ResponseType) response == ResponseType.Ok) {
-			path = file_chooser.Filename;
+			uri = new Uri (file_chooser.Uri);
 		}
 
 		file_chooser.Destroy ();
-		return path;
+		return uri;
 	}
 
-	public void SetImportPath (string path)
-	{
-		import_path = path;
-	}
-
-//	private void HandleTagMenuSelected (Tag t) 
-//	{
-//		tag_selected = t;
-//		//tag_image.Pixbuf = t.Icon;
-//		//tag_label.Text = t.Name;
-//	}
-
 	private void HandleRecurseToggled (object sender, System.EventArgs args)
 	{
 		this.Cancel ();
@@ -546,7 +544,7 @@ public class ImportCommand : GladeDialog
 		duplicate_check.Active = Preferences.Get<bool> (Preferences.IMPORT_CHECK_DUPLICATES);
 	}
 
-	public int ImportFromFile (PhotoStore store, string path)
+	public int ImportFromUri (PhotoStore store, Uri uri)
 	{
 		this.store = store;
 		this.CreateDialog ("import_dialog");
@@ -595,19 +593,22 @@ public class ImportCommand : GladeDialog
 		tag_entry.Show ();
 
 		this.Dialog.Show ();
+        progress_bar.Hide ();
 
 		//source_option_menu.Changed += HandleSourceChanged;
-		if (path != null) {
-			SetImportPath (path);
-			int i = menu.FindItemPosition (path);
+		if (uri != null) {
+			ImportUri = uri;
+			int i = menu.FindItemPosition (uri);
+
+			var file = FileFactory.NewForUri (uri);
 
 			if (i > 0) {
 				source_option_menu.SetHistory ((uint)i);
-			} else if (Directory.Exists (path)) {
-				SourceItem path_item = new SourceItem (new VfsSource (path));
-				menu.Prepend (path_item);
-				path_item.ShowAll ();
-				SetImportPath (path);
+			} else if (file.QueryExists (null)) {
+				SourceItem uri_item = new SourceItem (new VfsSource (uri));
+				menu.Prepend (uri_item);
+				uri_item.ShowAll ();
+				ImportUri = uri;
 				source_option_menu.SetHistory (0);
 			} 
 			idle_start.Start ();
@@ -617,7 +618,8 @@ public class ImportCommand : GladeDialog
 		
 		while (response == ResponseType.Ok) {
 			try {
-				if (Directory.Exists (this.ImportPath))
+				var file = FileFactory.NewForUri (uri);
+				if (file.QueryExists (null))
 					break;
 			} catch (System.Exception e){
 				System.Console.WriteLine (e);
@@ -630,7 +632,7 @@ public class ImportCommand : GladeDialog
 				ButtonsType.Ok,
 				Catalog.GetString ("Directory does not exist."),
 				String.Format (Catalog.GetString ("The directory you selected \"{0}\" does not exist.  " + 
-								  "Please choose a different directory"), this.ImportPath));
+								  "Please choose a different directory"), ImportUri));
 
 			md.Run ();
 			md.Destroy ();
@@ -709,27 +711,17 @@ public class ImportCommand : GladeDialog
 			importer.Cancel ();
 			importer = null;
 		}
-		
-		if (collection == null || collection.Count == 0)
-			return;
-		
-		Photo [] photos = new Photo [collection.Count];
-		for (int i = 0; i < collection.Count; i++)
-			photos [i] = (Photo) collection [i];
-
-		store.Remove (photos);
 	}
 
-	public bool Start ()
+	private bool Start ()
 	{
 		if (Dialog != null)
 			Dialog.Sensitive = true;
 
-		if (import_path == null)
+		if (ImportUri == null)
 			return false;
 
-		string [] pathimport =  {ImportPath};
-		//this.Dialog.Destroy();
+		Uri [] uriimport =  {ImportUri};
 		
 		if (copy_check != null)
 			copy = copy_check.Active;
@@ -740,78 +732,41 @@ public class ImportCommand : GladeDialog
 
 		bool detect_duplicates = false;
 		if (duplicate_check != null)
-		 	detect_duplicates = duplicate_check.Active;
-		
-//		importer = new FileImportBackend (store, pathimport, copy, recurse, null);
-		importer = new FileImportBackend (store, pathimport, copy, recurse, detect_duplicates, null, Dialog);
-		AllowFinish = false;
-		
-		total = importer.Prepare ();
-		
-		if (total > 0)
-			UpdateProgressBar (1, total);
+			detect_duplicates = duplicate_check.Active;
 		
+		importer = new FileImportBackend (store, uriimport, copy, recurse, detect_duplicates, null, Dialog);
+
 		collection.Clear ();
-		collection.Capacity = total;
+		AllowFinish = false;
+
+		var info = importer.Prepare ();
+		total = info.Count;
+
+		AllowFinish = true;
+		collection.AddAll (info);
 
-		if (total > 0)
-			step.Start ();
-	       
 		return false;
 	}
 
-	public int ImportFromPaths (PhotoStore store, string [] paths, bool copy)
+	public int ImportFromUris (PhotoStore store, Uri [] uris, bool copy)
 	{
-		return ImportFromPaths (store, paths, null, copy);
+		return ImportFromUris (store, uris, null, copy);
 	}
 	
-	public int ImportFromPaths (PhotoStore store, string [] paths, Tag [] tags)
+	public int ImportFromUris (PhotoStore store, Uri [] uris, Tag [] tags)
 	{
-		return ImportFromPaths (store, paths, tags, false);
+		return ImportFromUris (store, uris, tags, false);
 	}
 	
-	public int ImportFromPaths (PhotoStore store, string [] paths, Tag [] tags, bool copy)
+	public int ImportFromUris (PhotoStore store, Uri [] uris, Tag [] tags, bool copy)
 	{
 		collection = new FSpot.PhotoList (new Photo [0]);
-		int count = DoImport (new FileImportBackend (store, paths, copy, true, tags, main_window ));
+		int count = DoImport (new FileImportBackend (store, uris, copy, true, tags, main_window ));
 
 		Finish ();
 
 		return count;
 	}
-	
-#if TEST_IMPORT_COMMAND
-
-	private const string db_path = "/tmp/ImportCommandTest.db";
-	private static string directory_path;
-
-	private static bool OnIdleStartImport ()
-	{
-		Db db = new Db (db_path, true);
-
-		ImportCommand command = new ImportCommand ();
-
-		command.ImportFromPath (db.Photos, directory_path, true);
-
-		Application.Quit ();
-		return false;
-	}
-
-	public static void Main (string [] args)
-	{
-		Program program = new Program ("ImportCommandTest", "0.0", Modules.UI, args);
-
-		try {
-			File.Delete (db_path);
-		} catch {}
-
-		directory_path = args [0];
-
-		Idle.Add (new IdleHandler (OnIdleStartImport));
-		program.Run ();
-	}
-
-#endif
 }
 
 public class StepStatusInfo {
diff --git a/src/MainWindow.cs b/src/MainWindow.cs
index 4f4b5e9..0d9fbbe 100644
--- a/src/MainWindow.cs
+++ b/src/MainWindow.cs
@@ -1135,16 +1135,16 @@ namespace FSpot
 		public void ImportUriList (UriList list, bool copy) 
 		{
 			ImportCommand command = new ImportCommand (main_window);
-			if (command.ImportFromPaths (Database.Photos, list.ToLocalPaths (), copy) > 0) {
+			if (command.ImportFromUris (Database.Photos, list.ToArray (), copy) > 0) {
 				query.RollSet = new RollSet (Database.Rolls.GetRolls (1)[0]);
 				UpdateQuery ();
 			}
 		}
 	
-		public void ImportFile (string path)
+		public void ImportFile (Uri uri)
 		{
 			ImportCommand command = new ImportCommand (main_window);
-			if (command.ImportFromFile (Database.Photos, path) > 0) {
+			if (command.ImportFromUri (Database.Photos, uri) > 0) {
 				query.RollSet = new RollSet (Database.Rolls.GetRolls (1)[0]);
 				UpdateQuery ();
 			}
@@ -1468,7 +1468,7 @@ namespace FSpot
 		{
 			Database.Sync = false;
 			ImportCommand command = new ImportCommand (main_window);
-			if (command.ImportFromFile (Database.Photos, null) > 0) {
+			if (command.ImportFromUri (Database.Photos, null) > 0) {
 				query.RollSet = new RollSet (Database.Rolls.GetRolls (1)[0]);
 				UpdateQuery ();
 			}
diff --git a/src/Makefile.am b/src/Makefile.am
index ba9ed53..9a76c3d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -59,6 +59,7 @@ UTILS_CSDISTFILES =				\
 	$(srcdir)/Utils/Log.cs			\
 	$(srcdir)/Utils/PixbufOrientation.cs	\
 	$(srcdir)/Utils/PixbufUtils.cs		\
+	$(srcdir)/Utils/RecursiveFileEnumerator.cs		\
 	$(srcdir)/Utils/Unix.cs			\
 	$(srcdir)/Utils/UriExtensions.cs			\
 	$(srcdir)/Utils/UriUtils.cs
@@ -340,6 +341,7 @@ UTILS_ASSEMBLIES =				\
 	-pkg:gnome-sharp-2.0			\
 	-r:Mono.Posix				\
 	-r:Mono.Cairo				\
+	$(LINK_GIOSHARP)			\
 	$(GCONF_PKG)
 
 JOBSCHEDULER_ASSEMBLIES =			\
diff --git a/src/PhotoList.cs b/src/PhotoList.cs
index 1a5296b..c66212f 100644
--- a/src/PhotoList.cs
+++ b/src/PhotoList.cs
@@ -37,6 +37,12 @@ namespace FSpot {
 		public int Capacity {
 			set { list.Capacity = value; }
 		}
+        
+		public void AddAll (List<IBrowsableItem> photos)
+		{
+			list = photos;
+			Reload ();
+		}
 
 		public void Add (IBrowsableItem photo)
 		{
diff --git a/src/Utils/RecursiveFileEnumerator.cs b/src/Utils/RecursiveFileEnumerator.cs
new file mode 100644
index 0000000..090c10c
--- /dev/null
+++ b/src/Utils/RecursiveFileEnumerator.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using GLib;
+
+namespace FSpot.Utils
+{
+    public class RecursiveFileEnumerator : IEnumerable<File>
+    {
+        Uri root;
+		bool recurse;
+
+        public RecursiveFileEnumerator (Uri root) : this (root, true)
+        {
+        }
+
+		public RecursiveFileEnumerator (Uri root, bool recurse)
+		{
+			this.root = root;
+			this.recurse = recurse;
+		}
+
+        IEnumerable<File> ScanForFiles (File root)
+        {
+            var enumerator = root.EnumerateChildren ("standard::name,standard::type", FileQueryInfoFlags.None, null);
+            foreach (FileInfo info in enumerator) {
+                File file = root.GetChild (info.Name);
+                
+                if (info.FileType == FileType.Regular) {
+                    yield return file;
+                } else if (info.FileType == FileType.Directory && recurse) {
+                    foreach (var child in ScanForFiles (file)) {
+                        yield return child;
+                    }
+                }
+                info.Dispose ();
+            }
+            enumerator.Close (null);
+        }
+
+        public IEnumerator<File> GetEnumerator ()
+        {
+            var file = FileFactory.NewForUri (root);
+            return ScanForFiles (file).GetEnumerator ();
+        }
+
+        IEnumerator IEnumerable.GetEnumerator ()
+        {
+            return GetEnumerator ();
+        }
+    }
+}
diff --git a/src/XmpTagsImporter.cs b/src/XmpTagsImporter.cs
index 6404179..30297ba 100644
--- a/src/XmpTagsImporter.cs
+++ b/src/XmpTagsImporter.cs
@@ -271,10 +271,13 @@ namespace FSpot.Xmp {
 #endif
 		}
 		
-		public bool Import (Photo photo, string path, string orig_path)
+		public bool Import (Photo photo, Uri uri, Uri orig_uri)
 		{
 			XmpFile xmp;
 			
+			string path = uri.AbsolutePath;
+			string orig_path = orig_uri.AbsolutePath;
+
 			string source_sidecar = String.Format ("{0}{1}{2}.xmp",
 							       Path.GetDirectoryName (orig_path),
 							       Path.DirectorySeparatorChar,
@@ -293,7 +296,7 @@ namespace FSpot.Xmp {
 				xmp = new XmpFile ();
 			}
 			
-			using (ImageFile img = ImageFile.Create (path)) {
+			using (ImageFile img = ImageFile.Create (uri)) {
 				StatementSource source = img as StatementSource;
 				if (source != null) {
 					try {



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