%PDF- %PDF-
Direktori : /lib/rhythmbox/plugins/alternative-toolbar/ |
Current File : //lib/rhythmbox/plugins/alternative-toolbar/alttoolbar_controller.py |
# -*- Mode: python; coding: utf-8; tab-width: 4; indent-tabs-mode: nil; -*- # # Copyright (C) 2015 - 2020 David Mohammed <fossfreedom@ubuntu.com> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. from alttoolbar_preferences import CoverLocale from gi.repository import GObject from gi.repository import Gio from gi.repository import Gtk class AltControllerCategory(object): OTHER = 0 LOCAL = 1 ONLINE = 2 PLAYLIST = 3 class AltControllerBase(GObject.Object): """ base controller """ def __init__(self, header): """ Initialises the object. """ self.header = header self.find = self.header.find # convenience function self._pixbuf = None super(AltControllerBase, self).__init__() def get_category(self): """ return the category type for the source """ return AltControllerCategory.OTHER def toolbar_visibility(self): """ return the toolbar visibility by default None which means user controlled """ return None def get_gicon(self, source): """ return the source icon :param source: :return: """ if source.props.icon: return source.props.icon return None def valid_source(self, source): """ returns bool if the given source is applicable to the controller """ return False def update_controls(self, source): """ update the button controls on the header """ pass def remove_controls(self, container): """ remove any controls that are contained in a container """ for child in container.get_children(): container.remove(child) def hide_controls(self, source): """ hide controls for a given controller """ pass def get_search_entry(self, toolbar_container): """ find the GtkEntry field corresponding to the search entry returns 1. the GtkWidget containing the GtkEntry 2. the GtkEntry returns None if nothing found """ return None def get_toolbar(self, source): """ return GtkWidget corresponding to the toolbar within the source None if no toolbar """ return None def moveto_searchbar(self, toolbar, widget, searchbar): """ move from toolbar the widget and add to the searchbar """ pass def set_library_labels(self): """ set the centre library song-category button label """ self.header.set_library_labels() class AltGenericController(AltControllerBase): """ generic controller for the headerbar (only) """ __gtype_name = 'AltGenericController' def __init__(self, header): """ Initialises the object. """ super(AltGenericController, self).__init__(header) self.centre_controls = {} self.end_controls = {} def get_category(self): return AltControllerCategory.LOCAL def hide_controls(self, source): val, view_button = self.header.has_button_with_label(source, _('View All')) if val: view_button.set_visible(False) def get_toolbar(self, source): toolbar = self.find(source, 'RBSourceToolbar', 'by_name') print(toolbar) print(source) return toolbar def get_search_entry(self, container): if container is None: print("no container to search") return None, None search = self.find(container, 'RBSearchEntry', 'by_name') if not search: print("no RBSearchEntry found") return None, None entry = self.find(search, 'GtkEntry', 'by_name') print(entry) return search, entry def moveto_searchbar(self, toolbar, search, searchbar): toolbar.remove(search) toolbar.set_visible(False) searchbar.add(search) def update_controls(self, source): """ update the button controls on the header """ val, browser_button = self.header.is_browser_view(source) if not val: # if not a browser_view based source then default just to the title print("no browser view") self.header.set_library_box_sensitive(False) else: print("browser view found") browser_button.set_visible(False) self.header.set_library_box_sensitive(True) self.header.current_search_button = None toolbar = self.get_toolbar(source) if not toolbar: # there is no source-bar so the header is empty print("no toolbar so nothing left to do - cleanup endbox and exit") self.remove_controls(self.header.end_box) return self.hide_controls(toolbar) if source not in self.end_controls: # this is the first time for the source so extract the # RBSearchEntry print("first time around") controls = {} self.remove_controls(self.header.end_box) print(toolbar) # should be the RBSourceToolbar search, entry = self.get_search_entry(toolbar) if not search: return if self.header.searchbar: self.header.searchbar.set_visible(False) # define a searchbar widget self.header.searchbar = Gtk.SearchBar.new() # we need to add this to the top of the source window # to-do this - find the first child and physically move this into # the second position in a box - the first position being the # searchbar children = source.get_children() print(children) # We assume the first container in a source is a GtkNotebook first = children[0] box = Gtk.Box() box.set_orientation(Gtk.Orientation.VERTICAL) box.pack_start(self.header.searchbar, False, True, 0) box.show_all() # so remove the notebook from the source Gtk.Container.remove(source, first) box.pack_start(first, True, True, 1) # add the notebook to a box source.add(box) # then add the box back to the source - # i.e. we added another parent self.header.register_moved_control(child=first, old_parent=source, new_parent=box) self.moveto_searchbar(toolbar, search, self.header.searchbar) entry.set_size_request(300, -1) self.header.searchbar.connect_entry(entry) # self.header.searchbar.show_all() self.header.searchbar.set_visible(False) search_button = Gtk.ToggleButton.new() sym = "preferences-system-search-symbolic" image = \ Gtk.Image.new_from_icon_name(sym, Gtk.IconSize.SMALL_TOOLBAR) search_button.add(image) self.header.end_box.add(search_button) self.header.end_box.reorder_child(search_button, 0) search_button.show_all() search_button.connect('toggled', self.header.search_button_toggled) controls['searchbar'] = self.header.searchbar controls['search_button'] = search_button self.header.current_search_button = search_button self.end_controls[source] = controls print(controls) else: print("second time around") print(self.end_controls[source]) search = self.end_controls[source]['searchbar'] if self.header.searchbar: self.header.searchbar.set_visible(False) self.header.searchbar = search # self.header.searchbar.set_visible(True) self.remove_controls(self.header.end_box) search_button = self.end_controls[source]['search_button'] self.header.current_search_button = search_button self.header.searchbar.show_all() self.header.searchbar.set_visible(search_button.get_active()) self.header.end_box.add(search_button) self.header.end_box.reorder_child(search_button, 0) self.header.end_box.show_all() class AltMusicLibraryController(AltGenericController): """ music library controller """ __gtype_name = 'AltMusicLibraryController' def __init__(self, header): """ Initialises the object. """ super(AltMusicLibraryController, self).__init__(header) def valid_source(self, source): """ override """ return "LibrarySource" in type(source).__name__ class AltSoundCloudController(AltGenericController): """ sound-cloud controller """ __gtype_name = 'AltSoundCloudController' def __init__(self, header): """ Initialises the object. """ super(AltSoundCloudController, self).__init__(header) self._has_toolbar = None def valid_source(self, source): """ override """ return "SoundCloud" in type(source).__name__ def get_category(self): return AltControllerCategory.ONLINE def get_toolbar(self, source): if self._has_toolbar: return self._has_toolbar search_box = self.find(source, 'box1', 'by_id') self._has_toolbar = search_box return search_box def moveto_searchbar(self, toolbar, widget, searchbar): """ override - here we want to actually remove the toolbar from the source so get the parent """ parent_grid = toolbar.get_parent() parent_grid.remove(toolbar) searchbar.add(toolbar) self.header.register_moved_control(child=toolbar, old_parent=parent_grid, new_parent=searchbar) class AltCoverArtBrowserController(AltGenericController): """ CoverArtBrowser controller """ __gtype_name = 'AltCoverArtBrowserController' def __init__(self, header): """ Initialises the object. """ super(AltCoverArtBrowserController, self).__init__(header) self._has_toolbar = None def valid_source(self, source): """ override """ return "CoverArtBrowser" in type(source).__name__ def get_category(self): return AltControllerCategory.LOCAL def get_toolbar(self, source): if not self._has_toolbar: search_box = self.find(source, 'toolbar', 'by_id') self._has_toolbar = search_box return self._has_toolbar def moveto_searchbar(self, toolbar, widget, searchbar): """ override - here we want to actually remove the toolbar from the source so get the parent """ parent_grid = toolbar.get_parent() parent_grid.remove(toolbar) searchbar.add(toolbar) searchbar.show_all() self.header.register_moved_control(child=toolbar, old_parent=parent_grid, new_parent=searchbar) def get_search_entry(self, toolbar): """ override - use the GtkEntry in the coverartbrowser """ entrysearch = self.find(toolbar, 'entry_search_alignment', 'by_id') entry = self.find(entrysearch, 'GtkEntry', 'by_name') return entrysearch, entry class AltCoverArtPlaySourceController(AltGenericController): """ CoverArtPlaySource controller """ __gtype_name = 'AltCoverArtPlaySourceController' def __init__(self, header): """ Initialises the object. """ super(AltCoverArtPlaySourceController, self).__init__(header) self._has_toolbar = None def valid_source(self, source): """ override """ return "CoverArtPlaySource" in type(source).__name__ def get_category(self): return AltControllerCategory.LOCAL def get_toolbar(self, source): if not self._has_toolbar: self._has_toolbar = self.find(source, 'RBButtonBar', 'by_name') print("############", self._has_toolbar) return self._has_toolbar class AltQueueController(AltGenericController): """ RB QueueSource controller """ __gtype_name = 'AltQueueController' def __init__(self, header): """ Initialises the object. """ super(AltQueueController, self).__init__(header) self._gicon = Gio.ThemedIcon(name='audio-x-queue-symbolic') def valid_source(self, source): return "RBPlayQueueSource" in type(source).__name__ def get_gicon(self, source): return self._gicon class AltErrorsController(AltGenericController): """ RB ErrorsSource controller """ __gtype_name = 'AltErrorsController' def __init__(self, header): """ Initialises the object. """ super(AltErrorsController, self).__init__(header) self._gicon = Gio.ThemedIcon(name='dialog-error-symbolic') self._source_types = ["RBImportErrorsSource", "RBMissingFilesSource"] def valid_source(self, source): print(type(source).__name__) for source_type in self._source_types: if source_type in type(source).__name__: return True def get_category(self): return AltControllerCategory.LOCAL def get_gicon(self, source): return self._gicon class AltRadioController(AltGenericController): """ RB RadioSource controller """ __gtype_name = 'AltRadioController' def __init__(self, header): """ Initialises the object. """ super(AltRadioController, self).__init__(header) self._gicon = Gio.ThemedIcon(name='audio-radio-symbolic') def valid_source(self, source): return "RBIRadioSource" in type(source).__name__ def get_gicon(self, source): return self._gicon def get_category(self): return AltControllerCategory.ONLINE def set_library_labels(self): self.header.set_library_labels(song_label=_('Stations')) def toolbar_visibility(self): return True # radio source the source toolbar is always shown class AltLastFMController(AltGenericController): """ RB LastFMSource controller """ __gtype_name = 'AltLastFMController' def __init__(self, header): """ Initialises the object. """ super(AltLastFMController, self).__init__(header) self._libre_gicon = Gio.ThemedIcon(name='librefm-symbolic') self._lastfm_gicon = Gio.ThemedIcon(name='lastfm-symbolic') def valid_source(self, source): return "RBAudioscrobblerProfilePage" in type(source).__name__ def get_gicon(self, source): # locale stuff cl = CoverLocale() cl.switch_locale(cl.Locale.RB) if source.props.name == _("Libre.fm"): return self._libre_gicon else: return self._lastfm_gicon def get_category(self): return AltControllerCategory.ONLINE class AltPlaylistController(AltGenericController): """ playlist controller """ __gtype_name = 'AltPlaylistController' def __init__(self, header): """ Initialises the object. """ super(AltPlaylistController, self).__init__(header) self._static_gicon = \ Gio.ThemedIcon(name='audio-x-playlist-symbolic') self._auto_gicon = \ Gio.ThemedIcon(name='audio-x-playlist-automatic-symbolic') self._toprated_gicon = Gio.ThemedIcon(name='starred-symbolic') self._recentlyadded_gicon = \ Gio.ThemedIcon(name='audio-x-playlist-recently-added-symbolic') self._recentlyplayed_gicon = \ Gio.ThemedIcon(name='audio-x-playlist-recently-played-symbolic') def valid_source(self, source): """ override """ return "PlaylistSource" in type(source).__name__ def get_gicon(self, source): # locale stuff cl = CoverLocale() cl.switch_locale(cl.Locale.RB) print(source.props.name) if source.props.name == _('My Top Rated') \ or source.props.name == 'My Top Rated': return self._toprated_gicon if source.props.name == _('Recently Added') \ or source.props.name == 'Recently Added': return self._recentlyadded_gicon if source.props.name == _('Recently Played') \ or source.props.name == 'Recently Played': return self._recentlyplayed_gicon if "StaticPlaylistSource" in type(source).__name__: return self._static_gicon else: return self._auto_gicon def get_category(self): return AltControllerCategory.PLAYLIST class AltPodcastController(AltGenericController): """ podcast controller """ __gtype_name = 'AltPodcastController' def valid_source(self, source): """ override """ return 'RBPodcastMainSource' in type(source).__name__ def get_category(self): return AltControllerCategory.LOCAL def set_library_labels(self): # locale stuff cl = CoverLocale() cl.switch_locale(cl.Locale.LOCALE_DOMAIN) self.header.set_library_labels(song_label=_('Podcasts')) def toolbar_visibility(self): return True # podcast source the source toolbar is always shown class AltStandardOnlineController(AltGenericController): """ standard controller where we dont need specific customisation """ __gtype_name = 'AltStandardOnlineController' def __init__(self, header): """ Initialises the object. """ super(AltStandardOnlineController, self).__init__(header) self._source_types = ['MagnatuneSource', 'RBGriloSource', 'RadioBrowserSource'] def valid_source(self, source): print(type(source).__name__) for source_type in self._source_types: if source_type in type(source).__name__: return True return False def get_category(self): return AltControllerCategory.ONLINE class AltStandardLocalController(AltGenericController): """ standard controller where we dont need specific customisation """ __gtype_name = 'AltStandardLocalController' def __init__(self, header): """ Initialises the object. """ super(AltStandardLocalController, self).__init__(header) self._source_types = ['RBMtpSource'] def valid_source(self, source): print(type(source).__name__) for source_type in self._source_types: if source_type in type(source).__name__: return True return False def get_category(self): return AltControllerCategory.LOCAL class AltAndroidController(AltGenericController): ''' android controller ''' __gtype_name = 'AltAndroidController' def valid_source(self, source): ''' override ''' return 'RBAndroidSource' in type(source).__name__ def get_category(self): return AltControllerCategory.LOCAL