[banshee] [Playlist Sync] Update sync options when src change



commit 15ac1586a596eb38267737fd1b41bf52232c84aa
Author: Gabriel Burt <gabriel burt gmail com>
Date:   Mon Dec 14 16:02:33 2009 -0800

    [Playlist Sync] Update sync options when src change
    
    If library sources are added or removed (eg disabling Podcasts) that is
    reflected, and if the playlists in a library are added/changed/removed
    they are also reflected in the dropdown.

 src/Dap/Banshee.Dap/Banshee.Dap.Gui/DapContent.cs  |   87 +++++------
 .../Banshee.Dap.Gui/LibrarySyncOptions.cs          |  163 ++++++++++++++++++++
 src/Dap/Banshee.Dap/Banshee.Dap/DapSync.cs         |  105 +++++++++----
 src/Dap/Banshee.Dap/Makefile.am                    |    1 +
 4 files changed, 277 insertions(+), 79 deletions(-)
---
diff --git a/src/Dap/Banshee.Dap/Banshee.Dap.Gui/DapContent.cs b/src/Dap/Banshee.Dap/Banshee.Dap.Gui/DapContent.cs
index efacfad..cc64f8a 100644
--- a/src/Dap/Banshee.Dap/Banshee.Dap.Gui/DapContent.cs
+++ b/src/Dap/Banshee.Dap/Banshee.Dap.Gui/DapContent.cs
@@ -27,6 +27,7 @@
 //
 
 using System;
+using System.Collections.Generic;
 using System.Linq;
 
 using Gtk;
@@ -50,6 +51,8 @@ namespace Banshee.Dap.Gui
     public class DapContent : DapPropertiesDisplay
     {
         private Label title;
+        private SimpleTable<DapLibrarySync> table;
+        private Dictionary<DapLibrarySync, LibrarySyncOptions> library_opts = new Dictionary<DapLibrarySync, LibrarySyncOptions> ();
         private DapSource dap;
 
         // Ugh, this is to avoid the GLib.MissingIntPtrCtorException seen by some; BGO #552169
@@ -66,6 +69,16 @@ namespace Banshee.Dap.Gui
             dap.Properties.PropertyChanged += OnPropertyChanged;
         }
 
+        public override void Dispose ()
+        {
+            foreach (var opt in library_opts.Values) {
+                opt.Dispose ();
+            }
+            library_opts.Clear ();
+
+            base.Dispose ();
+        }
+
         private void BuildWidgets ()
         {
             HBox split_box = new HBox ();
@@ -79,65 +92,27 @@ namespace Banshee.Dap.Gui
 
             // Define custom preference widgetry
             var hbox = new HBox ();
-            var table = new Table ((uint)dap.Sync.Libraries.Count (), 2, false) {
-                RowSpacing = 6,
-                ColumnSpacing = 6
-            };
+            table = new SimpleTable<DapLibrarySync> ();
+
+            dap.Sync.LibraryAdded += l => AddLibrary (l);
+            dap.Sync.LibraryRemoved += l => RemoveLibrary (l);
 
-            uint i = 0;
-            foreach (var iter_sync in dap.Sync.LibrarySyncs) {
-                var library_sync = iter_sync;
-                var library = library_sync.Library;
-                // Translators: {0} is the name of a library, eg 'Music' or 'Podcasts'
-                var label = new Label (String.Format (Catalog.GetString ("{0}:"), library.Name)) { Xalign = 1f };
-                table.Attach (label, 0, 1, i, i + 1);
-
-                var combo = new DictionaryComboBox<DatabaseSource> ();
-                combo.RowSeparatorFunc = (model, iter) => { return (string)model.GetValue (iter, 0) == "---"; };
-                combo.Add (Catalog.GetString ("Manage manually"), null);
-                combo.Add (Catalog.GetString ("Sync entire library"), null);
-
-                var playlists = library.Children.Where (c => c is DatabaseSource).Cast<DatabaseSource> ().ToList ();
-                if (playlists.Count > 0) {
-                    combo.Add ("---", null);
-
-                    foreach (var playlist in playlists) {
-                        // Translators: {0} is the name of a playlist
-                        combo.Add (String.Format (Catalog.GetString ("Sync from â??{0}â??"), playlist.Name), playlist);
-                    }
-                }
-
-                if (!library_sync.Enabled)
-                    combo.Active = 0;
-                else if (library_sync.SyncEntireLibrary)
-                    combo.Active = 1;
-                else if (library_sync.SyncSource != null)
-                    combo.ActiveValue = library_sync.SyncSource;
-
-                combo.Changed += (o, a) => {
-                    library_sync.Enabled = combo.Active != 0;
-                    library_sync.SyncEntireLibrary = combo.Active == 1;
-
-                    if (combo.Active > 1) {
-                        library_sync.SyncSource = combo.ActiveValue;
-                    }
-                };
-                table.Attach (combo, 1, 2, i, i + 1);
-                i++;
+            foreach (var sync in dap.Sync.Libraries) {
+                AddLibrary (sync);
             }
 
             hbox.PackStart (table, false, false, 0);
             hbox.ShowAll ();
             dap.Preferences["sync"]["library-options"].DisplayWidget = hbox;
 
-            Banshee.Preferences.Gui.NotebookPage properties = new Banshee.Preferences.Gui.NotebookPage (dap.Preferences);
-            properties.BorderWidth = 0;
+            var properties = new Banshee.Preferences.Gui.NotebookPage (dap.Preferences) {
+                BorderWidth = 0
+            };
 
             content_box.PackStart (title, false, false, 0);
             content_box.PackStart (properties, false, false, 0);
 
-            Image image = new Image (LargeIcon);
-            image.Yalign = 0.0f;
+            var image = new Image (LargeIcon) { Yalign = 0.0f };
 
             split_box.PackStart (image, false, true, 0);
             split_box.PackEnd (content_box, true, true, 0);
@@ -146,6 +121,22 @@ namespace Banshee.Dap.Gui
             ShowAll ();
         }
 
+        private void AddLibrary (DapLibrarySync library_sync)
+        {
+            var opts = new LibrarySyncOptions (library_sync);
+            table.AddRow (library_sync, opts.RowCells);
+            table.ShowAll ();
+            library_opts.Add (library_sync, opts);
+        }
+
+        private void RemoveLibrary (DapLibrarySync library_sync)
+        {
+            table.RemoveRow (library_sync);
+            var opts = library_opts[library_sync];
+            library_opts.Remove (library_sync);
+            opts.Dispose ();
+        }
+
         private void BuildActions ()
         {
             if (actions == null) {
diff --git a/src/Dap/Banshee.Dap/Banshee.Dap.Gui/LibrarySyncOptions.cs b/src/Dap/Banshee.Dap/Banshee.Dap.Gui/LibrarySyncOptions.cs
new file mode 100644
index 0000000..3bb0a02
--- /dev/null
+++ b/src/Dap/Banshee.Dap/Banshee.Dap.Gui/LibrarySyncOptions.cs
@@ -0,0 +1,163 @@
+//
+// LibrarySyncOptions.cs
+//
+// Authors:
+//   Gabriel Burt <gburt novell com>
+//
+// Copyright (C) 2009 Novell, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Linq;
+
+using Gtk;
+
+using Hyena;
+using Hyena.Data;
+using Hyena.Widgets;
+
+using Mono.Unix;
+
+using Banshee.Dap;
+using Banshee.Sources.Gui;
+using Banshee.ServiceStack;
+using Banshee.Preferences;
+using Banshee.Sources;
+using Banshee.Preferences.Gui;
+using Banshee.Widgets;
+
+namespace Banshee.Dap.Gui
+{
+    public class LibrarySyncOptions : IDisposable
+    {
+        private DapLibrarySync library_sync;
+        private DictionaryComboBox<DatabaseSource> combo;
+        private TreeIter sep_iter;
+        private int playlist_count = 0;
+
+        public Widget [] RowCells { get; private set; }
+
+        public LibrarySyncOptions (DapLibrarySync library_sync)
+        {
+            this.library_sync = library_sync;
+            var library = library_sync.Library;
+
+            // Translators: {0} is the name of a library, eg 'Music' or 'Podcasts'
+            var label = new Label (String.Format (Catalog.GetString ("{0}:"), library.Name)) { Xalign = 1f };
+
+            // Create the combo for selecting what type of sync to do for this library
+            combo = new DictionaryComboBox<DatabaseSource> ();
+            combo.RowSeparatorFunc = (model, iter) => { return (string)model.GetValue (iter, 0) == "---"; };
+            combo.Add (null, Catalog.GetString ("Manage manually"), -10);
+            combo.Add (null, Catalog.GetString ("Sync entire library"), -9);
+
+            foreach (var child in library.Children) {
+                AddPlaylist (child);
+            }
+
+            library.ChildSourceAdded   += OnChildSourceAdded;
+            library.ChildSourceRemoved += OnChildSourceRemoved;
+
+            if (!library_sync.Enabled)
+                combo.Active = 0;
+            else if (library_sync.SyncEntireLibrary)
+                combo.Active = 1;
+            else if (library_sync.SyncSource != null)
+                combo.ActiveValue = library_sync.SyncSource;
+
+            combo.Changed += (o, a) => {
+                library_sync.Enabled = combo.Active != 0;
+                library_sync.SyncEntireLibrary = combo.Active == 1;
+
+                if (combo.Active > 1) {
+                    library_sync.SyncSource = combo.ActiveValue;
+                }
+            };
+
+            RowCells = new Widget [] { label, combo };
+        }
+
+        public void Dispose ()
+        {
+            library_sync.Library.ChildSourceAdded   -= OnChildSourceAdded;
+            library_sync.Library.ChildSourceRemoved -= OnChildSourceRemoved;
+
+            foreach (var child in library_sync.Library.Children) {
+                RemovePlaylist (child, true);
+            }
+        }
+
+        private void AddPlaylist (Source source)
+        {
+            var db_src = source as DatabaseSource;
+            if (db_src == null)
+                return;
+
+            if (playlist_count == 0) {
+                sep_iter = combo.Add (null, "---", -8);
+            }
+
+            // Translators: {0} is the name of a playlist
+            combo.Add (db_src, String.Format (Catalog.GetString ("Sync from â??{0}â??"), db_src.Name), db_src.Order);
+            db_src.Updated += OnPlaylistChanged;
+            playlist_count++;
+        }
+
+        private void RemovePlaylist (Source source, bool disposing)
+        {
+            var db_src = source as DatabaseSource;
+            if (db_src == null)
+                return;
+
+            // If this was the selected playlist, change to manually manage
+            if (!disposing && db_src == combo.ActiveValue) {
+                combo.Active = 0;
+            }
+
+            if (combo.Remove (db_src)) {
+                db_src.Updated -= OnPlaylistChanged;
+                playlist_count--;
+
+                if (playlist_count == 0) {
+                    combo.Remove (ref sep_iter);
+                    sep_iter = TreeIter.Zero;
+                }
+            }
+        }
+
+        private void OnPlaylistChanged (object o, EventArgs args)
+        {
+            var db_src = o as DatabaseSource;
+            combo.Update (db_src, String.Format (Catalog.GetString ("Sync from â??{0}â??"), db_src.Name), db_src.Order);
+        }
+
+        private void OnChildSourceAdded (SourceEventArgs args)
+        {
+            AddPlaylist (args.Source);
+        }
+
+        private void OnChildSourceRemoved (SourceEventArgs args)
+        {
+            RemovePlaylist (args.Source, false);
+        }
+    }
+}
diff --git a/src/Dap/Banshee.Dap/Banshee.Dap/DapSync.cs b/src/Dap/Banshee.Dap/Banshee.Dap/DapSync.cs
index 461a174..44436dc 100644
--- a/src/Dap/Banshee.Dap/Banshee.Dap/DapSync.cs
+++ b/src/Dap/Banshee.Dap/Banshee.Dap/DapSync.cs
@@ -27,6 +27,7 @@
 //
 
 using System;
+using System.Linq;
 using System.Collections.Generic;
 
 using Mono.Unix;
@@ -70,6 +71,9 @@ namespace Banshee.Dap
 
         public event Action<DapSync> Updated;
 
+        public event Action<DapLibrarySync> LibraryAdded;
+        public event Action<DapLibrarySync> LibraryRemoved;
+
         internal string ConfigurationNamespace {
             get { return conf_ns; }
         }
@@ -80,7 +84,7 @@ namespace Banshee.Dap
             get { return dap; }
         }
 
-        public IEnumerable<DapLibrarySync> LibrarySyncs {
+        public IList<DapLibrarySync> Libraries {
             get { return library_syncs; }
         }
 
@@ -109,12 +113,9 @@ namespace Banshee.Dap
 
         public void Dispose ()
         {
-            foreach (LibrarySource source in Libraries) {
-                source.TracksAdded -= OnLibraryChanged;
-                source.TracksDeleted -= OnLibraryChanged;
-            }
-
             foreach (DapLibrarySync sync in library_syncs) {
+                sync.Library.TracksAdded -= OnLibraryChanged;
+                sync.Library.TracksDeleted -= OnLibraryChanged;
                 sync.Dispose ();
             }
         }
@@ -161,20 +162,63 @@ namespace Banshee.Dap
 
         private void BuildSyncLists ()
         {
-            foreach (LibrarySource source in Libraries) {
-                DapLibrarySync library_sync = new DapLibrarySync (this, source);
-                library_syncs.Add (library_sync);
-                //pref_sections.Add (library_sync.PrefsSection);
-                //library_sync.PrefsSection.Order = ++i;
-
-                source.TracksAdded += OnLibraryChanged;
-                source.TracksDeleted += OnLibraryChanged;
+            var src_mgr = ServiceManager.SourceManager;
+            src_mgr.SourceAdded   += (a) => AddLibrary (a.Source, true);
+            src_mgr.SourceRemoved += (a) => RemoveLibrary (a.Source);
+
+            foreach (var src in src_mgr.Sources) {
+                AddLibrary (src, false);
             }
 
+            SortLibraries ();
+
             dap.TracksAdded += OnDapChanged;
             dap.TracksDeleted += OnDapChanged;
         }
 
+        private void AddLibrary (Source source, bool initialized)
+        {
+            var library = GetSyncableLibrary (source);
+            if (library != null) {
+                var sync = new DapLibrarySync (this, library);
+                library_syncs.Add (sync);
+                library.TracksAdded += OnLibraryChanged;
+                library.TracksDeleted += OnLibraryChanged;
+
+                if (initialized) {
+                    SortLibraries ();
+
+                    var h = LibraryAdded;
+                    if (h != null) {
+                        h (sync);
+                    }
+                }
+            }
+        }
+
+        private void RemoveLibrary (Source source)
+        {
+            var library = GetSyncableLibrary (source);
+            if (library != null) {
+                var sync = library_syncs.First (s => s.Library == library);
+                library_syncs.Remove (sync);
+                sync.Library.TracksAdded -= OnLibraryChanged;
+                sync.Library.TracksDeleted -= OnLibraryChanged;
+
+                var h = LibraryRemoved;
+                if (h != null) {
+                    h (sync);
+                }
+
+                sync.Dispose ();
+            }
+        }
+
+        private void SortLibraries ()
+        {
+            library_syncs.Sort ((a, b) => a.Library.Order.CompareTo (b.Library.Order));
+        }
+
         /*private void OnManuallyManageChanged (Root preference)
         {
             UpdateSensitivities ();
@@ -226,27 +270,26 @@ namespace Banshee.Dap
             }
          }
 
-        internal IEnumerable<LibrarySource> Libraries {
-            get {
-                List<Source> sources = new List<Source> (ServiceManager.SourceManager.Sources);
-                sources.Sort (delegate (Source a, Source b) {
-                    return a.Order.CompareTo (b.Order);
-                });
+        private LibrarySource GetSyncableLibrary (Source source)
+        {
+            var library = source as LibrarySource;
+            if (library == null)
+                return null;
 
-                if (!dap.SupportsVideo) {
-                    sources.Remove (ServiceManager.SourceManager.VideoLibrary);
-                }
+                //List<Source> sources = new List<Source> (ServiceManager.SourceManager.Sources);
+                //sources.Sort (delegate (Source a, Source b) {
+                    //return a.Order.CompareTo (b.Order);
+                //});
 
-                if (!dap.SupportsPodcasts) {
-                    sources.RemoveAll (s => s.UniqueId == "PodcastSource-PodcastLibrary");
-                }
+            if (!dap.SupportsVideo && library == ServiceManager.SourceManager.VideoLibrary) {
+                return null;
+            }
 
-                foreach (Source source in sources) {
-                    if (source is LibrarySource) {
-                        yield return source as LibrarySource;
-                    }
-                }
+            if (!dap.SupportsPodcasts && library.UniqueId == "PodcastSource-PodcastLibrary") {
+                return null;
             }
+
+            return library;
         }
 
         public int ItemCount {
diff --git a/src/Dap/Banshee.Dap/Makefile.am b/src/Dap/Banshee.Dap/Makefile.am
index c181c85..ebb4383 100644
--- a/src/Dap/Banshee.Dap/Makefile.am
+++ b/src/Dap/Banshee.Dap/Makefile.am
@@ -9,6 +9,7 @@ SOURCES =  \
 	Banshee.Dap.Gui/DapInfoBar.cs \
 	Banshee.Dap.Gui/DapPropertiesDialog.cs \
 	Banshee.Dap.Gui/DapPropertiesDisplay.cs \
+	Banshee.Dap.Gui/LibrarySyncOptions.cs \
 	Banshee.Dap.Gui/PurchasedMusicActions.cs \
 	Banshee.Dap/DapLibrarySync.cs \
 	Banshee.Dap/DapService.cs \



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