f-spot r4149 - in trunk: . src src/Utils src/Widgets



Author: sdelcroix
Date: Fri Jul  4 11:54:46 2008
New Revision: 4149
URL: http://svn.gnome.org/viewvc/f-spot?rev=4149&view=rev

Log:
2008-07-04  Stephane Delcroix  <stephane delcroix org>

	* src/PhotoView.cs: implement a Dispose pattern

	* src/PixbufCache.cs:
	* src/PixbufLoader.cs:
	* src/ThumbnailGenerator.cs: switch to Uri

	* src/Utils/Cache.cs: Contains method

	* src/Widgets/Filmstrip.cs: avoid unecessary redraw on PixbufLoaded


Modified:
   trunk/ChangeLog
   trunk/src/PhotoView.cs
   trunk/src/PixbufCache.cs
   trunk/src/PixbufLoader.cs
   trunk/src/ThumbnailGenerator.cs
   trunk/src/Utils/Cache.cs
   trunk/src/Widgets/Filmstrip.cs

Modified: trunk/src/PhotoView.cs
==============================================================================
--- trunk/src/PhotoView.cs	(original)
+++ trunk/src/PhotoView.cs	Fri Jul  4 11:54:46 2008
@@ -433,6 +433,7 @@
 		private void HandleDestroy (object sender, System.EventArgs args)
 		{
 			CommitPendingChanges ();
+			Dispose ();
 		}
 	
 		public bool FilmStripVisibility {
@@ -593,7 +594,32 @@
 			Realized += delegate (object o, EventArgs e) {SetColors ();};
 			Preferences.SettingChanged += OnPreferencesChanged;
 		}
+
+		~PhotoView ()
+		{
+			FSpot.Utils.Log.DebugFormat ("Finalizer called on {0}. Should be Disposed", GetType ());		
+			Dispose (false);	
+		}
+
+		public override void Dispose ()
+		{
+			Dispose (true);
+			base.Dispose ();
+			System.GC.SuppressFinalize (this);
+		}
 	
+		bool is_disposed = false;
+		protected virtual void Dispose (bool disposing)
+		{
+			if (is_disposed)
+				return;
+			if (disposing) { //Free managed resources
+				filmstrip.Dispose ();	
+			}
+
+			is_disposed = true;
+		}
+
 		private void OnPreferencesChanged (object sender, NotifyEventArgs args)
 		{
 			LoadPreference (args.Key);

Modified: trunk/src/PixbufCache.cs
==============================================================================
--- trunk/src/PixbufCache.cs	(original)
+++ trunk/src/PixbufCache.cs	Fri Jul  4 11:54:46 2008
@@ -1,3 +1,13 @@
+/*
+ * FSpot.PixbufCache.cs
+ *
+ * Author(s):
+ * 	Larry Ewing <lewing novell com>
+ *
+ * This is free software. See COPYING for details.
+ */
+
+using System;
 using System.Collections;
 using System.Threading;
 
@@ -24,9 +34,9 @@
 			ThumbnailGenerator.Default.OnPixbufLoaded += HandleThumbnailLoaded;
 		}
 		
-		public void HandleThumbnailLoaded (PixbufLoader loader, string path, int order, Gdk.Pixbuf result)
+		public void HandleThumbnailLoaded (PixbufLoader loader, Uri uri, int order, Gdk.Pixbuf result)
 		{
-			string thumb_path = ThumbnailGenerator.ThumbnailPath (new System.Uri (path));
+			string thumb_path = ThumbnailGenerator.ThumbnailPath (uri);
 			
 			if (result != null)
 				Reload (thumb_path);

Modified: trunk/src/PixbufLoader.cs
==============================================================================
--- trunk/src/PixbufLoader.cs	(original)
+++ trunk/src/PixbufLoader.cs	Fri Jul  4 11:54:46 2008
@@ -1,16 +1,28 @@
+/*
+ * PixbufLoader.cs
+ *
+ * Author(s):
+ *	Ettore Perazzoli <ettore perazzoli org>
+ *	Larry Ewing <lewing novell com>
+ *
+ * This is free software. See COPYING for details
+ */
 using Gdk;
 using Gtk;
 using System.Collections;
+using System.Collections.Generic;
 using System.Threading;
 using System;
 
+using FSpot.Utils;
+
 public class PixbufLoader {
 
 	// Types.
 
 	protected class RequestItem {
 		/* The path to the image.  */
-		public string path;
+		public Uri uri;
 
 		/* Order value; requests with a lower value get performed first.  */
 		public int order;
@@ -22,8 +34,8 @@
 		public int width;
 		public int height;
 
-		public RequestItem (string path, int order, int width, int height) {
-			this.path = path;
+		public RequestItem (Uri uri, int order, int width, int height) {
+			this.uri = uri;
 			this.order = order;
 			this.width = width;
 			this.height = height;
@@ -43,11 +55,12 @@
 	   needs to be locked prior to access.  */
 	private ArrayList queue;
 
-	/* A hash of all the requests; note that the current request
-	   isn't in the hash.  */
-	private Hashtable requests_by_path;
+	/* A dict of all the requests; note that the current request
+	   isn't in the dict.  */
+	Dictionary<Uri, RequestItem> requests_by_uri;
+//	private Hashtable requests_by_path;
 
-	/* Current requeust.  Request currently being handled by the
+	/* Current request.  Request currently being handled by the
 	   auxiliary thread.  Should be modified only by the auxiliary
 	   thread (the GTK thread can only read it).  */
 	private RequestItem current_request;
@@ -66,13 +79,14 @@
 
 	// Public API.
 
-	public delegate void PixbufLoadedHandler (PixbufLoader loader, string path, int order, Pixbuf result);
+	public delegate void PixbufLoadedHandler (PixbufLoader loader, Uri uri, int order, Pixbuf result);
 	public event PixbufLoadedHandler OnPixbufLoaded;
 
 	public PixbufLoader ()
 	{
 		queue = new ArrayList ();
-		requests_by_path = Hashtable.Synchronized (new Hashtable ());
+		requests_by_uri = new Dictionary<Uri, RequestItem> ();
+//		requests_by_path = Hashtable.Synchronized (new Hashtable ());
 		processed_requests = new Queue ();
 		
 		pending_notify = new ThreadNotify (new Gtk.ReadyEvent (HandleProcessedRequests));
@@ -105,35 +119,25 @@
 			t.Abort ();
 	}
 
-	public void Request (string path, int order)
+	public void Request (Uri uri, int order)
 	{
-		Request (path, order, 0, 0);
+		Request (uri, order, 0, 0);
 	}
 
-	public void Request (string path, int order, int width, int height)
+	public void Request (Uri uri, int order, int width, int height)
 	{
 		lock (queue) {
-			if (InsertRequest (path, order, width, height))
+			if (InsertRequest (uri, order, width, height))
 				Monitor.Pulse (queue);
 		}
 	}
 
-	public void Request (Uri uri, int order)
-	{
-		Request (uri.ToString (), order);
-	}
-
-	public void Request (Uri uri, int order, int width, int height)
-	{
-		Request (uri.ToString (), order, width, height);
-	}
-
-	public void Cancel (string path)
+	public void Cancel (Uri uri)
 	{
 		lock (queue) {
-			RequestItem r = requests_by_path [path] as RequestItem;
+			RequestItem r = requests_by_uri [uri];
 			if (r != null) {
-				requests_by_path.Remove (path);
+				requests_by_uri.Remove (uri);
 				queue.Remove (r);
 			}
 		}
@@ -145,7 +149,7 @@
 	{
 		Pixbuf orig_image;
 		try {
-			using (FSpot.ImageFile img = System.IO.File.Exists (request.path) ? FSpot.ImageFile.Create (request.path) : FSpot.ImageFile.Create (new Uri (request.path))) {
+			using (FSpot.ImageFile img = FSpot.ImageFile.Create (request.uri)) {
 				if (request.width > 0) {
 					orig_image = img.Load (request.width, request.height);
 				} else {
@@ -166,20 +170,20 @@
 	/* Insert the request in the queue, return TRUE if the queue actually grew.
 	   NOTE: Lock the queue before calling.  */
 
-	private bool InsertRequest (string path, int order, int width, int height)
+	private bool InsertRequest (Uri uri, int order, int width, int height)
 	{
 		/* Check if this is the same as the request currently being processed.  */
 		lock(processed_requests) {
-			if (current_request != null && current_request.path == path)
+			if (current_request != null && current_request.uri == uri)
 				return false;
 		}
 		/* Check if a request for this path has already been queued.  */
-		RequestItem existing_request = requests_by_path [path] as RequestItem;
-		if (existing_request != null) {
+		RequestItem existing_request;
+		if (requests_by_uri.TryGetValue (uri, out existing_request)) {
 			/* FIXME: At least for now, this shouldn't happen.  */
 			if (existing_request.order != order)
-				Console.WriteLine ("BUG: Filing another request of order {0} (previously {1}) for `{2}'",
-						   order, existing_request.order, path);
+				Log.WarningFormat ("BUG: Filing another request of order {0} (previously {1}) for `{2}'",
+						   order, existing_request.order, uri);
 
 			queue.Remove (existing_request);
 			queue.Add (existing_request);
@@ -187,11 +191,13 @@
 		}
 
 		/* New request, just put it on the queue with the right order.  */
-		RequestItem new_request = new RequestItem (path, order, width, height);
+		RequestItem new_request = new RequestItem (uri, order, width, height);
 
 		queue.Add (new_request);
 
-		requests_by_path.Add (path, new_request);
+		lock (queue) {
+			requests_by_uri.Add (uri, new_request);
+		}
 		return true;
 	}
 
@@ -222,7 +228,7 @@
 	
 					current_request = queue [pos] as RequestItem;
 					queue.RemoveAt (pos);
-					requests_by_path.Remove (current_request.path);
+					requests_by_uri.Remove (current_request.uri);
 				}
 				
 				ProcessRequest (current_request);
@@ -236,7 +242,7 @@
 	{
 		if (OnPixbufLoaded != null) {
 			foreach (RequestItem r in results)
-				OnPixbufLoaded (this, r.path, r.order, r.result);
+				OnPixbufLoaded (this, r.uri, r.order, r.result);
 		}
 	}
 

Modified: trunk/src/ThumbnailGenerator.cs
==============================================================================
--- trunk/src/ThumbnailGenerator.cs	(original)
+++ trunk/src/ThumbnailGenerator.cs	Fri Jul  4 11:54:46 2008
@@ -1,3 +1,12 @@
+/*
+ * FSpot.ThumbnailGenerator.cs
+ *
+ * Author(s)
+ * 	Larry Ewing  <lewing novell com>
+ *
+ * This is free software. See COPYING for details.
+ */
+
 using System;
 using System.IO;
 using FSpot.Utils;
@@ -57,6 +66,7 @@
 			return large_path;
 		}
 
+		[Obsolete ("Use ThumbnailPath (System.Uri) instead")]
 		public static string ThumbnailPath (string path) 
 		{
 			return ThumbnailPath (UriUtils.PathToFileUri (path));
@@ -108,15 +118,8 @@
 				base.ProcessRequest (request);
 
 				Gdk.Pixbuf image = request.result;
-				if (image != null) {
-					Uri uri;
-					if (File.Exists (request.path))
-						uri = UriUtils.PathToFileUri (request.path);
-					else
-						uri = new Uri (request.path);
-
-					Save (image, uri);
-				}
+				if (image != null)
+					Save (image, request.uri);
 
 				System.Threading.Thread.Sleep (75);
 			} catch (System.Exception e) {

Modified: trunk/src/Utils/Cache.cs
==============================================================================
--- trunk/src/Utils/Cache.cs	(original)
+++ trunk/src/Utils/Cache.cs	Fri Jul  4 11:54:46 2008
@@ -77,6 +77,21 @@
 				hash.Remove (key);
 			}
 		}
+
+		public bool TryRemove (TKey key)
+		{
+			try {
+				Remove (key);
+				return true;
+			} catch (KeyNotFoundException) {
+				return false;
+			}
+		}
+
+		public bool Contains (TKey key)
+		{
+			return mru.Contains (key);
+		}
 	}
 
 	public class DisposableCache<TKey, TValue> : Cache<TKey, TValue>, IDisposable

Modified: trunk/src/Widgets/Filmstrip.cs
==============================================================================
--- trunk/src/Widgets/Filmstrip.cs	(original)
+++ trunk/src/Widgets/Filmstrip.cs	Fri Jul  4 11:54:46 2008
@@ -8,7 +8,6 @@
  */
 
 //TODO:
-//	* deal with vertical orientations (medium)
 //	* only redraw required parts on ExposeEvents (low)
 //	* Handle orientation changes (low) (require gtk# changes, so I can trigger an OrientationChanged event)
 
@@ -209,7 +208,7 @@
 			}
 		}
 
-		int x_offset = 2, y_offset = 2;
+		int x_offset = 2;
 		public int XOffset {
 			get { return x_offset; }
 			set { 
@@ -219,6 +218,7 @@
 			}
 		}
 
+		int y_offset = 2;
 		public int YOffset {
 			get { return y_offset; }
 			set { 
@@ -276,7 +276,16 @@
 
 		public int ActiveItem {
 			get { return selection.Index; }
-			set { selection.Index = value; }
+			set {
+				if (value == selection.Index)
+					return;
+				if (value < 0)
+					value = 0;
+				if (value > selection.Collection.Count - 1)
+					value = selection.Collection.Count - 1;
+
+				selection.Index = value;
+			}
 		}
 
 		float position;
@@ -302,7 +311,9 @@
 		FSpot.BrowsablePointer selection;
 		DisposableCache<string, Pixbuf> thumb_cache;
 
-		public Filmstrip (FSpot.BrowsablePointer selection) : this (selection, true) { }
+		public Filmstrip (FSpot.BrowsablePointer selection) : this (selection, true)
+		{
+		}
 
 		public Filmstrip (FSpot.BrowsablePointer selection, bool squared_thumbs) : base ()
 		{
@@ -313,7 +324,7 @@
 			this.selection.Collection.ItemsChanged += HandleCollectionItemsChanged;
 			this.squared_thumbs = squared_thumbs;
 			thumb_cache = new DisposableCache<string, Pixbuf> (30);
-			ThumbnailGenerator.Default.OnPixbufLoaded += delegate (PixbufLoader pl, string path, int order, Pixbuf p) {QueueDraw ();};
+			ThumbnailGenerator.Default.OnPixbufLoaded += HandlePixbufLoaded;
 		}
 	
 		int min_length = 400;
@@ -354,7 +365,6 @@
 			}
 		}
 
-	
 		Hashtable start_indexes;
 		int filmstrip_end_pos;
 		protected override bool OnExposeEvent (EventExpose evnt)
@@ -443,13 +453,13 @@
 			case Gdk.Key.Page_Down:
 			case Gdk.Key.Down:
 			case Gdk.Key.Right:
-				Position ++;
+				ActiveItem ++;
 				return true;
 				
 			case Gdk.Key.Page_Up:
 			case Gdk.Key.Up:
 			case Gdk.Key.Left:
-				Position --;
+				ActiveItem --;
 				return true;
 			}
 			return false;
@@ -463,28 +473,38 @@
 			QueueDraw ();
 		}
 
-		public void HandlePointerChanged (BrowsablePointer pointer, BrowsablePointerChangedArgs old)
+		void HandlePointerChanged (BrowsablePointer pointer, BrowsablePointerChangedArgs old)
 		{
 			Position = ActiveItem;
 		}
 
-		public void HandleCollectionChanged (IBrowsableCollection coll)
+		void HandleCollectionChanged (IBrowsableCollection coll)
 		{
 			Position = ActiveItem;
 			QueueDraw ();
 		}
 
-		public void HandleCollectionItemsChanged (IBrowsableCollection coll, BrowsableEventArgs args)
+		void HandleCollectionItemsChanged (IBrowsableCollection coll, BrowsableEventArgs args)
 		{
-			//FIXME: need to be smarter here...
-
 			if (!args.DataChanged)
 				return;
+			foreach (int item in args.Items)
+				thumb_cache.TryRemove (FSpot.ThumbnailGenerator.ThumbnailPath ((selection.Collection [item]).DefaultVersionUri));
 
-			// Invalidate the thumbs cache
-			thumb_cache.Dispose ();
-			thumb_cache = new DisposableCache<string, Pixbuf> (30);
+			//FIXME call QueueDrawArea
+			QueueDraw ();
+		}
+
+		void HandlePixbufLoaded (PixbufLoader pl, Uri uri, int order, Pixbuf p) {
+			if (!thumb_cache.Contains (FSpot.ThumbnailGenerator.ThumbnailPath (uri))) {
+				return;
+			}
+			
+			//FIXME use QueueDrawArea
+			//FIXME only invalidate if displayed
 			QueueDraw ();
+			
+
 		}
 
 		protected override bool OnButtonPressEvent (EventButton evnt)
@@ -537,9 +557,11 @@
 					} catch {
 						current = null;
 					}
+					thumb_cache.Add (thumb_path, null);
 				}
-			}
 
+			}
+			
 			if (!highlighted)
 				return current;
 
@@ -554,27 +576,35 @@
 		~Filmstrip ()
 		{
 			Log.DebugFormat ("Finalizer called on {0}. Should be Disposed", GetType ());		
-			lock (this) {
-				if (background_pixbuf != null)
-					background_pixbuf.Dispose ();
-				if (background_tile != null)
-					background_tile.Dispose ();
-			}
-			background_pixbuf = null;
-			background_tile = null;
+			Dispose (false);
 		}
 			
 		public override void Dispose ()
 		{
-			lock (this) {
+			Dispose (true);
+			base.Dispose ();
+			System.GC.SuppressFinalize (this);
+		}
+
+		bool is_disposed = false;
+		protected virtual void Dispose (bool disposing)
+		{
+			if (is_disposed)
+				return;
+			if (disposing) {
+				this.selection.Changed -= HandlePointerChanged;
+				this.selection.Collection.Changed -= HandleCollectionChanged;
+				this.selection.Collection.ItemsChanged -= HandleCollectionItemsChanged;
+				ThumbnailGenerator.Default.OnPixbufLoaded -= HandlePixbufLoaded;
 				if (background_pixbuf != null)
 					background_pixbuf.Dispose ();
 				if (background_tile != null)
 					background_tile.Dispose ();
+				thumb_cache.Dispose ();
 			}
-			background_pixbuf = null;
-			background_tile = null;
-			System.GC.SuppressFinalize (this);
+			//Free unmanaged resources
+
+			is_disposed = true;
 		}
 
 		public interface IAnimator



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