/// <summary> /// Activated when the user clicks the "Configure" button. Opens a new dialog containing the configuration /// widget of the selected plugin /// </summary> /// <param name="sender"> /// A <see cref="System.Object"/> -- not used /// </param> /// <param name="e"> /// A <see cref="EventArgs"/> -- not used /// </param> void OnConfigureButtonClicked(object sender, EventArgs e) { LiveRadioPluginListModel model = plugin_view.Model as LiveRadioPluginListModel; ILiveRadioPlugin plugin = model[plugin_view.Model.Selection.FocusedIndex]; Dialog dialog = new Dialog(); dialog.Title = String.Format("LiveRadio Plugin {0} configuration", plugin.Name); dialog.IconName = "gtk-preferences"; dialog.Resizable = false; dialog.BorderWidth = 6; dialog.ContentArea.Spacing = 12; dialog.ContentArea.PackStart(plugin.ConfigurationWidget, false, false, 0); Button save_button = new Button(Stock.Save); Button cancel_button = new Button(Stock.Cancel); dialog.AddActionWidget(cancel_button, 0); dialog.AddActionWidget(save_button, 0); cancel_button.Clicked += delegate { dialog.Destroy(); }; save_button.Clicked += delegate { plugin.SaveConfiguration(); dialog.Destroy(); }; dialog.ShowAll(); }
/// <summary> /// Event Handler for the event that a plugin has returned an error /// </summary> /// <param name="plugin"> /// A <see cref="ILiveRadioPlugin"/> -- the plugin that has encountered the error /// </param> /// <param name="error"> /// A <see cref="LiveRadioPluginError"/> containing information about the error /// </param> void OnPluginErrorReturned(ILiveRadioPlugin plugin, LiveRadioPluginError error) { AddStatistic(LiveRadioStatisticType.Error, plugin.Name, AddinManager.CurrentLocalizer.GetString(error.Message), AddinManager.CurrentLocalizer.GetString(error.LongMessage), 1); }
/// <summary> /// Event Handler for the event that a plugin has retrieved a list of genres /// </summary> /// <param name="sender"> /// A <see cref="System.Object"/> -- the plugin that has retrieved the genre list /// </param> /// <param name="genres"> /// A <see cref="List<Genre>"/> -- the list of genres that has been retrieved /// </param> void OnPluginGenreListLoaded(object sender, List <Genre> genres) { ILiveRadioPlugin plugin = sender as ILiveRadioPlugin; AddStatistic(LiveRadioStatisticType.Message, plugin.Name, AddinManager.CurrentLocalizer.GetString("Genre List Retrieved"), AddinManager.CurrentLocalizer.GetString("The plugin has returned the list of genres"), genres.Count); }
/// <summary> /// Register an external plugin with the main source, so it can be added as a child via AddPlugin method. /// Assembly plugins are autodetected/autoregistered /// </summary> /// <param name="plugin"> /// A <see cref="ILiveRadioPlugin"/> -- an external plugin /// </param> public void RegisterPlugin(ILiveRadioPlugin plugin) { if (plugins.Contains(plugin)) { Log.DebugFormat("[LiveRadioSource]<RegisterPlugin> plugin {0} already registered", plugin.Name); } else { plugins.Add(plugin); source_contents.ConnectPluginEvents(plugin); } }
/// <summary> /// Event Handler for the event that a plugin has retreived a result list for a query /// </summary> /// <param name="sender"> /// A <see cref="System.Object"/> -- the plugin that has retrieved the results /// </param> /// <param name="request"> /// A <see cref="System.String"/> -- the original request string, either freetext or the genre name /// </param> /// <param name="request_type"> /// A <see cref="LiveRadioRequestType"/> -- the original request type /// </param> /// <param name="result"> /// A <see cref="List<DatabaseTrackInfo>"/> -- the results list /// </param> void OnPluginRequestResultRetrieved(object sender, string request, LiveRadioRequestType request_type, List <DatabaseTrackInfo> result) { if (result != null) { ILiveRadioPlugin plugin = sender as ILiveRadioPlugin; AddStatistic(LiveRadioStatisticType.Message, plugin.Name, AddinManager.CurrentLocalizer.GetString("Requested Results Returned"), AddinManager.CurrentLocalizer.GetString("The plugin has returned a list of results for a genre or freetext query"), result.Count); } }
/// <summary> /// Adds the currently selected item(s) of the active source to the internet radio source /// as new stations. Any session data (as in live365 with activated user login) will previously /// be cleared. /// </summary> /// <param name="o"> /// A <see cref="System.Object"/> -- not used /// </param> /// <param name="e"> /// A <see cref="EventArgs"/> -- not used /// </param> protected void OnAddToInternetRadio(object o, EventArgs e) { PrimarySource internet_radio_source = GetInternetRadioSource(); PrimarySource current_source = ServiceManager.SourceManager.ActiveSource as PrimarySource; if (current_source == null) { Log.Debug("[LiveRadioSource]<OnAddToInternetRadio> ActiveSource not Primary"); return; } if (internet_radio_source == null) { Log.Debug("[LiveRadioSource]<OnAddToInternetRadio> Internet Radio not found"); return; } ITrackModelSource active_track_model_source = (ITrackModelSource)current_source; if (active_track_model_source.TrackModel.SelectedItems == null || active_track_model_source.TrackModel.SelectedItems.Count <= 0) { return; } ILiveRadioPlugin current_plugin = null; foreach (ILiveRadioPlugin plugin in plugins) { if (plugin.PluginSource != null && plugin.PluginSource.Equals(current_source)) { current_plugin = plugin; } } foreach (TrackInfo track in active_track_model_source.TrackModel.SelectedItems) { DatabaseTrackInfo station_track = new DatabaseTrackInfo(track as DatabaseTrackInfo); if (station_track != null) { station_track.PrimarySource = internet_radio_source; if (current_plugin != null) { station_track.Uri = current_plugin.CleanUpUrl(station_track.Uri); } station_track.Save(); } } }
/// <summary> /// Goes through all the assembly classes to find any non-abstract class implementing ILiveRadioPlugin and adds /// an object instance of the class to the plugin list /// </summary> /// <returns> /// A <see cref="List<ILiveRadioPlugin>"/> -- a list of one instance for each plugin class /// </returns> public List <ILiveRadioPlugin> LoadPlugins() { List <ILiveRadioPlugin> plugins = new List <ILiveRadioPlugin> (); foreach (Type type in assembly.GetTypes()) { if (type.GetInterface("ILiveRadioPlugin") != null && !type.IsAbstract) { ILiveRadioPlugin plugin = (ILiveRadioPlugin)Activator.CreateInstance(type); //shoutcast not working at the moment, don't activate if (plugin.Active) { plugins.Add(plugin); } } } return(plugins); }
/// <summary> /// Removes a plugin source /// </summary> /// <param name="plugin"> /// A <see cref="ILiveRadioPlugin"/> the plugin which to remove the source for /// </param> public void RemovePlugin(ILiveRadioPlugin plugin) { if (plugins.Contains(plugin)) { LiveRadioPluginSource plugin_source = plugin.PluginSource; plugin.Disable(); this.RemoveChildSource(plugin_source); plugin_source.Dispose(); this.UpdateCounts(); if (enabled_plugins.Contains(plugin.Name)) { enabled_plugins.Remove(plugin.Name); SetEnabledPluginsEntry(); } } else { Log.DebugFormat("[LiveRadioSource]<RemovePlugin> plugin {0} not registered, cannot remove", plugin.Name); } }
/// <summary> /// Add and initialize a plugin -- if it is not an assembly plugin, it must be registered first, assembly /// plugins are auto registered /// </summary> /// <param name="plugin"> /// A <see cref="ILiveRadioPlugin"/> -- the plugin to initialize /// </param> public void AddPlugin(ILiveRadioPlugin plugin) { if (plugins.Contains(plugin)) { LiveRadioPluginSource plugin_source = new LiveRadioPluginSource(plugin); this.AddChildSource(plugin_source); this.MergeSourceInput(plugin_source, SourceMergeType.Source); plugin.Initialize(); plugin_source.UpdateCounts(); if (!enabled_plugins.Contains(plugin.Name)) { enabled_plugins.Add(plugin.Name); SetEnabledPluginsEntry(); } } else { Log.DebugFormat("[LiveRadioSource]<AddPlugin> plugin {0} not registered, cannot add", plugin.Name); } }
/// <summary> /// Activated when the user clicks the "Disable" button. Disables the selected, /// previously active plugin /// </summary> /// <param name="sender"> /// A <see cref="System.Object"/> -- not used /// </param> /// <param name="e"> /// A <see cref="EventArgs"/> -- not used /// </param> void OnDisableButtonClicked(object sender, EventArgs e) { LiveRadioPluginListModel model = plugin_view.Model as LiveRadioPluginListModel; ILiveRadioPlugin plugin = model[plugin_view.Model.Selection.FocusedIndex]; if (!plugin.Enabled) { return; } LiveRadioSource source = plugin.PluginSource.Parent as LiveRadioSource; if (source == null) { return; } source.RemovePlugin(plugin); enable_button.Sensitive = true; disable_button.Sensitive = false; plugin_view.GrabFocus(); }
/// <summary> /// Disconnects class functions from plugin events /// </summary> /// <param name="plugin"> /// A <see cref="ILiveRadioPlugin"/> the events of which will be disconnected /// </param> public void DisconnectPluginEvents(ILiveRadioPlugin plugin) { plugin.ErrorReturned -= OnPluginErrorReturned; plugin.GenreListLoaded -= OnPluginGenreListLoaded; plugin.RequestResultRetrieved -= OnPluginRequestResultRetrieved; }
/// <summary> /// Register an external plugin with the main source, so it can be added as a child via AddPlugin method. /// Assembly plugins are autodetected/autoregistered /// </summary> /// <param name="plugin"> /// A <see cref="ILiveRadioPlugin"/> -- an external plugin /// </param> public void RegisterPlugin(ILiveRadioPlugin plugin) { if (plugins.Contains (plugin)) { Log.DebugFormat ("[LiveRadioSource]<RegisterPlugin> plugin {0} already registered", plugin.Name); } else { plugins.Add (plugin); source_contents.ConnectPluginEvents (plugin); } }
/// <summary> /// Constructor -- creates a new temporary LiveRadio Plugin source and sets itself as the plugin's source /// Any tracks that have remained in the source from a previous (interrupted) session are purged /// </summary> /// <param name="plugin"> /// A <see cref="ILiveRadioPlugin"/> -- the plugin the source is created for /// </param> public LiveRadioPluginSource(ILiveRadioPlugin plugin) : base(AddinManager.CurrentLocalizer.GetString("LiveRadioPlugin") + plugin.Name, plugin.Name, "live-radio-plugin-" + plugin.Name.ToLower(), sort_order) { TypeUniqueId = "live-radio-" + plugin.Name; IsLocal = false; Gdk.Pixbuf icon = new Gdk.Pixbuf(System.Reflection.Assembly.GetExecutingAssembly() .GetManifestResourceStream("LiveRadioIcon.svg")); SetIcon(icon); plugin.SetLiveRadioPluginSource(this); this.plugin = plugin; AfterInitialized(); Properties.Set <bool> ("Nereid.SourceContentsPropagate", true); Properties.SetString("TrackView.ColumnControllerXml", String.Format(@" <column-controller> <!--<column modify-default=""IndicatorColumn""> <renderer type=""Banshee.Podcasting.Gui.ColumnCellPodcastStatusIndicator"" /> </column>--> <add-default column=""IndicatorColumn"" /> <add-default column=""GenreColumn"" /> <column modify-default=""GenreColumn""> <visible>false</visible> </column> <add-default column=""TitleColumn"" /> <column modify-default=""TitleColumn""> <title>{0}</title> <long-title>{0}</long-title> </column> <add-default column=""ArtistColumn"" /> <column modify-default=""ArtistColumn""> <title>{1}</title> <long-title>{1}</long-title> </column> <add-default column=""CommentColumn"" /> <column modify-default=""CommentColumn""> <title>{2}</title> <long-title>{2}</long-title> </column> <add-default column=""RatingColumn"" /> <add-default column=""PlayCountColumn"" /> <add-default column=""LastPlayedColumn"" /> <add-default column=""LastSkippedColumn"" /> <add-default column=""DateAddedColumn"" /> <add-default column=""UriColumn"" /> <sort-column direction=""asc"">genre</sort-column> </column-controller>", AddinManager.CurrentLocalizer.GetString("Station"), AddinManager.CurrentLocalizer.GetString("Creator"), AddinManager.CurrentLocalizer.GetString("Description") )); ServiceManager.PlayerEngine.TrackIntercept += OnPlayerEngineTrackIntercept; TrackEqualHandler = delegate(DatabaseTrackInfo a, TrackInfo b) { RadioTrackInfo radio_track = b as RadioTrackInfo; return(radio_track != null && DatabaseTrackInfo.TrackEqual(radio_track.ParentTrack as DatabaseTrackInfo, a)); }; source_contents = new LiveRadioPluginSourceContents(plugin); source_contents.SetSource(this); Properties.Set <ISourceContents> ("Nereid.SourceContents", source_contents); this.PurgeTracks(); }
/// <summary> /// Constructor -- creates a new temporary LiveRadio Plugin source and sets itself as the plugin's source /// Any tracks that have remained in the source from a previous (interrupted) session are purged /// </summary> /// <param name="plugin"> /// A <see cref="ILiveRadioPlugin"/> -- the plugin the source is created for /// </param> public LiveRadioPluginSource(ILiveRadioPlugin plugin) : base(AddinManager.CurrentLocalizer.GetString ("LiveRadioPlugin") + plugin.Name, plugin.Name, "live-radio-plugin-" + plugin.Name.ToLower (), sort_order) { TypeUniqueId = "live-radio-" + plugin.Name; IsLocal = false; Gdk.Pixbuf icon = new Gdk.Pixbuf (System.Reflection.Assembly.GetExecutingAssembly () .GetManifestResourceStream ("LiveRadioIcon.svg")); SetIcon (icon); plugin.SetLiveRadioPluginSource (this); this.plugin = plugin; AfterInitialized (); Properties.Set<bool> ("Nereid.SourceContentsPropagate", true); Properties.SetString ("TrackView.ColumnControllerXml", String.Format (@" <column-controller> <!--<column modify-default=""IndicatorColumn""> <renderer type=""Banshee.Podcasting.Gui.ColumnCellPodcastStatusIndicator"" /> </column>--> <add-default column=""IndicatorColumn"" /> <add-default column=""GenreColumn"" /> <column modify-default=""GenreColumn""> <visible>false</visible> </column> <add-default column=""TitleColumn"" /> <column modify-default=""TitleColumn""> <title>{0}</title> <long-title>{0}</long-title> </column> <add-default column=""ArtistColumn"" /> <column modify-default=""ArtistColumn""> <title>{1}</title> <long-title>{1}</long-title> </column> <add-default column=""CommentColumn"" /> <column modify-default=""CommentColumn""> <title>{2}</title> <long-title>{2}</long-title> </column> <add-default column=""RatingColumn"" /> <add-default column=""PlayCountColumn"" /> <add-default column=""LastPlayedColumn"" /> <add-default column=""LastSkippedColumn"" /> <add-default column=""DateAddedColumn"" /> <add-default column=""UriColumn"" /> <sort-column direction=""asc"">genre</sort-column> </column-controller>", AddinManager.CurrentLocalizer.GetString ("Station"), AddinManager.CurrentLocalizer.GetString ("Creator"), AddinManager.CurrentLocalizer.GetString ("Description") )); ServiceManager.PlayerEngine.TrackIntercept += OnPlayerEngineTrackIntercept; TrackEqualHandler = delegate(DatabaseTrackInfo a, TrackInfo b) { RadioTrackInfo radio_track = b as RadioTrackInfo; return radio_track != null && DatabaseTrackInfo.TrackEqual (radio_track.ParentTrack as DatabaseTrackInfo, a); }; source_contents = new LiveRadioPluginSourceContents (plugin); source_contents.SetSource (this); Properties.Set<ISourceContents> ("Nereid.SourceContents", source_contents); this.PurgeTracks (); }
/// <summary> /// Event Handler for the event that a plugin has returned an error /// </summary> /// <param name="plugin"> /// A <see cref="ILiveRadioPlugin"/> -- the plugin that has encountered the error /// </param> /// <param name="error"> /// A <see cref="LiveRadioPluginError"/> containing information about the error /// </param> void OnPluginErrorReturned(ILiveRadioPlugin plugin, LiveRadioPluginError error) { AddStatistic (LiveRadioStatisticType.Error, plugin.Name, AddinManager.CurrentLocalizer.GetString (error.Message), AddinManager.CurrentLocalizer.GetString (error.LongMessage), 1); }
/// <summary> /// Add and initialize a plugin -- if it is not an assembly plugin, it must be registered first, assembly /// plugins are auto registered /// </summary> /// <param name="plugin"> /// A <see cref="ILiveRadioPlugin"/> -- the plugin to initialize /// </param> public void AddPlugin(ILiveRadioPlugin plugin) { if (plugins.Contains (plugin)) { LiveRadioPluginSource plugin_source = new LiveRadioPluginSource (plugin); this.AddChildSource (plugin_source); this.MergeSourceInput (plugin_source, SourceMergeType.Source); plugin.Initialize (); plugin_source.UpdateCounts (); if (!enabled_plugins.Contains (plugin.Name)) { enabled_plugins.Add(plugin.Name); SetEnabledPluginsEntry (); } } else { Log.DebugFormat ("[LiveRadioSource]<AddPlugin> plugin {0} not registered, cannot add", plugin.Name); } }
/// <summary> /// Connects class functions to plugin events /// </summary> /// <param name="plugin"> /// A <see cref="ILiveRadioPlugin"/> the events of which will be connected /// </param> public void ConnectPluginEvents(ILiveRadioPlugin plugin) { plugin.ErrorReturned += OnPluginErrorReturned; plugin.GenreListLoaded += OnPluginGenreListLoaded; plugin.RequestResultRetrieved += OnPluginRequestResultRetrieved; }
/// <summary> /// Removes a plugin source /// </summary> /// <param name="plugin"> /// A <see cref="ILiveRadioPlugin"/> the plugin which to remove the source for /// </param> public void RemovePlugin(ILiveRadioPlugin plugin) { if (plugins.Contains (plugin)) { LiveRadioPluginSource plugin_source = plugin.PluginSource; plugin.Disable (); this.RemoveChildSource(plugin_source); plugin_source.Dispose (); this.UpdateCounts (); if (enabled_plugins.Contains (plugin.Name)) { enabled_plugins.Remove(plugin.Name); SetEnabledPluginsEntry (); } } else { Log.DebugFormat ("[LiveRadioSource]<RemovePlugin> plugin {0} not registered, cannot remove", plugin.Name); } }
/// <summary> /// Constructor -- creates the source contents for a plugin and sets up the event handlers for the view /// and the plugin refresh events. /// </summary> /// <param name="plugin"> /// A <see cref="ILiveRadioPlugin"/> -- the plugin to set up the source contents for. /// </param> public LiveRadioPluginSourceContents(ILiveRadioPlugin plugin) { base.Name = plugin.Name; this.plugin = plugin; InitializeViews(); string position = ForcePosition == null?BrowserPosition.Get() : ForcePosition; if (position == "top") { LayoutTop(); } else { LayoutLeft(); } plugin.GenreListLoaded += OnPluginGenreListLoaded; plugin.RequestResultRetrieved += OnPluginRequestResultRetrieved; if (ForcePosition != null) { return; } if (ServiceManager.Contains("InterfaceActionService")) { action_service = ServiceManager.Get <InterfaceActionService> (); if (action_service.FindActionGroup("BrowserView") == null) { browser_view_actions = new ActionGroup("BrowserView"); browser_view_actions.Add(new RadioActionEntry [] { new RadioActionEntry("BrowserLeftAction", null, AddinManager.CurrentLocalizer.GetString("Browser on Left"), null, AddinManager.CurrentLocalizer.GetString("Show the artist/album browser to the left of the track list"), 0), new RadioActionEntry("BrowserTopAction", null, AddinManager.CurrentLocalizer.GetString("Browser on Top"), null, AddinManager.CurrentLocalizer.GetString("Show the artist/album browser above the track list"), 1), }, position == "top" ? 1 : 0, null); browser_view_actions.Add(new ToggleActionEntry [] { new ToggleActionEntry("BrowserVisibleAction", null, AddinManager.CurrentLocalizer.GetString("Show Browser"), "<control>B", AddinManager.CurrentLocalizer.GetString("Show or hide the artist/album browser"), null, BrowserVisible.Get()) }); action_service.AddActionGroup(browser_view_actions); action_service.UIManager.AddUiFromString(menu_xml); } (action_service.FindAction("BrowserView.BrowserLeftAction") as RadioAction).Changed += OnViewModeChanged; (action_service.FindAction("BrowserView.BrowserTopAction") as RadioAction).Changed += OnViewModeChanged; action_service.FindAction("BrowserView.BrowserVisibleAction").Activated += OnToggleBrowser; } ServiceManager.SourceManager.ActiveSourceChanged += delegate { ThreadAssist.ProxyToMain(delegate { browser_container.Visible = ActiveSourceCanHasBrowser ? BrowserVisible.Get() : false; }); }; NoShowAll = true; }