? ImportXmpTags4.diff
? src/XmpTagsImporter.cs
? src/XmpTagsMetadata.cs
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/f-spot/ChangeLog,v
retrieving revision 1.1510
diff -u -p -r1.1510 ChangeLog
--- ChangeLog	15 Jun 2006 01:34:14 -0000	1.1510
+++ ChangeLog	1 Jul 2006 10:44:38 -0000
@@ -1,3 +1,17 @@
+2006-07-01  Bengt Thuree <bengt@thuree.com> 
+
+	* src/XmpTagsMetadata.cs: Reads the XMP tags from a photo during import
+	
+	* src/XmpTagsImporter.cs: Creates XMP tags during import
+	
+	* src/FileImportBackend.cs: Calls XmpTagsImporter during import.
+	
+	* src/Makefile.am: Added XmpTagsMetadata.cs and XmpTagsImporter.cs
+	
+	* src/ImportCommand.cs: disable DisplayTags since otherwise we get a crash. 
+	Cancel do not seem to remove all...
+
+
 2006-06-14  Larry Ewing  <lewing@novell.com>
 
 	* src/IthmbDb.cs: update the entries drop the db loader for now.
Index: src/FileImportBackend.cs
===================================================================
RCS file: /cvs/gnome/f-spot/src/FileImportBackend.cs,v
retrieving revision 1.35
diff -u -p -r1.35 FileImportBackend.cs
--- src/FileImportBackend.cs	6 Jun 2006 17:11:46 -0000	1.35
+++ src/FileImportBackend.cs	1 Jul 2006 10:44:38 -0000
@@ -3,6 +3,7 @@ using Gtk;
 using Gnome;
 using System.Collections;
 using System;
+using FSpot;
 using System.IO;
 
 public class ImportException : System.Exception {
@@ -13,13 +14,17 @@ public class ImportException : System.Ex
 
 public class FileImportBackend : ImportBackend {
 	PhotoStore store;
+	TagStore tag_store = FSpot.Core.Database.Tags;
 	bool recurse;
 	bool copy;
 	string [] base_paths;
 	Tag [] tags;
+	Gtk.Dialog dialog;
 
 	int count;
 
+	XmpTagsImporter xmptags;
+
 	ArrayList file_paths;
 	ArrayList imported_photos;
 	Stack directories;
@@ -95,6 +100,7 @@ public class FileImportBackend : ImportB
 
 		imported_photos = new ArrayList ();
 		directories = new Stack ();
+		xmptags = new XmpTagsImporter (dialog, store, tag_store);
 
 		return file_paths.Count;
 	}
@@ -179,6 +185,8 @@ public class FileImportBackend : ImportB
 
 		// FIXME Need to get the EXIF info etc.
 		string path = (string) file_paths [this.count];
+		string orig_path = path;
+		bool needs_commit = false;
 		
 		try {
 			string dest = path;
@@ -204,14 +212,21 @@ public class FileImportBackend : ImportB
 
 				path = dest;
 			}
-			
+			photo = store.Create (dest, path, out thumbnail);
+			path = dest;
 			if (tags != null) {
 				foreach (Tag t in tags)
 					photo.AddTag (t);
 
-				store.Commit(photo);
+				needs_commit = true;
 			}
 
+
+			needs_commit |= xmptags.Import (photo, path, orig_path);
+
+			if (needs_commit)
+				store.Commit(photo);
+
 			imported_photos.Add (photo);
 			
 		} catch (System.Exception e) {
@@ -255,6 +270,8 @@ public class FileImportBackend : ImportB
 					info.Delete ();
 			}
 		}
+		// Clean up just created tags
+		xmptags.Cancel();
 	}
 
 	public override void Finish ()
@@ -269,13 +286,15 @@ public class FileImportBackend : ImportB
 		}
 
 		imported_photos = null;
+		xmptags.Finish();
 		count = 0;
 	}
 
-	public FileImportBackend (PhotoStore store, string [] base_paths, bool recurse) : this (store, base_paths, false, recurse, null) {}
+	public FileImportBackend (Gtk.Dialog dialog, PhotoStore store, string [] base_paths, bool recurse) : this (dialog, store, base_paths, false, recurse, null) {}
 
-	public FileImportBackend (PhotoStore store, string [] base_paths, bool copy, bool recurse, Tag [] tags)
+	public FileImportBackend (Gtk.Dialog dialog, PhotoStore store, string [] base_paths, bool copy, bool recurse, Tag [] tags)
 	{
+		this.dialog = dialog;
 		this.store = store;
 		this.copy = copy;
 		this.base_paths = base_paths;
Index: src/ImportCommand.cs
===================================================================
RCS file: /cvs/gnome/f-spot/src/ImportCommand.cs,v
retrieving revision 1.63
diff -u -p -r1.63 ImportCommand.cs
--- src/ImportCommand.cs	9 Jun 2006 22:53:02 -0000	1.63
+++ src/ImportCommand.cs	1 Jul 2006 10:44:39 -0000
@@ -346,7 +346,6 @@ public class ImportCommand : FSpot.Glade
 
 			if (item.Source is BrowseSource) {
 				string path = ChoosePath ();
-				
 				if (path != null) {
 					SourceItem path_item = new SourceItem (new VfsSource (path));
 					menu.Prepend (path_item);
@@ -512,7 +511,6 @@ public class ImportCommand : FSpot.Glade
 	public string ChoosePath ()
 	{
 		string path = null;
-
 		CompatFileChooserDialog file_selector =
 			new CompatFileChooserDialog ("Import", this.Dialog,
 						     CompatFileChooserDialog.Action.SelectFolder);
@@ -529,7 +527,6 @@ public class ImportCommand : FSpot.Glade
 		if ((ResponseType) response == ResponseType.Ok) {
 			path = file_selector.Filename;
 		}
-
 		file_selector.Destroy ();
 		return path;
 	}
@@ -562,6 +559,7 @@ public class ImportCommand : FSpot.Glade
 		this.Dialog.TransientFor = main_window;
 		this.Dialog.WindowPosition = Gtk.WindowPosition.CenterOnParent;
 		this.Dialog.Response += HandleDialogResponse;
+		bool SavedDisplayTags;
 
 		CreateTagMenu ();
 		
@@ -578,6 +576,8 @@ public class ImportCommand : FSpot.Glade
 
 		collection = new FSpot.PhotoList (new Photo [0]);
 		tray = new FSpot.ScalingIconView (collection);
+		SavedDisplayTags = tray.DisplayTags;	// So we know which state we had.
+		tray.DisplayTags = false;		// Otherwise deleting just created XMP tags will crash.
 		tray.Selection.Changed += HandleTraySelectionChanged;
 		icon_scrolled.SetSizeRequest (200, 200);
 		icon_scrolled.Add (tray);
@@ -659,12 +659,13 @@ public class ImportCommand : FSpot.Glade
 					store.Commit (p);
 				}
 			}
-
+			tray.DisplayTags = SavedDisplayTags;
 			this.Dialog.Destroy ();
 			return collection.Count;
 		} else {
 			this.Cancel ();
 			//this.Dialog.Destroy();
+			tray.DisplayTags = SavedDisplayTags;
 			return 0;
 		}
 	}
@@ -699,6 +700,7 @@ public class ImportCommand : FSpot.Glade
 	{
 		idle_start.Stop ();
 		step.Stop ();
+		
 		if (importer != null) {
 			importer.Cancel ();
 			importer = null;
@@ -732,7 +734,7 @@ public class ImportCommand : FSpot.Glade
 		if (recurse_check != null)
 			recurse = recurse_check.Active;
 		
-		importer = new FileImportBackend (store, pathimport, copy, recurse, null);
+		importer = new FileImportBackend (this.Dialog, store, pathimport, copy, recurse, null);
 		AllowFinish = false;
 		
 		total = importer.Prepare ();
@@ -762,7 +764,7 @@ public class ImportCommand : FSpot.Glade
 	public int ImportFromPaths (PhotoStore store, string [] paths, Tag [] tags, bool copy)
 	{
 		collection = new FSpot.PhotoList (new Photo [0]);
-		int count = DoImport (new FileImportBackend (store, paths, copy, true, tags));
+		int count = DoImport (new FileImportBackend (this.Dialog, store, paths, copy, true, tags));
 
 		Finish ();
 
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	1 Jul 2006 10:44:39 -0000
@@ -118,6 +118,8 @@ F_SPOT_CSDISTFILES =				\
 	$(srcdir)/TagSelectionDialog.cs		\
 	$(srcdir)/X3fFile.cs			\
 	$(srcdir)/XmpFile.cs			\
+	$(srcdir)/XmpTagsImporter.cs		\
+	$(srcdir)/XmpTagsMetadata.cs		\
 	$(srcdir)/main.cs
 
 ASSEMBLIES =					\
--- /dev/null	2006-05-23 00:25:23.000000000 +1000
+++ src/XmpTagsImporter.cs	2006-07-01 20:22:21.000000000 +1000
@@ -0,0 +1,162 @@
+using Gtk;
+using System;
+using System.Collections;
+using System.IO;
+using System.Xml;
+using FSpot.Xmp;
+
+public class XmpTagsImporter {
+	private PhotoStore photo_store;
+	private TagStore tag_store;
+	private Stack tags_created;
+	private Gtk.Window parent;
+	static private string LastImportStr = "Last Import";
+	static private string CityStr = "City";
+	static private string CountryStr = "Country";
+	static private string LocationStr = "Location";
+	static private string PlacesStr = "Places";
+				
+	public XmpTagsImporter (Gtk.Window parent, PhotoStore photo_store, TagStore tag_store)
+	{
+		this.parent = parent;
+		this.photo_store = photo_store;
+		this.tag_store = tag_store;
+		tags_created = new Stack ();
+	}
+
+	private void AddTagToPhoto (Photo photo, string new_tag_name, string rootstr, string subrootstr)
+	{
+		if (new_tag_name != null) {
+			// Check if a tag exists for this place
+			Tag place = tag_store.GetTagByName (new_tag_name);
+
+			// If not, make sure the rootstr tag exists and add this place under it
+			if (place == null) {
+				Tag root_tag = tag_store.GetTagByName (Mono.Posix.Catalog.GetString (rootstr));
+				if (root_tag == null) {
+					root_tag = tag_store.GetTagByName (rootstr);
+
+					if (root_tag == null) {
+						root_tag = tag_store.CreateCategory (
+							tag_store.RootCategory, 
+							Mono.Posix.Catalog.GetString (rootstr));
+						tags_created.Push (root_tag);
+					}
+				}
+				// If we should have a sub root, add it now.
+				if (subrootstr != null)	{
+					Tag subroot_tag = tag_store.GetTagByName (Mono.Posix.Catalog.GetString (subrootstr));
+					if (subroot_tag == null) {
+						subroot_tag = tag_store.GetTagByName (subrootstr);
+
+						if (subroot_tag == null) {
+							subroot_tag = tag_store.CreateCategory (
+								root_tag as Category, 
+								Mono.Posix.Catalog.GetString (subrootstr));
+							tags_created.Push (subroot_tag);
+						}
+					}
+					root_tag = subroot_tag; // Change so we attach to subroot_tag 
+				} // end adding subroot
+				
+				// add the new tag, and put ut under the root/subroot
+				place = tag_store.CreateCategory (root_tag as Category, new_tag_name);
+				tags_created.Push (place);
+			}
+			
+			// Now we have the tag for this place, add the photo to it
+			photo.AddTag (place);
+		} // if new_tag_name != null
+	}
+
+	private void AddTagToPhoto (Photo photo, string [] new_tag_names, string rootstr, string subrootstr)
+	{
+		if (new_tag_names != null)
+			foreach (string keyword in new_tag_names)
+				AddTagToPhoto (photo, keyword, rootstr, subrootstr);
+	}
+	
+
+	
+	public bool Import (Photo photo, string path, string orig_path)
+	{
+		bool needs_commit = false;
+
+		XmpTagsMetadata xmd = XmpTagsMetadata.ForPhoto (path, orig_path);
+
+		if (xmd == null)
+			return needs_commit;
+		
+		// Read the XMP tags.
+		if (! xmd.Read())
+			return needs_commit;
+
+		// Ok, we have XMP data embeeded in the photo. 
+		needs_commit = true;
+
+		// F-Spot do not keep Headline/Caption but only a description field, 
+		// so we need to combine the two headline/caption to one field (with a " : " between)
+		// Also, there are at least two different options here. So we assume that if
+		// something is set, we should use it. Start to check for the title, then description.
+
+		// Since F-Spot do not handle the EXIF description to good yet, we leave this one out.
+//		if (xmd.EXIF_Description != null) 
+//			photo.Description = xmd.EXIF_Description;
+
+		// F-Spot only stores the description into XMP User Comment, so if this one is set, we use it.
+		if (xmd.adobe_UserComment != null) {
+			photo.Description = xmd.adobe_UserComment;
+		}
+
+		// only check for more title/comment if you still do not have one.
+		if ((photo.Description == null) || (photo.Description.Length == 0)) {
+			if (xmd.ps_Headline != null)
+				photo.Description = xmd.ps_Headline;
+			if (xmd.ps_Caption != null)
+				photo.Description += (( (xmd.ps_Headline == null) ? "" : " : ") + xmd.ps_Caption);
+		}	
+		
+		// only check for more title/comment if you still do not have one.
+		if ((photo.Description == null) || (photo.Description.Length == 0)) {
+			if (xmd.pu_Title != null)
+				photo.Description = xmd.pu_Title;
+			if (xmd.pu_Description != null)
+				photo.Description += (( (xmd.pu_Title == null) ? "" : " : ") + xmd.pu_Description);
+		}
+		
+		if (xmd.Time != DateTime.MinValue)
+			photo.Time = xmd.Time;
+
+		if (xmd.Urgency != null) {
+		}
+		if (xmd.Rights != null) {
+		}
+		if (xmd.Creator != null) {
+		}
+
+		if (xmd.City != null)
+			AddTagToPhoto (photo, xmd.City, PlacesStr, CityStr);
+		if (xmd.Country != null)
+			AddTagToPhoto (photo, xmd.Country, PlacesStr, CountryStr);
+		if (xmd.Location != null)
+			AddTagToPhoto (photo, xmd.Location, PlacesStr, LocationStr);
+		if (xmd.Keywords != null)
+			AddTagToPhoto (photo, xmd.Keywords, LastImportStr, null);
+		
+		return needs_commit;
+	}
+
+	public void Cancel()
+	{
+		while (tags_created.Count > 0) 
+			tag_store.Remove ((DbItem) tags_created.Pop());		
+		tags_created.Clear();
+	}
+
+	public void Finish()
+	{
+		tags_created.Clear();		
+	}
+
+
+}
--- /dev/null	2006-05-23 00:25:23.000000000 +1000
+++ src/XmpTagsMetadata.cs	2006-07-01 20:22:21.000000000 +1000
@@ -0,0 +1,376 @@
+#define UseImageFile
+using System;
+using System.IO;
+using System.Xml;
+using FSpot;
+using FSpot.Xmp;
+
+public class XmpTagsMetadata {
+	private bool xmptags_sidecar;
+	private string xmptags_photofile;
+	private string xmptags_sidecarfile;
+	
+	// Xmp meta data
+	private string [] keywords;
+	public string [] Keywords {
+		get { return keywords; }
+	}
+
+	private DateTime time = DateTime.MinValue;	
+	public DateTime Time {		
+		get { return time; }	
+	}
+	private string creator;			public string Creator 		{get { return creator; }	}
+	private string rights;			public string Rights 		{get { return rights; }	}	
+	private string city;			public string City 		{get { return city; }}
+	private string country;			public string Country		{get { return country; }	}
+	private string ps_headline;		public string ps_Headline	{get { return ps_headline; }	}
+	private string ps_caption;		public string ps_Caption 	{get { return ps_caption; }	}
+	private string pu_title;		public string pu_Title 		{get { return pu_title; }	}
+	private string pu_description;		public string pu_Description 	{get { return pu_description; }}
+	private string exif_description;	public string Exif_Description 	{get { return exif_description; }	}
+	private string adobe_usercomment;	public string adobe_UserComment {get { return adobe_usercomment; }	}
+	private string location;		public string Location 		{get { return location; }	}	
+	private string urgency;			public string Urgency 		{get { return urgency; }	}
+	private string make;			public string Make 		{get { return make; }	}
+	private string model;			public string Model 		{get { return model; }	}
+	private string orientation;		public string Orientation 	{get { return orientation; }	}
+	private string resolutionunit;		public string ResolutionUnit 	{get { return resolutionunit; }	}
+	private string exposuretime;		public string ExposureTime 	{get { return exposuretime; }	}
+	private string fnumber;			public string FNumber 		{get { return fnumber; }	}
+	private string shutterspeedvalue;	public string ShutterSpeedValue {get { return shutterspeedvalue; }	}
+	private string aperturevalue;		public string ApertureValue 	{get { return aperturevalue; }	}
+	private string exposurebiasvalue;	public string ExposureBiasValue {get { return exposurebiasvalue; }	}
+	private string maxaperturevalue;	public string MaxApertureValue 	{get { return maxaperturevalue; }	}
+	private string meteringmode;		public string MeteringMode 	{get { return meteringmode; }	}
+	private string focallength;		public string FocalLength 	{get { return focallength; }	}
+	private string colorspace;		public string ColorSpace 	{get { return colorspace; }	}
+	private string pixelxdimension;		public string PixelXDimension 	{get { return pixelxdimension; }	}
+	private string pixelydimension;		public string PixelYDimension 	{get { return pixelydimension; }	}
+	private string exposuremode;		public string ExposureMode 	{get { return exposuremode; }	}
+	private string whitebalance;		public string WhiteBalance 	{get { return whitebalance; }	}
+	private string digitalzoomratio;	public string DigitalZoomRatio 	{get { return digitalzoomratio; }	}
+
+	public static XmpTagsMetadata ForPhoto (string path, string orig_path)
+	{
+		// First check if there are readable XMP tags embedded in the photo.
+		// If not, then check if there is a sidecar file.
+		
+		string xmptag_sidecarfile = String.Format ("{0}{1}{2}.xmp",
+					Path.GetDirectoryName (path),
+					Path.DirectorySeparatorChar,
+					Path.GetFileName (path));
+
+		// FIXME, When F-Spot copies the sidecar file with the photo, we do not need the extra path.
+		// FIXME bug #342892 http://bugzilla.gnome.org/show_bug.cgi?id=342892
+		string xmptag_sidecarfile2 = String.Format ("{0}{1}{2}.xmp",
+					Path.GetDirectoryName (orig_path),
+					Path.DirectorySeparatorChar,
+					Path.GetFileName (orig_path));
+
+		try {
+#if UseImageFile
+			ImageFile img = ImageFile.Create (path);
+			if (img is SemWeb.StatementSource) {
+				System.Console.WriteLine ("This was a JPG, will not check for a sidecar");			
+				return new XmpTagsMetadata (path, null, false);
+			}
+#else
+			JpegFile jpegfile = new JpegFile(path);
+			JpegHeader jpegheader = jpegfile.Header;
+			XmpFile xmpfile = jpegheader.GetXmp();
+			if (xmpfile != null) {
+//				System.Console.WriteLine ("This was a JPG, will not check for a sidecar");			
+				return new XmpTagsMetadata (path, null, false);
+			}
+#endif
+
+		} catch (System.Exception e) {
+			System.Console.WriteLine ("Error reading XMP headers for {0}\n{1}", path, e.ToString ());
+		}
+		
+		System.Console.WriteLine ("Checking for a sidecar file {0}, {1}", xmptag_sidecarfile, File.Exists (xmptag_sidecarfile));
+		if (File.Exists (xmptag_sidecarfile)) {
+			return new XmpTagsMetadata (path, xmptag_sidecarfile, true);
+		}
+		System.Console.WriteLine ("Checking for a sidecar file {0}, {1}", xmptag_sidecarfile2, File.Exists (xmptag_sidecarfile2));
+		if (File.Exists (xmptag_sidecarfile2)) {
+			return new XmpTagsMetadata (path, xmptag_sidecarfile2, true);
+		}
+//		System.Console.WriteLine ("No XMP tags will be read at all.");		
+		return null;
+	}
+
+	public XmpTagsMetadata (string photo_path, string sidecar_path, bool sidecar)
+	{
+		this.xmptags_photofile = photo_path;
+		this.xmptags_sidecarfile = sidecar_path;
+		this.xmptags_sidecar = sidecar; 
+	}
+	
+	private string fetch_object (string obj)
+	{
+		// SemWeb puts quotes around the strings it returns, 
+		// so we need to remove them
+		
+		// SemWeb returns the language appended to the string as "....."@x-default, so if we remove everything 
+		// between the first and last '"' it should be ok.
+		
+		int last_pos = obj.LastIndexOf('"');
+		if (last_pos > 0)
+			obj = obj.Substring (1, last_pos - 1);
+
+		// Remove blanks from start and end of the string.			
+		return obj.Trim();
+	}
+
+	public bool Read ()
+	{
+		bool collecting_items = false;
+		System.Collections.ArrayList items_list = new System.Collections.ArrayList();
+		XmpFile xmpfile = null;
+		MetadataStore store = new MetadataStore ();		
+		
+		// See if there's metadata
+//		if (! Exists)
+//			return false;
+
+		try {
+			if (xmptags_sidecar) {
+				Console.WriteLine ("Importing xmptags metadata from sidecar {0}", xmptags_sidecarfile);	
+				xmpfile = new XmpFile(System.IO.File.OpenRead(xmptags_sidecarfile));
+				store = xmpfile.Store;
+			} else {
+				Console.WriteLine ("Importing xmptags metadata from {0}", xmptags_photofile);	
+				ImageFile img = ImageFile.Create (xmptags_photofile);
+#if UseImageFile
+				if (img is SemWeb.StatementSource) {
+					SemWeb.StatementSource source = (SemWeb.StatementSource)img;
+					source.Select (store);
+				}
+#else
+				JpegFile jpegfile = new JpegFile(xmptags_photofile);
+				JpegHeader jpegheader = jpegfile.Header;
+				xmpfile = jpegheader.GetXmp();
+#endif
+				
+				// Get the EXIF description
+				if (img is FSpot.JpegFile) {
+					FSpot.JpegFile jimg = img as FSpot.JpegFile;			
+					exif_description = jimg.Description;
+//					Console.WriteLine ("Set the description to JPEG = >>{0}<<" ,jimg.Description);	
+				} else if (img is FSpot.Png.PngFile) {
+					FSpot.Png.PngFile png = img as FSpot.Png.PngFile;
+					exif_description = png.Description;
+//					Console.WriteLine ("Set the description to PNG = >>{0}<<" ,png.Description);	
+				}
+
+			} // if xmptags_sidecar
+
+			// if we find a photoshop:Headline node than put it's content in the description field.
+//Console.WriteLine ("xmptags_sidecar = {0}, store.StatementCount = {1}", xmptags_sidecar, store.StatementCount);
+#if UseImageFile
+			if (store.StatementCount > 0) {
+				foreach (SemWeb.Statement stmt in store) {				
+#else				
+				foreach (SemWeb.Statement stmt in xmpfile.Store) {
+#endif			
+//					Console.WriteLine ("Subject = >>{0}<<" ,stmt.Subject);	
+//					Console.WriteLine ("Predicate = >>{0}<<", stmt.Predicate);
+//					Console.WriteLine ("Object = >>{0}<<", stmt.Object);
+//					Console.WriteLine ("Meta = >>{0}<<", stmt.Meta);
+
+					string stmt_pre_str = stmt.Predicate.ToString();
+					string stmt_obj_str = stmt.Object.ToString();
+
+					// Check for headline (if we are not processing keywords)
+					if (!collecting_items)
+						switch (stmt_pre_str) {
+							case "http://ns.adobe.com/photoshop/1.0/City" :
+								city = fetch_object (stmt_obj_str);
+								break;
+							case "http://ns.adobe.com/photoshop/1.0/Country" :
+								country = fetch_object (stmt_obj_str);
+								break;
+							case "http://ns.adobe.com/photoshop/1.0/Headline" :
+								ps_headline = fetch_object (stmt_obj_str);
+								break;
+							case "http://ns.adobe.com/photoshop/1.0/Caption" :
+								ps_caption = fetch_object (stmt_obj_str);
+								break;
+							case "http://ns.adobe.com/photoshop/1.0/Urgency" :
+								urgency = fetch_object (stmt_obj_str);
+								break;
+							case "http://ns.adobe.com/tiff/1.0/Make" :
+								make = fetch_object (stmt_obj_str);
+								break;
+							case "http://ns.adobe.com/tiff/1.0/Model" :
+								model = fetch_object (stmt_obj_str);
+								break;
+							case "http://ns.adobe.com/tiff/1.0/Orientation" :
+								orientation = fetch_object (stmt_obj_str);
+								break;
+							case "http://ns.adobe.com/tiff/1.0/ResolutionUnit" :
+								resolutionunit = fetch_object (stmt_obj_str);
+								break;
+							case "http://ns.adobe.com/exif/1.0/ExposureTime" :
+								exposuretime = fetch_object (stmt_obj_str);
+								break;
+							case "http://ns.adobe.com/exif/1.0/FNumber" :
+								fnumber = fetch_object (stmt_obj_str);
+								break;
+							case "http://ns.adobe.com/exif/1.0/ShutterSpeedValue" :
+								shutterspeedvalue = fetch_object (stmt_obj_str);
+								break;
+							case "http://ns.adobe.com/exif/1.0/ApertureValue" :
+								aperturevalue = fetch_object (stmt_obj_str);
+								break;
+							case "http://ns.adobe.com/exif/1.0/ExposureBiasValue" :
+								exposurebiasvalue = fetch_object (stmt_obj_str);
+								break;
+							case "http://ns.adobe.com/exif/1.0/MaxApertureValue" :
+								maxaperturevalue = fetch_object (stmt_obj_str);
+								break;
+							case "http://ns.adobe.com/exif/1.0/MeteringMode" :
+								meteringmode = fetch_object (stmt_obj_str);
+								break;
+							case "http://ns.adobe.com/exif/1.0/FocalLength" :
+								focallength= fetch_object (stmt_obj_str);
+								break;
+							case "http://ns.adobe.com/exif/1.0/ColorSpace" :
+								colorspace = fetch_object (stmt_obj_str);
+								break;
+							case "http://ns.adobe.com/exif/1.0/PixelXDimension" :
+								pixelxdimension = fetch_object (stmt_obj_str);
+								break;
+							case "http://ns.adobe.com/exif/1.0/PixelYDimension" :
+								pixelydimension = fetch_object (stmt_obj_str);
+								break;
+							case "http://ns.adobe.com/exif/1.0/ExposureMode" :
+								exposuremode = fetch_object (stmt_obj_str);
+								break;
+							case "http://ns.adobe.com/exif/1.0/WhiteBalance" :
+								whitebalance = fetch_object (stmt_obj_str);
+								break;
+							case "http://ns.adobe.com/exif/1.0/DigitalZoomRatio" :
+								digitalzoomratio = fetch_object (stmt_obj_str);
+								break;
+							case "http://ns.iview-multimedia.com/mediapro/1.0/Location" :
+								location = fetch_object (stmt_obj_str);
+								break;
+							default :
+								break;
+						}
+
+					// Items are attached in objects between a header (http..) and an ending ("_")
+					// Check if we have a start item object
+					if (stmt_pre_str == "http://www.w3.org/1999/02/22-rdf-syntax-ns#type") {
+						collecting_items = true;
+						continue;	// Next foreach
+					}
+					
+					// If we found end object for items
+					if ( (collecting_items) && (stmt_obj_str == "_") ) {
+						collecting_items = false;
+						
+						// Check the predicate to see which items we just collected.
+						switch (stmt_pre_str) {
+							case "http://purl.org/dc/elements/1.1/subject" :
+								keywords = new string[items_list.Count]; 
+								items_list.CopyTo(keywords);
+								break;
+							case "http://purl.org/dc/elements/1.1/creator" :
+								if (items_list.Count > 0)
+									creator = items_list[0].ToString();
+								break;
+							case "http://purl.org/dc/elements/1.1/rights" :
+								if (items_list.Count > 0)
+									rights = items_list[0].ToString();
+								break;
+							case "http://purl.org/dc/elements/1.1/description" :
+								if (items_list.Count > 0)
+									pu_description = items_list[0].ToString();
+								break;
+							case "http://purl.org/dc/elements/1.1/title" :
+								if (items_list.Count > 0)
+									pu_title = items_list[0].ToString();
+								break;
+							case "http://ns.adobe.com/exif/1.0/UserComment" :
+								if (items_list.Count > 0) {
+									adobe_usercomment = items_list[0].ToString();
+									
+									// Found weird \u0000\u0000\u0000... in this field. remove them
+									if (adobe_usercomment.StartsWith("\\u0000")) 
+										adobe_usercomment = adobe_usercomment.Replace("\\u0000", null);
+									// After replacing, we need to check if anything left, if not set it to null
+									if (adobe_usercomment.Length == 0) 
+										adobe_usercomment = null;
+								}
+								break;
+							default	:
+								break;
+						} // switch
+						
+						// Since end tag was found for this list, and we have just copied
+						// all the items to its proper place, we can clear the list now.
+						items_list.Clear();
+						continue;	// Next foreach
+						
+					}  // end found end field for items.
+					
+					// Add to items (keywords or similar), if we are collecting them.
+					if (collecting_items) 
+						items_list.Add(fetch_object (stmt_obj_str));
+				}
+#if UseImageFile
+			}
+#endif
+
+		} catch (Exception e) {
+			Console.WriteLine ("Exception: {0}", e.ToString ());
+			return false;
+		}
+	
+/*		
+		Console.WriteLine ("Have city = >>{0}<<", city==null ? "null" : city);
+		Console.WriteLine ("Have country = >>{0}<<", country==null ? "null" : country );
+		Console.WriteLine ("Have ps_headline = >>{0}<<", ps_headline==null ? "null" : ps_headline);
+		Console.WriteLine ("Have ps_caption = >>{0}<<", ps_caption==null ? "null" : ps_caption);
+		Console.WriteLine ("Have urgency = >>{0}<<", urgency==null ? "null" : urgency );
+		Console.WriteLine ("Have location = >>{0}<<", location==null ? "null" : location );	
+		Console.WriteLine ("Have pu_title = >>{0}<<", pu_title==null ? "null" : pu_title );	
+		Console.WriteLine ("Have pu_description = >>{0}<<", pu_description==null ? "null" : pu_description );	
+		Console.WriteLine ("Have exif description = >>{0}<<", exif_description==null ? "null" : exif_description );	
+		Console.WriteLine ("Have adobe usercomment = >>{0}<<", adobe_usercomment==null ? "null" : adobe_usercomment );	
+		Console.WriteLine ("Have rights = >>{0}<<", rights==null ? "null" : rights );	
+		Console.WriteLine ("Have creator = >>{0}<<", creator==null ? "null" : creator );	
+		if (keywords == null)
+			Console.WriteLine ("Have keyword = >>null<<" );
+		else
+			foreach (string keyword in keywords) 
+				Console.WriteLine ("Have keyword = >>{0}<<", keyword==null ? "null" : keyword );	
+
+		Console.WriteLine ("Have make = >>{0}<<", make==null ? "null" : make );	
+		Console.WriteLine ("Have model = >>{0}<<", model==null ? "null" : model );	
+		Console.WriteLine ("Have orientation = >>{0}<<", orientation==null ? "null" : orientation );	
+		Console.WriteLine ("Have resolutionunit = >>{0}<<", resolutionunit==null ? "null" : resolutionunit );	
+		Console.WriteLine ("Have exposuretime = >>{0}<<", exposuretime==null ? "null" : exposuretime );	
+		Console.WriteLine ("Have fnumber = >>{0}<<", fnumber==null ? "null" : fnumber );	
+		Console.WriteLine ("Have shutterspeedvalue = >>{0}<<", shutterspeedvalue==null ? "null" : shutterspeedvalue );	
+		Console.WriteLine ("Have aperturevalue = >>{0}<<", aperturevalue==null ? "null" : aperturevalue );	
+		Console.WriteLine ("Have exposurebiasvalue = >>{0}<<", exposurebiasvalue==null ? "null" : exposurebiasvalue );	
+		Console.WriteLine ("Have maxaperturevalue = >>{0}<<", maxaperturevalue==null ? "null" : maxaperturevalue );	
+		Console.WriteLine ("Have meteringmode = >>{0}<<", meteringmode==null ? "null" : meteringmode );	
+		Console.WriteLine ("Have focallength = >>{0}<<", focallength==null ? "null" : focallength );	
+		Console.WriteLine ("Have colorspace = >>{0}<<", colorspace==null ? "null" : colorspace );	
+		Console.WriteLine ("Have pixelxdimension = >>{0}<<", pixelxdimension==null ? "null" : pixelxdimension );	
+		Console.WriteLine ("Have pixelydimension = >>{0}<<", pixelydimension==null ? "null" : pixelydimension );	
+		Console.WriteLine ("Have exposuremode = >>{0}<<", exposuremode==null ? "null" : exposuremode );	
+		Console.WriteLine ("Have whitebalance = >>{0}<<", whitebalance==null ? "null" : whitebalance );	
+		Console.WriteLine ("Have digitalzoomratio = >>{0}<<", digitalzoomratio==null ? "null" : digitalzoomratio );	
+*/
+
+		//Console.WriteLine ("Done importing xmp metadata");
+		return true;
+	}
+}
