banshee r3830 - in trunk/banshee: . src/Backends/Banshee.GStreamer/Banshee.GStreamer src/Core/Banshee.Services/Banshee.ServiceStack src/Core/Banshee.ThickClient/Banshee.Gui src/Extensions/Banshee.AudioCd/Banshee.AudioCd src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea



Author: abock
Date: Sat Apr 26 03:54:54 2008
New Revision: 3830
URL: http://svn.gnome.org/viewvc/banshee?rev=3830&view=rev

Log:
2008-04-25  Aaron Bockover  <abock gnome org>

    * src/Core/Banshee.Services/Banshee.ServiceStack/IExtensionService.cs:
    * src/Backends/Banshee.GStreamer/Banshee.GStreamer/Service.cs: Require
    all extension services to implement IDisposable

    * src/Core/Banshee.Services/Banshee.ServiceStack/ServiceManager.cs:
    Listen to the addin manager for when service extensions are enabled or
    disabled and enable/disable accordingly; this allows all service extensions
    to now be enabled or disabled at runtime

    * src/Core/Banshee.ThickClient/Banshee.Gui/BansheeActionGroup.cs:
    Added an override for removing an action by name

    * src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdService.cs:
    Moved the UI actions from the source to the service since all of the
    UI here is global; fixes issue where there were UI conflicts with multiple
    CDs and also helps with the runtime enable/disable of the service

    * src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdSource.cs:
    Reflect said changes above

    * src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/NotificationAreaService.cs:
    * src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/X11NotificationAreaBox.cs:
    Many fixes for runtime enable/disable



Modified:
   trunk/banshee/ChangeLog
   trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer/Service.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.ServiceStack/IExtensionService.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.ServiceStack/ServiceManager.cs
   trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/BansheeActionGroup.cs
   trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdService.cs
   trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdSource.cs
   trunk/banshee/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/NotificationAreaService.cs
   trunk/banshee/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/X11NotificationAreaBox.cs

Modified: trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer/Service.cs
==============================================================================
--- trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer/Service.cs	(original)
+++ trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer/Service.cs	Sat Apr 26 03:54:54 2008
@@ -72,6 +72,10 @@
             }
         }
         
+        void IDisposable.Dispose ()
+        {
+        }
+        
         private void NativeLogHandler (LogEntryType type, IntPtr componentPtr, IntPtr messagePtr)
         {
             string component = componentPtr == IntPtr.Zero ? null : GLib.Marshaller.Utf8PtrToString (componentPtr);

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.ServiceStack/IExtensionService.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.ServiceStack/IExtensionService.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.ServiceStack/IExtensionService.cs	Sat Apr 26 03:54:54 2008
@@ -30,7 +30,7 @@
 
 namespace Banshee.ServiceStack
 {
-    public interface IExtensionService : IService
+    public interface IExtensionService : IService, IDisposable
     {
         void Initialize ();
     }

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.ServiceStack/ServiceManager.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.ServiceStack/ServiceManager.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.ServiceStack/ServiceManager.cs	Sat Apr 26 03:54:54 2008
@@ -47,6 +47,7 @@
     public static class ServiceManager
     {
         private static Dictionary<string, IService> services = new Dictionary<string, IService> ();
+        private static Dictionary<string, IExtensionService> extension_services = new Dictionary<string, IExtensionService> ();
         private static Stack<IService> dispose_services = new Stack<IService> ();
         private static List<Type> service_types = new List<Type> ();
         private static ExtensionNodeList extension_nodes;
@@ -129,30 +130,11 @@
                 }
                 
                 foreach (TypeExtensionNode node in extension_nodes) {
-                    IExtensionService service = null;
-                    
-                    try {
-                        uint timer_id = Log.DebugTimerStart ();
-                        
-                        service = (IExtensionService)node.CreateInstance (typeof (IExtensionService));
-                        service.Initialize ();
-                        RegisterService (service);
-                    
-                        Log.DebugTimerPrint (timer_id, String.Format (
-                            "Extension service started ({0}, {{0}})", service.ServiceName));
-                    
-                        OnServiceStarted (service);
-                    
-                        if (service is IDisposable) {
-                            dispose_services.Push (service);
-                        }
-                    } catch (Exception e) {
-                        Log.Exception (e.InnerException ?? e);
-                        Log.Warning (String.Format ("Extension `{0}' not started: {1}", 
-                            service == null ? node.Path : service.GetType ().FullName, e.Message));
-                    }
+                    StartExtension (node);
                 }
                 
+                AddinManager.AddExtensionNodeHandler ("/Banshee/ServiceManager/Service", OnExtensionChanged);
+                
                 is_initialized = true;
                 
                 Log.InformationTimerPrint (cumulative_timer_id, "All services are started {0}");
@@ -161,6 +143,66 @@
             }
         }
         
+        private static void StartExtension (TypeExtensionNode node)
+        {
+            if (extension_services.ContainsKey (node.Path)) {
+                return;
+            }
+        
+            IExtensionService service = null;
+                    
+            try {
+                uint timer_id = Log.DebugTimerStart ();
+                
+                service = (IExtensionService)node.CreateInstance (typeof (IExtensionService));
+                service.Initialize ();
+                RegisterService (service);
+            
+                Log.DebugTimerPrint (timer_id, String.Format (
+                    "Extension service started ({0}, {{0}})", service.ServiceName));
+            
+                OnServiceStarted (service);
+                
+                extension_services.Add (node.Path, service);
+            
+                if (service is IDisposable) {
+                    dispose_services.Push (service);
+                }
+            } catch (Exception e) {
+                Log.Exception (e.InnerException ?? e);
+                Log.Warning (String.Format ("Extension `{0}' not started: {1}", 
+                    service == null ? node.Path : service.GetType ().FullName, e.Message));
+            }
+        }
+        
+        private static void OnExtensionChanged (object o, ExtensionNodeEventArgs args) 
+        {
+            lock (self_mutex) {
+                TypeExtensionNode node = (TypeExtensionNode)args.ExtensionNode;
+                
+                if (args.Change == ExtensionChange.Add) {
+                    StartExtension (node);
+                } else if (args.Change == ExtensionChange.Remove && extension_services.ContainsKey (node.Path)) {
+                    IExtensionService service = extension_services[node.Path];
+                    extension_services.Remove (node.Path);
+                    services.Remove (service.ServiceName);
+                    ((IDisposable)service).Dispose ();
+                    
+                    Log.DebugFormat ("Extension service disposed ({0})", service.ServiceName);
+                    
+                    // Rebuild the dispose stack excluding the extension service
+                    IService [] tmp_services = new IService[dispose_services.Count - 1];
+                    int count = tmp_services.Length;
+                    foreach (IService tmp_service in dispose_services) {
+                        if (tmp_service != service) {
+                            tmp_services[--count] = tmp_service;
+                        }
+                    }
+                    dispose_services = new Stack<IService> (tmp_services);
+                }
+            }
+        }
+        
         public static void Shutdown ()
         {
             lock (self_mutex) {

Modified: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/BansheeActionGroup.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/BansheeActionGroup.cs	(original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/BansheeActionGroup.cs	Sat Apr 26 03:54:54 2008
@@ -63,6 +63,14 @@
                 this[entry.name].IsImportant = true;
             }
         }
+        
+        public void Remove (string actionName)
+        {
+            Gtk.Action action = this[actionName];
+            if (action != null) {
+                Remove (action);
+            }
+        }
 
         public void UpdateActions (bool visible, bool sensitive, params string [] action_names)
         {

Modified: trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdService.cs
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdService.cs	(original)
+++ trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdService.cs	Sat Apr 26 03:54:54 2008
@@ -36,6 +36,7 @@
 using Banshee.Configuration;
 using Banshee.Preferences;
 using Banshee.Hardware;
+using Banshee.Gui;
 
 namespace Banshee.AudioCd
 {
@@ -43,6 +44,7 @@
     {
         private Dictionary<string, AudioCdSource> sources;
         private Section pref_section;
+        private uint global_interface_id;
         
         public AudioCdService ()
         {
@@ -61,6 +63,8 @@
                 
                 ServiceManager.HardwareManager.DeviceAdded += OnHardwareDeviceAdded;
                 ServiceManager.HardwareManager.DeviceRemoved += OnHardwareDeviceRemoved;
+                
+                SetupActions ();
             }
         }
         
@@ -73,11 +77,14 @@
                 ServiceManager.HardwareManager.DeviceRemoved -= OnHardwareDeviceRemoved;
                 
                 foreach (AudioCdSource source in sources.Values) {
+                    source.Dispose ();
                     ServiceManager.SourceManager.RemoveSource (source);
                 }
                 
                 sources.Clear ();
                 sources = null;
+                
+                DisposeActions ();
             }    
         }
         
@@ -134,6 +141,8 @@
             }
         }
         
+#region Preferences        
+        
         private void InstallPreferences ()
         {
             PreferenceService service = ServiceManager.Get<PreferenceService> ();
@@ -190,6 +199,75 @@
             "When importing an audio CD, enable error correction (paranoia mode)"
         );
 
+#endregion
+
+#region UI Actions
+
+        private void SetupActions ()
+        {
+            InterfaceActionService uia_service = ServiceManager.Get<InterfaceActionService> ();
+            if (uia_service == null) {
+                return;
+            }
+            
+            uia_service.GlobalActions.AddImportant (new Gtk.ActionEntry [] {
+                new Gtk.ActionEntry ("RipDiscAction", null,
+                    Catalog.GetString ("Import CD"), null,
+                    Catalog.GetString ("Import this audio CD to the library"),
+                    OnImportDisc)
+            });
+            
+            uia_service.GlobalActions.AddImportant (
+                new Gtk.ActionEntry ("DuplicateDiscAction", null,
+                    Catalog.GetString ("Duplicate CD"), null,
+                    Catalog.GetString ("Duplicate this audio CD"),
+                    OnDuplicateDisc)
+            );
+            
+            global_interface_id = uia_service.UIManager.AddUiFromResource ("GlobalUI.xml");
+        }
+        
+        private void DisposeActions ()
+        {
+            InterfaceActionService uia_service = ServiceManager.Get<InterfaceActionService> ();
+            if (uia_service == null) {
+                return;
+            }
+            
+            uia_service.GlobalActions.Remove ("RipDiscAction");
+            uia_service.GlobalActions.Remove ("DuplicateDiscAction");
+            uia_service.UIManager.RemoveUi (global_interface_id);
+        }
+        
+        private void OnImportDisc (object o, EventArgs args)
+        {
+            ImportOrDuplicateDisc (true);
+        }
+        
+        private void OnDuplicateDisc (object o, EventArgs args)
+        {
+            ImportOrDuplicateDisc (false);
+        }
+        
+        private void ImportOrDuplicateDisc (bool import)
+        {
+            InterfaceActionService uia_service = ServiceManager.Get<InterfaceActionService> ();
+            if (uia_service == null) {
+                return;
+            }
+            
+            AudioCdSource source = uia_service.SourceActions.ActionSource as AudioCdSource;
+            if (source != null) {
+                if (import) {
+                    source.ImportDisc ();
+                } else {
+                    source.DuplicateDisc ();
+                }
+            }
+        }
+
+#endregion
+
         string IService.ServiceName {
             get { return "AudioCdService"; }
         }

Modified: trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdSource.cs
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdSource.cs	(original)
+++ trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdSource.cs	Sat Apr 26 03:54:54 2008
@@ -142,7 +142,7 @@
             }
         }
 
-        private void OnImportDisc (object o, EventArgs args)
+        internal void ImportDisc ()
         {
             AudioCdRipper ripper = null;
             
@@ -161,7 +161,7 @@
             }
         }
 
-        private void OnDuplicateDisc (object o, EventArgs args)
+        internal void DuplicateDisc ()
         {
             Hyena.Log.Information ("This feature is not implemented yet.", true);
         }
@@ -326,24 +326,6 @@
             Properties.SetStringList ("Icon.Name", "media-cdrom", "gnome-dev-cdrom-audio", "source-cd-audio");
             Properties.SetString ("UnmapSourceActionLabel", Catalog.GetString ("Eject Disc"));
             Properties.SetString ("UnmapSourceActionIconName", "media-eject");
-            
-            InterfaceActionService uia_service = ServiceManager.Get<InterfaceActionService> ();
-            uia_service.GlobalActions.AddImportant (new ActionEntry [] {
-                new ActionEntry ("RipDiscAction", null,
-                    Catalog.GetString ("Import CD"), null,
-                    Catalog.GetString ("Import this audio CD to the library"),
-                    OnImportDisc)
-            });
-            
-            uia_service.GlobalActions.AddImportant (
-                new ActionEntry ("DuplicateDiscAction", null,
-                    Catalog.GetString ("Duplicate CD"), null,
-                    Catalog.GetString ("Duplicate this audio CD"),
-                    OnDuplicateDisc)
-            );
-            
-            uia_service.UIManager.AddUiFromResource ("GlobalUI.xml");
-            
             Properties.SetString ("ActiveSourceUIResource", "ActiveSourceUI.xml");
             Properties.SetString ("GtkActionPath", "/AudioCdContextMenu");
             

Modified: trunk/banshee/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/NotificationAreaService.cs
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/NotificationAreaService.cs	(original)
+++ trunk/banshee/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/NotificationAreaService.cs	Sat Apr 26 03:54:54 2008
@@ -46,7 +46,7 @@
 
 namespace Banshee.NotificationArea 
 {
-    public class NotificationAreaService : IExtensionService, IDisposable
+    public class NotificationAreaService : IExtensionService
     {
         private INotificationAreaBox notif_area;
         private GtkElementsService elements_service;
@@ -181,9 +181,15 @@
             
             elements_service.PrimaryWindowClose = null;
             
+            Gtk.Action close_action = interface_action_service.GlobalActions["CloseAction"];
+            if (close_action != null) {
+                interface_action_service.GlobalActions.Remove (close_action);
+            }
+            
+            interface_action_service.RemoveActionGroup ("NotificationArea");
             interface_action_service.UIManager.RemoveUi (ui_manager_id);
-            interface_action_service.UIManager.RemoveActionGroup (actions);
             
+            actions = null;
             elements_service = null;
             interface_action_service = null;
             
@@ -220,6 +226,15 @@
             return true;
         }
         
+        private void DisposeNotificationArea ()
+        {
+            if (notif_area != null) {
+                notif_area.Disconnected -= OnNotificationAreaDisconnected;
+                notif_area.Activated -= OnNotificationAreaActivated;
+                notif_area.PopupMenuEvent -= OnNotificationAreaPopupMenuEvent;
+            }
+        }
+        
         private void RegisterCloseHandler ()
         {
             if (elements_service.PrimaryWindowClose == null) {
@@ -243,12 +258,7 @@
         private void OnNotificationAreaDisconnected (object o, EventArgs args)
         {
             // Ensure we don't keep the destroyed reference around
-            if (notif_area != null) {
-                notif_area.Disconnected -= OnNotificationAreaDisconnected;
-                notif_area.Activated -= OnNotificationAreaActivated;
-                notif_area.PopupMenuEvent -= OnNotificationAreaPopupMenuEvent;
-            }
-            
+            DisposeNotificationArea ();
             BuildNotificationArea ();
         }
         

Modified: trunk/banshee/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/X11NotificationAreaBox.cs
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/X11NotificationAreaBox.cs	(original)
+++ trunk/banshee/src/Extensions/Banshee.NotificationArea/Banshee.NotificationArea/X11NotificationAreaBox.cs	Sat Apr 26 03:54:54 2008
@@ -68,6 +68,18 @@
             ShowAll ();
         }
         
+        public override void Dispose ()
+        {
+            HidePopup ();
+        
+            event_box.ButtonPressEvent -= OnButtonPressEvent;
+            event_box.EnterNotifyEvent -= OnEnterNotifyEvent;
+            event_box.LeaveNotifyEvent -= OnLeaveNotifyEvent;
+            event_box.ScrollEvent -= OnMouseScroll;
+        
+            Destroy ();
+        }
+        
         public void PositionMenu (Menu menu, out int x, out int y, out bool push_in) 
         {
             PositionWidget (menu, out x, out y, 0);
@@ -200,7 +212,7 @@
             }
         }
         
-        private void OnEnterNotifyEvent(object o, EnterNotifyEventArgs args) 
+        private void OnEnterNotifyEvent (object o, EnterNotifyEventArgs args) 
         {
             cursor_over_trayicon = true;
             if (can_show_popup) {
@@ -215,7 +227,7 @@
             }
         }
         
-        private void OnLeaveNotifyEvent(object o, LeaveNotifyEventArgs args) 
+        private void OnLeaveNotifyEvent (object o, LeaveNotifyEventArgs args) 
         {
             cursor_over_trayicon = false;
             HidePopup ();



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