[f-spot/rubenv-gsoc-2009: 26/86] Add a status bar to show the progress of the RAW being loaded.



commit f80f08e23ae95b9a93151ad74272fcdfb7aef2db
Author: Ruben Vermeersch <ruben savanne be>
Date:   Tue Jul 28 15:41:28 2009 +0200

    Add a status bar to show the progress of the RAW being loaded.

 po/POTFILES.in                       |    1 +
 src/Loaders/GdkImageLoader.cs        |    5 ++-
 src/Loaders/IImageLoader.cs          |    1 +
 src/Loaders/LibrawImageLoader.cs     |   26 ++++++++++++--
 src/Loaders/ProgressHintEventArgs.cs |   24 +++++++++++++
 src/MainWindow.cs                    |    6 +++
 src/Makefile.am                      |    7 ++--
 src/PhotoImageView.cs                |   60 ++++++++++++++++++++++++++++++++++
 src/ui/main_window.ui                |    5 +--
 9 files changed, 122 insertions(+), 13 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index fa66818..a388f0f 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -75,6 +75,7 @@ src/Imaging/ImageFile.cs
 src/Imaging/IptcFile.cs
 src/ImportCommand.cs
 src/ItemAction.cs
+src/Loaders/LibrawImageLoader.cs
 src/Loupe.cs
 src/MainWindow.cs
 src/MetadataStore.cs
diff --git a/src/Loaders/GdkImageLoader.cs b/src/Loaders/GdkImageLoader.cs
index 8812279..58fcd30 100644
--- a/src/Loaders/GdkImageLoader.cs
+++ b/src/Loaders/GdkImageLoader.cs
@@ -44,6 +44,7 @@ namespace FSpot.Loaders {
 		new public event EventHandler<AreaPreparedEventArgs> AreaPrepared;
 		new public event EventHandler<AreaUpdatedEventArgs> AreaUpdated;
 		public event EventHandler<ItemsCompletedEventArgs> Completed;
+		public event EventHandler<ProgressHintEventArgs> ProgressHint;
 
 		public bool Loading { get; private set; }
 
@@ -159,10 +160,10 @@ namespace FSpot.Loaders {
 		void DoLoad ()
 		{
 			while (!is_disposed && !ItemsCompleted.Contains (ItemsRequested)) {
-				if (ItemsRequested.Contains (ImageLoaderItem.Thumbnail))
+				if (ItemsRequested.Contains (ImageLoaderItem.Thumbnail) && !ItemsCompleted.Contains (ImageLoaderItem.Thumbnail))
 					LoadThumbnail ();
 
-				if (ItemsRequested.Contains (ImageLoaderItem.Large))
+				if (ItemsRequested.Contains (ImageLoaderItem.Large) && !ItemsCompleted.Contains (ImageLoaderItem.Large))
 					LoadLarge ();
 			}
 
diff --git a/src/Loaders/IImageLoader.cs b/src/Loaders/IImageLoader.cs
index 1894a5a..55993f3 100644
--- a/src/Loaders/IImageLoader.cs
+++ b/src/Loaders/IImageLoader.cs
@@ -20,6 +20,7 @@ namespace FSpot.Loaders {
 		event EventHandler<AreaPreparedEventArgs> AreaPrepared;
 		event EventHandler<AreaUpdatedEventArgs> AreaUpdated;
 		event EventHandler<ItemsCompletedEventArgs> Completed;
+		event EventHandler<ProgressHintEventArgs> ProgressHint;
 
 		ImageLoaderItem Load (ImageLoaderItem items, bool async);
 
diff --git a/src/Loaders/LibrawImageLoader.cs b/src/Loaders/LibrawImageLoader.cs
index 5426864..64517ba 100644
--- a/src/Loaders/LibrawImageLoader.cs
+++ b/src/Loaders/LibrawImageLoader.cs
@@ -13,6 +13,7 @@ using FSpot.Loaders.Native;
 using FSpot.Platform;
 using FSpot.Utils;
 using Gdk;
+using Mono.Unix;
 using System;
 using System.Threading;
 
@@ -49,6 +50,7 @@ namespace FSpot.Loaders {
 		public event EventHandler<AreaPreparedEventArgs> AreaPrepared;
 		public event EventHandler<AreaUpdatedEventArgs> AreaUpdated;
 		public event EventHandler<ItemsCompletedEventArgs> Completed;
+		public event EventHandler<ProgressHintEventArgs> ProgressHint;
 
 		public bool Loading { get; private set; }
 
@@ -126,13 +128,13 @@ namespace FSpot.Loaders {
 		void DoLoad ()
 		{
 			while (!is_disposed && !ItemsCompleted.Contains (ItemsRequested)) {
-				if (ItemsRequested.Contains (ImageLoaderItem.Thumbnail))
+				if (ItemsRequested.Contains (ImageLoaderItem.Thumbnail) && !ItemsCompleted.Contains (ImageLoaderItem.Thumbnail))
 					LoadThumbnail ();
 
-				if (ItemsRequested.Contains (ImageLoaderItem.Large))
+				if (ItemsRequested.Contains (ImageLoaderItem.Large) && !ItemsCompleted.Contains (ImageLoaderItem.Large))
 					LoadLarge ();
 
-				if (ItemsRequested.Contains (ImageLoaderItem.Full))
+				if (ItemsRequested.Contains (ImageLoaderItem.Full) && !ItemsCompleted.Contains (ImageLoaderItem.Full))
 					LoadFull ();
 			}
 
@@ -209,8 +211,13 @@ namespace FSpot.Loaders {
 				return;
 
 			loader.ProgressUpdated += delegate (object o, ProgressUpdatedArgs args) {
-				Log.Debug ("Loading RAW: {0}/{1}", args.Done, args.Total);
+				if (args.Total <= 2)
+					return;
+
+				SignalProgressHint ((double) (args.Done + 1) / (double) (args.Total + 1));
 			};
+
+			SignalProgressHint (0.0);
 			full = loader.LoadFull ();
 			FullOrientation = PixbufOrientation.TopLeft;
 			if (full == null) {
@@ -222,6 +229,17 @@ namespace FSpot.Loaders {
 			SignalItemCompleted (ImageLoaderItem.Full);
 		}
 
+		void SignalProgressHint (double fraction)
+		{
+			EventHandler<ProgressHintEventArgs> eh = ProgressHint;
+			if (eh != null) {
+				GLib.Idle.Add (delegate {
+					eh (this, new ProgressHintEventArgs (Catalog.GetString ("Loading full size..."), fraction));
+					return false;
+				});
+			}
+		}
+
 		void WaitForCompletion (ImageLoaderItem items)
 		{
 			while (!ItemsCompleted.Contains(items)) {
diff --git a/src/Loaders/ProgressHintEventArgs.cs b/src/Loaders/ProgressHintEventArgs.cs
new file mode 100644
index 0000000..4ab494e
--- /dev/null
+++ b/src/Loaders/ProgressHintEventArgs.cs
@@ -0,0 +1,24 @@
+//
+// Fspot/Loaders/ProgressHintEventArgs.cs
+//
+// Author(s)
+//	Ruben Vermeersch  <ruben savanne be>
+//
+// This is free software. See COPYING for details
+//
+
+using System;
+
+namespace FSpot.Loaders {
+	public class ProgressHintEventArgs : EventArgs
+	{
+		public string Text { get; private set; }
+		public double Fraction { get; private set; }
+
+		public ProgressHintEventArgs (string text, double fraction) : base ()
+		{
+			this.Text = text;
+			this.Fraction = fraction;
+		}
+	}
+}
diff --git a/src/MainWindow.cs b/src/MainWindow.cs
index f1edd8c..44574c3 100644
--- a/src/MainWindow.cs
+++ b/src/MainWindow.cs
@@ -131,6 +131,12 @@ namespace FSpot
 		[GtkBeans.Builder.Object] Gtk.HBox tagbar;
 		[GtkBeans.Builder.Object] Gtk.VBox tag_entry_container;
 		[GtkBeans.Builder.Object] Gtk.VBox sidebar_vbox;
+
+		[GtkBeans.Builder.Object] Gtk.Container status_container;
+		public Gtk.Container StatusContainer {
+			get { return status_container; }
+		}
+
 		TagEntry tag_entry;
 	
 		Gtk.Toolbar toolbar;
diff --git a/src/Makefile.am b/src/Makefile.am
index 42f3c29..875edcd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -188,14 +188,15 @@ F_SPOT_CSDISTFILES =				\
 	$(srcdir)/Histogram.cs			\
 	$(srcdir)/Loaders/AreaPreparedEventArgs.cs		\
 	$(srcdir)/Loaders/AreaUpdatedEventArgs.cs		\
+	$(srcdir)/Loaders/GdkImageLoader.cs		\
+	$(srcdir)/Loaders/IImageLoader.cs		\
+	$(srcdir)/Loaders/IImageLoaderExtensions.cs		\
 	$(srcdir)/Loaders/ImageLoader.cs		\
 	$(srcdir)/Loaders/ImageLoaderItem.cs		\
 	$(srcdir)/Loaders/ImageLoaderItemExtensions.cs		\
-	$(srcdir)/Loaders/IImageLoader.cs		\
-	$(srcdir)/Loaders/IImageLoaderExtensions.cs		\
 	$(srcdir)/Loaders/ItemCompletedEventArgs.cs		\
-	$(srcdir)/Loaders/GdkImageLoader.cs		\
 	$(srcdir)/Loaders/LibrawImageLoader.cs		\
+	$(srcdir)/Loaders/ProgressHintEventArgs.cs		\
 	$(srcdir)/ImageLoaderThread.cs		\
 	$(srcdir)/ImportBackend.cs		\
 	$(srcdir)/ImportCommand.cs		\
diff --git a/src/PhotoImageView.cs b/src/PhotoImageView.cs
index c88d943..eaa9e3e 100644
--- a/src/PhotoImageView.cs
+++ b/src/PhotoImageView.cs
@@ -16,6 +16,7 @@ using FSpot.Utils;
 using FSpot.Loaders;
 
 using Gdk;
+using Gtk;
 
 namespace FSpot.Widgets {
 	public class PhotoImageView : ImageView {
@@ -33,6 +34,11 @@ namespace FSpot.Widgets {
 			item.Changed += HandlePhotoItemChanged;
 		}
 
+		~PhotoImageView () {
+			if (progress_bar_container != null && progress_bar != null)
+				progress_bar_container.Remove (progress_bar);
+		}
+
 		public BrowsablePointer Item {
 			get { return item; }
 		}
@@ -163,6 +169,55 @@ namespace FSpot.Widgets {
 		}
 #endregion
 
+#region progress bar
+		Container progress_bar_container;
+		ProgressBar progress_bar;
+		bool? progress_bar_present = null;
+
+		void UpdateStatus (string text, double fraction)
+		{
+			if (!CheckProgressBar ())
+				return;
+
+			progress_bar.Visible = true;
+			progress_bar.Fraction = fraction;
+			progress_bar.Text = text;
+		}
+
+		bool CheckProgressBar ()
+		{
+			if (progress_bar_present != null)
+				return (bool) progress_bar_present;
+
+			// I do not like the trip through MainWindow here, can this be
+			// done better?
+			if (MainWindow.Toplevel == null) {
+				progress_bar_present = false;
+				return false;
+			}
+
+			progress_bar = new ProgressBar ();
+			progress_bar.Visible = false;
+			progress_bar_container = MainWindow.Toplevel.StatusContainer;
+			progress_bar_container.Add (progress_bar);
+			progress_bar_present = true;
+
+			return true;
+		}
+
+		void HideStatus () {
+			if (!CheckProgressBar ())
+				return;
+
+			progress_bar.Visible = false;
+		}
+
+		void HandleProgressHint (object sender, ProgressHintEventArgs args)
+		{
+			UpdateStatus (args.Text, args.Fraction);
+		}
+#endregion
+
 #region loader		
 		uint timer;
 		IImageLoader loader;
@@ -174,6 +229,7 @@ namespace FSpot.Widgets {
 			timer = Log.DebugTimerStart ();
 			if (loader != null)
 				loader.Dispose ();
+			HideStatus ();
 
 			current_item = ImageLoaderItem.None;
 
@@ -181,6 +237,7 @@ namespace FSpot.Widgets {
 			loader = ImageLoader.Create (uri);
 			loader.AreaPrepared += HandlePixbufPrepared;
 			loader.AreaUpdated += HandlePixbufAreaUpdated;
+			loader.ProgressHint += HandleProgressHint;
 			loader.Load (ImageLoaderItem.Thumbnail | ImageLoaderItem.Large | ImageLoaderItem.Full, HandleCompleted);
 		}
 
@@ -197,6 +254,8 @@ namespace FSpot.Widgets {
 				return;
 
 			current_item = args.Item.Largest ();
+			Log.Debug ("Switched to new item: {0}", current_item);
+			Log.Debug ("Prepared is new: {0}", prepared_is_new);
 
 			Gdk.Pixbuf prev = Pixbuf;
 			PixbufOrientation orientation = Accelerometer.GetViewOrientation (loader.PixbufOrientation (current_item));
@@ -225,6 +284,7 @@ namespace FSpot.Widgets {
 		void HandleCompleted (object sender, ItemsCompletedEventArgs args)
 		{
 			Log.DebugTimerPrint (timer, "Loading image took {0} (" + args.Items.ToString () + ")");
+			HideStatus ();
 			IImageLoader loader = sender as IImageLoader;
 			if (loader != this.loader)
 				return;
diff --git a/src/ui/main_window.ui b/src/ui/main_window.ui
index 7082d1d..ddfbe52 100644
--- a/src/ui/main_window.ui
+++ b/src/ui/main_window.ui
@@ -867,15 +867,12 @@
           <object class="GtkHBox" id="hbox61">
             <property name="visible">True</property>
             <child>
-              <object class="GtkHBox" id="hbox62">
+              <object class="GtkHBox" id="status_container">
                 <property name="width_request">142</property>
                 <property name="visible">True</property>
                 <child>
                   <placeholder/>
                 </child>
-                <child>
-                  <placeholder/>
-                </child>
               </object>
               <packing>
                 <property name="expand">False</property>



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