banshee r4559 - in trunk/banshee: . src/Core/Banshee.Services/Banshee.Sources src/Core/Banshee.ThickClient/Banshee.Collection.Gui src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor src/Core/Banshee.Widgets/Banshee.Widgets



Author: abock
Date: Wed Sep 17 17:07:39 2008
New Revision: 4559
URL: http://svn.gnome.org/viewvc/banshee?rev=4559&view=rev

Log:
2008-09-17  Aaron Bockover  <abock gnome org>

    * src/Core/Banshee.ThickClient/Banshee.Collection.Gui/ColumnCellDuration.cs:
    Use the new static override in DurationStatusFormatters

    * src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/FieldPage.cs:
    Implement Changed event, raise when fields actually change

    * src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/ITrackEditorPage.cs:
    Add Changed event

    * src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/HelpPage.cs:
    * src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/StatisticsPage.cs:
    Implement Change event, do not raise, because um, nothing is editable here

    * src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/TrackEditorDialog.cs:
    Open a confirmation dialog when the user tries to cancel and has made
    changes

    * src/Core/Banshee.Services/Banshee.Sources/DurationStatusFormatters.cs:
    Added a new duration formatter, ApproximateVerboseFormatter and added
    overrides that do not require a StringBuilder

    * src/Core/Banshee.Widgets/Banshee.Widgets/HigMessageDialog.cs: Expose
    MessageLabel so it can be edited after the fact



Modified:
   trunk/banshee/ChangeLog
   trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/DurationStatusFormatters.cs
   trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Collection.Gui/ColumnCellDuration.cs
   trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/FieldPage.cs
   trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/HelpPage.cs
   trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/ITrackEditorPage.cs
   trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/StatisticsPage.cs
   trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/TrackEditorDialog.cs
   trunk/banshee/src/Core/Banshee.Widgets/Banshee.Widgets/HigMessageDialog.cs

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/DurationStatusFormatters.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/DurationStatusFormatters.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/DurationStatusFormatters.cs	Wed Sep 17 17:07:39 2008
@@ -38,7 +38,9 @@
     public delegate void DurationStatusFormatHandler (StringBuilder builder, TimeSpan span);
     
     public class DurationStatusFormatters : List<DurationStatusFormatHandler>
-    {       
+    {
+        private static StringBuilder default_builder = new StringBuilder ();
+        
         public DurationStatusFormatters ()
         {
             Add (AwesomeConciseFormatter);
@@ -46,6 +48,15 @@
             Add (ConfusingPreciseFormatter);
         }
         
+        public static string AwesomeConciseFormatter (TimeSpan span)
+        {
+            lock (default_builder) {
+                default_builder.Remove (0, default_builder.Length);
+                AwesomeConciseFormatter (default_builder, span);
+                return default_builder.ToString ();
+            }
+        }
+        
         public static void AwesomeConciseFormatter (StringBuilder builder, TimeSpan span)
         {
             if (span.Days > 0) {
@@ -63,6 +74,15 @@
             }
         }
         
+        public static string AnnoyingPreciseFormatter (TimeSpan span)
+        {
+            lock (default_builder) {
+                default_builder.Remove (0, default_builder.Length);
+                AnnoyingPreciseFormatter (default_builder, span);
+                return default_builder.ToString ();
+            }
+        }
+        
         public static void AnnoyingPreciseFormatter (StringBuilder builder, TimeSpan span)
         {
             if (span.Days > 0) {
@@ -71,7 +91,7 @@
             }
             
             if (span.Hours > 0) {
-                builder.AppendFormat(Catalog.GetPluralString ("{0} hour", "{0} hours", span.Hours), span.Hours);
+                builder.AppendFormat (Catalog.GetPluralString ("{0} hour", "{0} hours", span.Hours), span.Hours);
                 builder.Append (", ");
             }
 
@@ -80,6 +100,15 @@
             builder.AppendFormat (Catalog.GetPluralString ("{0} second", "{0} seconds", span.Seconds), span.Seconds);
         }
         
+        public static string ConfusingPreciseFormatter (TimeSpan span)
+        {
+            lock (default_builder) {
+                default_builder.Remove (0, default_builder.Length);
+                ConfusingPreciseFormatter (default_builder, span);
+                return default_builder.ToString ();
+            }
+        }
+        
         public static void ConfusingPreciseFormatter (StringBuilder builder, TimeSpan span)
         {
             if (span.Days > 0) {
@@ -94,5 +123,27 @@
                 builder.AppendFormat ("{0:00}:{1:00}", span.Minutes, span.Seconds);
             }
         }
+        
+        public static string ApproximateVerboseFormatter (TimeSpan span)
+        {
+            lock (default_builder) {
+                default_builder.Remove (0, default_builder.Length);
+                ApproximateVerboseFormatter (default_builder, span);
+                return default_builder.ToString ();
+            }
+        }
+        
+        public static void ApproximateVerboseFormatter (StringBuilder builder, TimeSpan span)
+        {
+            if (span.Days > 0) {
+                builder.AppendFormat (Catalog.GetPluralString ("{0} day", "{0} days", span.Days), span.Days);
+            } if (span.Hours > 0) {
+                builder.AppendFormat (Catalog.GetPluralString ("{0} hour", "{0} hours", span.Hours), span.Hours);
+            } else if (span.Minutes > 0) {
+                builder.AppendFormat (Catalog.GetPluralString ("{0} minute", "{0} minutes", span.Minutes), span.Minutes);
+            } else {
+                builder.AppendFormat (Catalog.GetPluralString ("{0} second", "{0} seconds", span.Seconds), span.Seconds);
+            }
+        }
     }
 }

Modified: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Collection.Gui/ColumnCellDuration.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Collection.Gui/ColumnCellDuration.cs	(original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Collection.Gui/ColumnCellDuration.cs	Wed Sep 17 17:07:39 2008
@@ -34,8 +34,6 @@
 {
     public class ColumnCellDuration : ColumnCellText
     {
-        private System.Text.StringBuilder builder = new System.Text.StringBuilder ();
-    
         public ColumnCellDuration (string property, bool expand) : base (property, expand)
         {
             Alignment = Pango.Alignment.Right;
@@ -56,9 +54,7 @@
                     return String.Empty;
                 }
                 
-                builder.Remove (0, builder.Length);
-                Banshee.Sources.DurationStatusFormatters.ConfusingPreciseFormatter (builder, TimeSpan.FromSeconds (seconds));
-                return builder.ToString ();
+                return Banshee.Sources.DurationStatusFormatters.ConfusingPreciseFormatter (TimeSpan.FromSeconds (seconds));
             }
         }
     }

Modified: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/FieldPage.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/FieldPage.cs	(original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/FieldPage.cs	Wed Sep 17 17:07:39 2008
@@ -41,6 +41,8 @@
         public delegate string FieldLabelClosure (EditorTrackInfo track, Widget widget);
         public delegate void FieldValueClosure (EditorTrackInfo track, Widget widget);
         
+        public event EventHandler Changed;
+        
         private TrackEditorDialog dialog;
         protected TrackEditorDialog Dialog {
             get { return dialog; }
@@ -80,6 +82,18 @@
         {
         }
         
+        protected virtual void OnChanged ()
+        {
+            if (current_track == null) {
+                return;
+            }
+            
+            EventHandler handler = Changed;
+            if (handler != null) {
+                handler (this, EventArgs.Empty);
+            }
+        }
+        
         public virtual bool MultipleTracks {
             get { return dialog.TrackCount > 1; }
         }
@@ -150,6 +164,7 @@
             IEditorField editor_field = field as IEditorField;
             if (editor_field != null) {
                 editor_field.Changed += delegate {
+                    OnChanged ();
                     if (CurrentTrack != null) {
                         slot.WriteClosure (CurrentTrack, slot.Field);
                     }

Modified: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/HelpPage.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/HelpPage.cs	(original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/HelpPage.cs	Wed Sep 17 17:07:39 2008
@@ -37,6 +37,8 @@
         private Box tab_widget;
         private TrackEditorDialog dialog;
         
+        public event EventHandler Changed;
+        
         public HelpPage () : base (0.5f, 0.5f, 0.0f, 0.0f)
         {
             Image help = new Image ();

Modified: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/ITrackEditorPage.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/ITrackEditorPage.cs	(original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/ITrackEditorPage.cs	Wed Sep 17 17:07:39 2008
@@ -34,6 +34,8 @@
 {
     public interface ITrackEditorPage
     {
+        event EventHandler Changed;
+        
         void Initialize (TrackEditorDialog dialog);
         void LoadTrack (EditorTrackInfo track);
         

Modified: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/StatisticsPage.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/StatisticsPage.cs	(original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/StatisticsPage.cs	Wed Sep 17 17:07:39 2008
@@ -38,6 +38,8 @@
         private CellRendererText name_renderer;
         private ListStore model;
         private TreeView view;
+        
+        public event EventHandler Changed;
 
         public StatisticsPage ()
         {

Modified: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/TrackEditorDialog.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/TrackEditorDialog.cs	(original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/TrackEditorDialog.cs	Wed Sep 17 17:07:39 2008
@@ -40,6 +40,7 @@
 using Banshee.Collection.Database;
 using Banshee.ServiceStack;
 
+using Banshee.Widgets;
 using Banshee.Gui.Dialogs;
 using Banshee.Collection.Gui;
 
@@ -60,11 +61,74 @@
         public static void Run (TrackListModel model, EditorMode mode)
         {
             TrackEditorDialog track_editor = new TrackEditorDialog (model, mode);
-            try {
-                track_editor.Run ();
-            } finally {
+            track_editor.Response += delegate (object o, ResponseArgs args) {
+                if (args.ResponseId == ResponseType.Ok) {
+                    track_editor.Save ();
+                } else if (track_editor.ChangesMade) {
+                    HigMessageDialog message_dialog = new HigMessageDialog (
+                        track_editor, DialogFlags.Modal, MessageType.Warning, ButtonsType.None, 
+                        
+                        String.Format (Catalog.GetPluralString (
+                            "Save the changes made to the open track?",
+                            "Save the changes made to the {0} open tracks?",
+                            track_editor.TrackCount), track_editor.TrackCount),
+                            
+                        String.Empty
+                    );
+                    
+                    UpdateCancelMessage (track_editor, message_dialog);
+                    uint timeout = 0;
+                    timeout = GLib.Timeout.Add (1000, delegate {
+                        bool result = UpdateCancelMessage (track_editor, message_dialog);
+                        if (!result) {
+                            timeout = 0;
+                        }
+                        return result;
+                    });
+                    
+                    message_dialog.AddButton (Catalog.GetString ("Close _without Saving"), ResponseType.Close, false);
+                    message_dialog.AddButton (Stock.Cancel, ResponseType.Cancel, false);
+                    message_dialog.AddButton (Stock.Save, ResponseType.Ok, true);
+                    
+                    try {
+                        switch ((ResponseType)message_dialog.Run ()) {
+                            case ResponseType.Ok:
+                                track_editor.Save ();
+                                break;
+                            case ResponseType.Close:
+                                break;
+                            case ResponseType.Cancel:
+                            case ResponseType.DeleteEvent:
+                                return;
+                        }
+                    } finally {
+                        if (timeout > 0) {
+                            GLib.Source.Remove (timeout);
+                        }
+                        message_dialog.Destroy ();
+                    }
+                }
+                
                 track_editor.Destroy ();
+            };
+            
+            track_editor.Run ();
+        }
+        
+        private static bool UpdateCancelMessage (TrackEditorDialog trackEditor, HigMessageDialog messageDialog)
+        {
+            if (messageDialog == null) {
+                return false;
             }
+            
+            messageDialog.MessageLabel.Text = String.Format (Catalog.GetString (
+                "If you don't save, changes from the last {0} will be permanently lost."),
+                Banshee.Sources.DurationStatusFormatters.ApproximateVerboseFormatter (
+                    DateTime.Now - trackEditor.first_change_time
+                )
+            );
+            
+            return messageDialog.IsMapped;
         }
     
         public delegate void EditorTrackOperationClosure (EditorTrackInfo track);
@@ -79,6 +143,19 @@
         private Label edit_notif_label;
         private object tooltip_host;
         
+        private DateTime first_change_time;
+        private bool changes_made;
+        public bool ChangesMade {
+            get { return changes_made; }
+            private set {
+                if (!changes_made && value) {
+                    first_change_time = DateTime.Now;
+                }
+                
+                changes_made = value;
+            }
+        }
+        
         private Notebook notebook;
         public Notebook Notebook {
             get { return notebook; }
@@ -205,6 +282,7 @@
                         page.Initialize (this);
                         page.Widget.Show ();
                     }
+                    page.Changed += OnPageChanged;
                 } catch (Exception e) {
                     Hyena.Log.Exception ("Invalid NotebookPage extension node. Should implement ITrackEditorPage.", e);
                 }
@@ -343,6 +421,11 @@
             sync_all_button.WidthRequest = (children[1].Allocation.X + 
                 children[1].Allocation.Width) - children[0].Allocation.X - 1;
         }
+        
+        private void OnPageChanged (object o, EventArgs args)
+        {
+            ChangesMade = true;
+        }
 
 #endregion
         
@@ -496,6 +579,25 @@
 #endregion
 
 #region Saving
+
+        protected override bool OnDeleteEvent (Gdk.Event evnt)
+        {
+            return true;
+            //return base.OnDeleteEvent (evnt);
+        }
+
+
+        protected override void OnResponse (ResponseType response_id)
+        {
+            base.OnResponse (response_id);
+        }
+
+
+        public void Save ()
+        {
+            Console.WriteLine ("If this were implemented, your data would now be saved.");
+        }
+
         
        /* private void OnSaveButtonClicked (object o, EventArgs args)
         {

Modified: trunk/banshee/src/Core/Banshee.Widgets/Banshee.Widgets/HigMessageDialog.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Widgets/Banshee.Widgets/HigMessageDialog.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Widgets/Banshee.Widgets/HigMessageDialog.cs	Wed Sep 17 17:07:39 2008
@@ -33,6 +33,7 @@
         private Gtk.AccelGroup accel_group;
         private Gtk.Image image;
         private Gtk.VBox label_vbox;
+        private Gtk.Label message_label;
 
         public HigMessageDialog(Gtk.Window parent,
                      Gtk.DialogFlags flags,
@@ -98,7 +99,7 @@
             label.Show ();
             label_vbox.PackStart (label, false, false, 0);
 
-            label = new Gtk.Label ();
+            message_label = label = new Gtk.Label ();
             label.Markup = msg;
             label.UseMarkup = true;
             label.Justify = Gtk.Justification.Left;
@@ -225,6 +226,10 @@
             }
         }
         
+        public Gtk.Label MessageLabel {
+            get { return message_label; }
+        }
+        
         public Gtk.VBox LabelVBox {
             get { return label_vbox; }
         }



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