def __init__(self, parent): """ Init widget @param device as Device @param parent as Gtk.Widget """ Gtk.Bin.__init__(self) MtpSync.__init__(self) self.__parent = parent self.__stop = False self._uri = None builder = Gtk.Builder() builder.add_from_resource('/org/gnome/Lollypop/DeviceManagerWidget.ui') self.__error_label = builder.get_object('error-label') self.__switch_albums = builder.get_object('switch_albums') self.__switch_albums.set_state(Lp().settings.get_value('sync-albums')) self.__switch_mp3 = builder.get_object('switch_mp3') self.__switch_normalize = builder.get_object('switch_normalize') if not self._check_encoder_status(): self.__switch_mp3.set_sensitive(False) self.__switch_normalize.set_sensitive(False) self.__switch_mp3.set_tooltip_text( _("You need to install " + "gstreamer-plugins-ugly")) else: self.__switch_mp3.set_state(Lp().settings.get_value('convert-mp3')) self.__menu_items = builder.get_object('menu-items') self.__menu = builder.get_object('menu') self.__model = Gtk.ListStore(bool, str, int) self.__view = builder.get_object('view') self.__view.set_model(self.__model) builder.connect_signals(self) self.add(builder.get_object('widget')) self.__infobar = builder.get_object('infobar') self.__infobar_label = builder.get_object('infobarlabel') renderer0 = Gtk.CellRendererToggle() renderer0.set_property('activatable', True) renderer0.connect('toggled', self.__on_playlist_toggled) column0 = Gtk.TreeViewColumn(" ✓", renderer0, active=0) column0.set_clickable(True) column0.connect('clicked', self.__on_column0_clicked) renderer1 = CellRendererAlbum() self.__column1 = Gtk.TreeViewColumn("", renderer1, album=2) renderer2 = Gtk.CellRendererText() renderer2.set_property('ellipsize-set', True) renderer2.set_property('ellipsize', Pango.EllipsizeMode.END) self.__column2 = Gtk.TreeViewColumn("", renderer2, markup=1) self.__column2.set_expand(True) self.__view.append_column(column0) self.__view.append_column(self.__column1) self.__view.append_column(self.__column2)
def __init__(self, name, uri, icon=None): """ Init widget @param name as str @param uri as str @param icon as Gio.Icon """ Gtk.ListBoxRow.__init__(self) self.get_style_context().add_class("background") self.__name = name self.__uri = uri self.__progress = 0 self.__builder = Gtk.Builder() self.__builder.add_from_resource("/org/gnome/Lollypop/DeviceWidget.ui") self.__progressbar = self.__builder.get_object("progress") self.__revealer = self.__builder.get_object("revealer") self.__switch_normalize = self.__builder.get_object("switch_normalize") self.__builder.get_object("name").set_label(self.__name) self.__combobox = self.__builder.get_object("combobox") self.__sync_button = self.__builder.get_object("sync_button") if icon is not None: device_symbolic = self.__builder.get_object("device-symbolic") device_symbolic.set_from_gicon(icon, Gtk.IconSize.DND) self.add(self.__builder.get_object("widget")) self.__builder.connect_signals(self) self.__calculate_free_space() self.__mtp_sync = MtpSync() self.__mtp_sync.connect("sync-finished", self.__on_sync_finished) self.__mtp_sync.connect("sync-progress", self.__on_sync_progress) for encoder in self.__mtp_sync._GST_ENCODER.keys(): if not self.__mtp_sync.check_encoder_status(encoder): self.__builder.get_object(encoder).set_sensitive(False) App().task_helper.run(self.__get_basename_for_sync, callback=(self.__set_combobox_content, ))
def __init__(self, progress, parent): """ Init widget @param device as Device @param progress bar as Gtk.ProgressBar @param parent as Gtk.Widget """ Gtk.Bin.__init__(self) MtpSync.__init__(self) self._parent = parent self._progress = progress self._uri = None builder = Gtk.Builder() builder.add_from_resource('/org/gnome/Lollypop/DeviceManagerWidget.ui') self._error_label = builder.get_object('error-label') self._switch_albums = builder.get_object('switch_albums') self._switch_albums.set_state(Lp().settings.get_value('sync-albums')) self._switch_mp3 = builder.get_object('switch_mp3') self._switch_normalize = builder.get_object('switch_normalize') if not self._check_encoder_status(): self._switch_mp3.set_sensitive(False) self._switch_normalize.set_sensitive(False) self._switch_mp3.set_tooltip_text(_("You need to install " + "gstreamer-plugins-ugly")) else: self._switch_mp3.set_state(Lp().settings.get_value('convert-mp3')) self._menu_items = builder.get_object('menu-items') self._menu = builder.get_object('menu') self._model = Gtk.ListStore(bool, str, int) self._model.set_sort_column_id(1, Gtk.SortType.ASCENDING) self._model.set_sort_func(1, self._sort_items) self._view = builder.get_object('view') self._view.set_model(self._model) self._view.set_sensitive(not Lp().settings.get_value('sync-albums')) builder.connect_signals(self) self.add(builder.get_object('widget')) self._infobar = builder.get_object('infobar') self._infobar_label = builder.get_object('infobarlabel') renderer0 = Gtk.CellRendererToggle() renderer0.set_property('activatable', True) renderer0.connect('toggled', self._on_playlist_toggled) column0 = Gtk.TreeViewColumn("toggle", renderer0, active=0) renderer1 = Gtk.CellRendererText() renderer1.set_property('ellipsize-set', True) renderer1.set_property('ellipsize', Pango.EllipsizeMode.END) renderer1.set_property('editable', True) column1 = Gtk.TreeViewColumn('text', renderer1, text=1) column1.set_expand(True) self._view.append_column(column0) self._view.append_column(column1)
def _on_finished(self): """ Emit finished signal """ MtpSync._on_finished(self) if not self._switch_albums.get_state(): self._view.set_sensitive(True) self._menu.set_sensitive(True) self.emit('sync-finished')
def _on_finished(self): """ Emit finished signal """ MtpSync._on_finished(self) if not self._switch.get_state(): self._view.set_sensitive(True) self._switch.set_sensitive(True) self.emit("sync-finished")
def __init__(self, progress, parent): """ Init widget @param device as Device @param progress bar as Gtk.ProgressBar @param parent as Gtk.Widget """ Gtk.Bin.__init__(self) MtpSync.__init__(self) self._parent = parent self._progress = progress self._uri = None builder = Gtk.Builder() builder.add_from_resource('/org/gnome/Lollypop/DeviceManagerWidget.ui') self._error_label = builder.get_object('error-label') self._switch_albums = builder.get_object('switch_albums') self._switch_albums.set_state(Lp().settings.get_value('sync-albums')) self._switch_mp3 = builder.get_object('switch_mp3') if not self._check_encoder_status(): self._switch_mp3.set_sensitive(False) self._switch_mp3.set_tooltip_text( _("You need to install " + "gstreamer-plugins-ugly")) else: self._switch_mp3.set_state(Lp().settings.get_value('convert-mp3')) self._menu_items = builder.get_object('menu-items') self._menu = builder.get_object('menu') self._model = Gtk.ListStore(bool, str, int) self._model.set_sort_column_id(1, Gtk.SortType.ASCENDING) self._model.set_sort_func(1, self._sort_items) self._view = builder.get_object('view') self._view.set_model(self._model) self._view.set_sensitive(not Lp().settings.get_value('sync-albums')) builder.connect_signals(self) self.add(builder.get_object('widget')) self._infobar = builder.get_object('infobar') self._infobar_label = builder.get_object('infobarlabel') renderer0 = Gtk.CellRendererToggle() renderer0.set_property('activatable', True) renderer0.connect('toggled', self._on_playlist_toggled) column0 = Gtk.TreeViewColumn("toggle", renderer0, active=0) renderer1 = Gtk.CellRendererText() renderer1.set_property('ellipsize-set', True) renderer1.set_property('ellipsize', Pango.EllipsizeMode.END) renderer1.set_property('editable', True) column1 = Gtk.TreeViewColumn('text', renderer1, text=1) column1.set_expand(True) self._view.append_column(column0) self._view.append_column(column1)
def _on_finished(self): """ Emit finished signal """ MtpSync._on_finished(self) Lp().window.progress.set_fraction(1.0, self) if not self.__switch_albums.get_state(): self.__view.set_sensitive(True) self.__menu.set_sensitive(True) self.emit('sync-finished')
def _on_finished(self): """ Emit finished signal """ MtpSync._on_finished(self) Lp().window.progress.set_fraction(1.0, self) if not self.__switch_albums.get_state(): self.__view.set_sensitive(True) self.__menu.set_sensitive(True) self.emit("sync-finished")
def __init__(self, parent): """ Init widget @param device as Device @param parent as Gtk.Widget """ Gtk.Bin.__init__(self) self.__mtp_sync = MtpSync() self.__mtp_sync.connect("sync-finished", self.__on_sync_finished) self.__mtp_sync.connect("sync-progress", self.__on_sync_progress) self.__parent = parent self.__uri = None self.__builder = Gtk.Builder() self.__builder.add_from_resource( "/org/gnome/Lollypop/DeviceManagerWidget.ui") widget = self.__builder.get_object("widget") self.connect("size-allocate", self.__on_size_allocate, widget) self.__switch_albums = self.__builder.get_object("switch_albums") self.__menu_items = self.__builder.get_object("menu-items") self.__menu = self.__builder.get_object("menu") self.__model = Gtk.ListStore(bool, str, int) self.__view = self.__builder.get_object("view") self.__view.set_model(self.__model) self.__builder.connect_signals(self) self.add(widget) renderer0 = Gtk.CellRendererToggle() renderer0.set_property("activatable", True) renderer0.connect("toggled", self.__on_item_toggled) column0 = Gtk.TreeViewColumn(" ✓", renderer0, active=0) column0.set_clickable(True) column0.connect("clicked", self.__on_column0_clicked) renderer1 = CellRendererAlbum() self.__column1 = Gtk.TreeViewColumn("", renderer1, album=2) renderer2 = Gtk.CellRendererText() renderer2.set_property("ellipsize-set", True) renderer2.set_property("ellipsize", Pango.EllipsizeMode.END) self.__column2 = Gtk.TreeViewColumn("", renderer2, markup=1) self.__column2.set_expand(True) self.__view.append_column(column0) self.__view.append_column(self.__column1) self.__view.append_column(self.__column2)
def _on_errors(self): MtpSync._on_errors(self) error_text = _("Unknown error while syncing," " try to reboot your device") try: d = Gio.File.new_for_uri(self._uri) info = d.query_filesystem_info('filesystem::free') free = info.get_attribute_as_string('filesystem::free') if free is None or int(free) < 1024: error_text = _("No free space available on device") except Exception as e: print("DeviceWidget::_on_errors(): %s" % e) self._error_label.set_text(error_text) self._infobar.show()
def __init__(self, progress, parent): """ Init widget @param device as Device @param progress bar as Gtk.ProgressBar @param parent as Gtk.Widget """ Gtk.Bin.__init__(self) MtpSync.__init__(self) self._parent = parent self._progress = progress self._on_disk_playlists = None self._uri = None builder = Gtk.Builder() builder.add_from_resource('/org/gnome/Lollypop/DeviceManagerWidget.ui') self._error_label = builder.get_object('error-label') self._switch = builder.get_object('switch') self._model = Gtk.ListStore(bool, str, int) self._model.set_sort_column_id(1, Gtk.SortType.ASCENDING) self._model.set_sort_func(1, self._sort_items) self._view = builder.get_object('view') self._view.set_model(self._model) builder.connect_signals(self) self.add(builder.get_object('widget')) self._infobar = builder.get_object('infobar') self._infobar_label = builder.get_object('infobarlabel') renderer0 = Gtk.CellRendererToggle() renderer0.set_property('activatable', True) renderer0.connect('toggled', self._on_playlist_toggled) column0 = Gtk.TreeViewColumn("toggle", renderer0, active=0) renderer1 = Gtk.CellRendererText() renderer1.set_property('ellipsize-set', True) renderer1.set_property('ellipsize', Pango.EllipsizeMode.END) renderer1.set_property('editable', True) column1 = Gtk.TreeViewColumn('text', renderer1, text=1) column1.set_expand(True) self._view.append_column(column0) self._view.append_column(column1)
def _on_errors(self): """ Show information bar with error message """ MtpSync._on_errors(self) error_text = _("Unknown error while syncing," " try to reboot your device") try: d = Gio.File.new_for_uri(self._uri) info = d.query_filesystem_info("filesystem::free") free = info.get_attribute_as_string("filesystem::free") if free is None or int(free) < 1024: error_text = _("No free space available on device") except Exception as e: print("DeviceWidget::_on_errors(): %s" % e) self.__error_label.set_text(error_text) self.__infobar.show()
def _on_finished(self): MtpSync._on_finished(self) self.emit('sync-finished')
def __init__(self, parent): """ Init widget @param device as Device @param parent as Gtk.Widget """ Gtk.Bin.__init__(self) MtpSync.__init__(self) self.__parent = parent self.__stop = False self._uri = None builder = Gtk.Builder() builder.add_from_resource("/org/gnome/Lollypop/DeviceManagerWidget.ui") widget = builder.get_object("widget") self.__error_label = builder.get_object("error-label") self.__switch_albums = builder.get_object("switch_albums") self.__switch_albums.set_state(Lp().settings.get_value("sync-albums")) self.__switch_mp3 = builder.get_object("switch_mp3") self.__switch_normalize = builder.get_object("switch_normalize") if not self._check_encoder_status(): self.__switch_mp3.set_sensitive(False) self.__switch_normalize.set_sensitive(False) self.__switch_mp3.set_tooltip_text( _("You need to install " + "gstreamer-plugins-ugly")) else: self.__switch_mp3.set_state(Lp().settings.get_value("convert-mp3")) self.__menu_items = builder.get_object("menu-items") self.__menu = builder.get_object("menu") self.__model = Gtk.ListStore(bool, str, int) self.__selection_list = SelectionList(False) self.__selection_list.connect("item-selected", self.__on_item_selected) widget.attach(self.__selection_list, 1, 1, 1, 1) self.__selection_list.set_hexpand(True) self.__view = builder.get_object("view") self.__view.set_model(self.__model) builder.connect_signals(self) self.add(widget) self.__infobar = builder.get_object("infobar") self.__infobar_label = builder.get_object("infobarlabel") renderer0 = Gtk.CellRendererToggle() renderer0.set_property("activatable", True) renderer0.connect("toggled", self.__on_item_toggled) column0 = Gtk.TreeViewColumn(" ✓", renderer0, active=0) column0.set_clickable(True) column0.connect("clicked", self.__on_column0_clicked) renderer1 = CellRendererAlbum() self.__column1 = Gtk.TreeViewColumn("", renderer1, album=2) renderer2 = Gtk.CellRendererText() renderer2.set_property("ellipsize-set", True) renderer2.set_property("ellipsize", Pango.EllipsizeMode.END) self.__column2 = Gtk.TreeViewColumn("", renderer2, markup=1) self.__column2.set_expand(True) self.__view.append_column(column0) self.__view.append_column(self.__column1) self.__view.append_column(self.__column2)
class DeviceWidget(Gtk.ListBoxRow): """ A device widget for sync """ __gsignals__ = { "syncing": (GObject.SignalFlags.RUN_FIRST, None, (bool, )), } def __init__(self, name, uri, icon=None): """ Init widget @param name as str @param uri as str @param icon as Gio.Icon """ Gtk.ListBoxRow.__init__(self) self.get_style_context().add_class("background") self.__name = name self.__uri = uri self.__progress = 0 self.__builder = Gtk.Builder() self.__builder.add_from_resource("/org/gnome/Lollypop/DeviceWidget.ui") self.__progressbar = self.__builder.get_object("progress") self.__revealer = self.__builder.get_object("revealer") self.__switch_normalize = self.__builder.get_object("switch_normalize") self.__builder.get_object("name").set_label(self.__name) self.__combobox = self.__builder.get_object("combobox") self.__sync_button = self.__builder.get_object("sync_button") if icon is not None: device_symbolic = self.__builder.get_object("device-symbolic") device_symbolic.set_from_gicon(icon, Gtk.IconSize.DND) self.add(self.__builder.get_object("widget")) self.__builder.connect_signals(self) self.__calculate_free_space() self.__mtp_sync = MtpSync() self.__mtp_sync.connect("sync-finished", self.__on_sync_finished) self.__mtp_sync.connect("sync-progress", self.__on_sync_progress) for encoder in self.__mtp_sync._GST_ENCODER.keys(): if not self.__mtp_sync.check_encoder_status(encoder): self.__builder.get_object(encoder).set_sensitive(False) App().task_helper.run(self.__get_basename_for_sync, callback=(self.__set_combobox_content, )) @property def uri(self): """ Get device URI @return str """ return self.__uri @property def name(self): """ Get device name @return str """ return self.__name @property def progress(self): """ Get progress status @return int """ return self.__progress ####################### # PROTECTED # ####################### def _on_reveal_button_clicked(self, button): """ Show advanced device options @param button as Gtk.Button """ revealed = self.__revealer.get_reveal_child() self.__revealer.set_reveal_child(not revealed) def _on_content_albums_clicked(self, button): """ Show synced albums @param button as Gtk.Button """ index = self.__get_device_index() if index is not None: App().window.emit("show-can-go-back", True) App().window.container.show_view([Type.DEVICE_ALBUMS], index) elif App().notify is not None: App().notify.send(_("No synchronized albums")) def _on_content_playlists_clicked(self, button): """ Show synced playlists @param button as Gtk.Button """ index = self.__get_device_index() if index is not None: App().window.emit("show-can-go-back", True) App().window.container.show_view([Type.DEVICE_PLAYLISTS], index) elif App().notify is not None: App().notify.send(_("No synchronized playlists")) def _on_sync_button_clicked(self, button): """ Sync music on device @param button as Gtk.Button """ if self.__sync_button.get_label() == _("Synchronize"): self.__progress = 0 uri = self.__get_music_uri() index = self.__get_device_index() if index is not None: App().task_helper.run(self.__mtp_sync.sync, uri, index) self.emit("syncing", True) button.set_label(_("Cancel")) else: self.__mtp_sync.cancel() button.set_sensitive(False) def _on_convert_toggled(self, widget): """ Save option @param widget as Gtk.RadioButton """ if widget.get_active(): encoder = widget.get_name() if encoder == "convert_none": self.__switch_normalize.set_sensitive(False) self.__mtp_sync.db.set_normalize(False) self.__mtp_sync.db.set_encoder("convert_none") else: self.__switch_normalize.set_sensitive(True) self.__mtp_sync.db.set_encoder(encoder) def _on_normalize_state_set(self, widget, state): """ Save option @param widget as Gtk.Switch @param state as bool """ self.__mtp_sync.db.set_normalize(state) def _on_combobox_changed(self, combobox): """ Update DB @param combobox as Gtk.ComboxText """ self.__load_uri_settings(self.__get_music_uri()) ####################### # PRIVATE # ####################### def __get_device_index(self): """ Get current device index @return int/None """ try: devices = list(App().settings.get_value("devices")) index = devices.index(self.__name) + 1 except Exception as e: Logger.warning("DeviceWidget::__get_device_index(): %s", e) index = None return index def __get_music_uri(self): """ Get music URI on device @return str """ if self.__combobox.get_visible(): if self.__uri.endswith("/"): uri = "%s%s/Music" % (self.__uri, self.__combobox.get_active_text()) else: uri = "%s/%s/Music" % (self.__uri, self.__combobox.get_active_text()) else: uri = "%s/Music" % self.__uri return uri def __get_basename_for_sync(self): """ Get basename base on device content @return str """ names = [] try: if not self.__uri.startswith("mtp://") and\ self.__name != "Librem phone": return None # Search for previous sync d = Gio.File.new_for_uri(self.__uri) infos = d.enumerate_children("standard::name,standard::type", Gio.FileQueryInfoFlags.NONE, None) for info in infos: if info.get_file_type() != Gio.FileType.DIRECTORY: continue f = infos.get_child(info) uri = f.get_uri() + "/Music" previous_sync = Gio.File.new_for_uri("%s/unsync" % uri) if previous_sync.query_exists(): names.insert(0, info.get_name()) else: names.append(info.get_name()) infos.close(None) except Exception as e: Logger.error("DeviceWidget::__get_best_uri_for_sync: %s: %s" % (self.__uri, e)) return names def __set_combobox_content(self, names): """ Set combobox content based on names @param names as [str] """ self.__sync_button.set_sensitive(True) if names is None: self.__load_uri_settings(self.__get_music_uri()) self.__combobox.hide() elif names: self.__combobox.show() for name in names: self.__combobox.append_text(name) self.__combobox.set_active(0) else: self.__sync_button.set_sensitive(False) self.__combobox.hide() def __load_uri_settings(self, uri): """ Load settings at URI @param uri as str """ self.__mtp_sync.db.load(uri) encoder = self.__mtp_sync.db.encoder normalize = self.__mtp_sync.db.normalize self.__switch_normalize.set_sensitive(False) self.__switch_normalize.set_active(normalize) self.__builder.get_object(encoder).set_active(True) for encoder in self.__mtp_sync._GST_ENCODER.keys(): if not self.__mtp_sync.check_encoder_status(encoder): self.__builder.get_object(encoder).set_sensitive(False) def __calculate_free_space(self): """ Calculate free space on device """ f = Gio.File.new_for_uri(self.__uri) f.query_filesystem_info_async( "{},{}".format(FILE_ATTRIBUTE_FILESYSTEM_SIZE, FILE_ATTRIBUTE_FILESYSTEM_FREE), GLib.PRIORITY_DEFAULT, None, self.__on_filesystem_info) def __on_filesystem_info(self, source, result): """ Show available space on disk @param source as GObject.Object @param result as Gio.AsyncResult """ try: info = source.query_filesystem_info_finish(result) size = info.get_attribute_uint64(FILE_ATTRIBUTE_FILESYSTEM_SIZE) free = info.get_attribute_uint64(FILE_ATTRIBUTE_FILESYSTEM_FREE) if size == 0: return used = size - free fraction = 1 * used / size self.__progressbar.set_fraction(fraction) style_context = self.__progressbar.get_style_context() style_context.remove_class("usagebar-green") style_context.remove_class("usagebar-orange") style_context.remove_class("usagebar-red") if fraction < 0.6: style_context.add_class("usagebar-green") elif fraction < 0.8: style_context.add_class("usagebar-orange") else: style_context.add_class("usagebar-red") except Exception as e: Logger.error("DeviceWiget::__on_filesystem_info(): %s", e) def __on_sync_progress(self, mtp_sync, value): """ Update progress bar @param mtp_sync as MtpSync @param value as float """ self.__progress = value def __on_sync_finished(self, mtp_sync): """ Emit finished signal @param mtp_sync as MtpSync """ self.emit("syncing", False) self.__progress = 0 self.__sync_button.set_label(_("Synchronize")) self.__sync_button.set_sensitive(True) self.__calculate_free_space()
class DeviceManagerWidget(Gtk.Bin): """ Widget for synchronize mtp devices """ def __init__(self, parent): """ Init widget @param device as Device @param parent as Gtk.Widget """ Gtk.Bin.__init__(self) self.__mtp_sync = MtpSync() self.__mtp_sync.connect("sync-finished", self.__on_sync_finished) self.__mtp_sync.connect("sync-progress", self.__on_sync_progress) self.__parent = parent self.__uri = None self.__builder = Gtk.Builder() self.__builder.add_from_resource( "/org/gnome/Lollypop/DeviceManagerWidget.ui") widget = self.__builder.get_object("widget") self.connect("size-allocate", self.__on_size_allocate, widget) self.__switch_albums = self.__builder.get_object("switch_albums") self.__menu_items = self.__builder.get_object("menu-items") self.__menu = self.__builder.get_object("menu") self.__model = Gtk.ListStore(bool, str, int) self.__view = self.__builder.get_object("view") self.__view.set_model(self.__model) self.__builder.connect_signals(self) self.add(widget) renderer0 = Gtk.CellRendererToggle() renderer0.set_property("activatable", True) renderer0.connect("toggled", self.__on_item_toggled) column0 = Gtk.TreeViewColumn(" ✓", renderer0, active=0) column0.set_clickable(True) column0.connect("clicked", self.__on_column0_clicked) renderer1 = CellRendererAlbum() self.__column1 = Gtk.TreeViewColumn("", renderer1, album=2) renderer2 = Gtk.CellRendererText() renderer2.set_property("ellipsize-set", True) renderer2.set_property("ellipsize", Pango.EllipsizeMode.END) self.__column2 = Gtk.TreeViewColumn("", renderer2, markup=1) self.__column2.set_expand(True) self.__view.append_column(column0) self.__view.append_column(self.__column1) self.__view.append_column(self.__column2) def populate(self, selected_ids=[]): """ Populate playlists or albums for selected_ids @param selected_ids as [int] """ self.__model.clear() if selected_ids[0] == Type.PLAYLISTS: playlists = [(Type.LOVED, App().playlists.LOVED)] playlists += App().playlists.get() synced_ids = App().playlists.get_synced_ids() self.__append_playlists(playlists, synced_ids) self.__column1.set_visible(False) self.__column2.set_title(_("Playlists")) else: if selected_ids[0] == Type.COMPILATIONS: albums = App().albums.get_compilation_ids([]) elif selected_ids[0] == Type.ALL: albums = App().albums.get_synced_ids() else: albums = App().albums.get_ids(selected_ids, []) self.__model.clear() self.__append_albums(albums) self.__column1.set_visible(True) self.__column2.set_title(_("Albums")) def set_uri(self, uri): """ Set uri @param uri as str """ try: self.__switch_albums.disconnect_by_func(self.__on_albums_state_set) except: pass self.__mtp_sync.db.load(uri) encoder = self.__mtp_sync.db.encoder normalize = self.__mtp_sync.db.normalize self.__switch_normalize = self.__builder.get_object("switch_normalize") self.__switch_normalize.set_sensitive(False) self.__switch_normalize.set_active(normalize) self.__builder.get_object(encoder).set_active(True) for encoder in self.__mtp_sync._GST_ENCODER.keys(): if not self.__mtp_sync.check_encoder_status(encoder): self.__builder.get_object(encoder).set_sensitive(False) self.__uri = uri d = Gio.File.new_for_uri(uri) try: if not d.query_exists(): d.make_directory_with_parents() except: pass def sync(self): """ Start synchronisation """ App().window.container.progress.add(self) self.__menu.set_sensitive(False) self.__view.set_sensitive(False) App().task_helper.run(self.__mtp_sync.sync, self.__uri) @property def uri(self): """ Get device uri @return str """ return self.__uri @property def mtp_sync(self): """ MtpSync object @return MtpSync """ return self.__mtp_sync ####################### # PROTECTED # ####################### def _pop_menu(self, button): """ Popup menu for album @param button as Gtk.Button @param album id as int """ parent = self.__menu_items.get_parent() if parent is not None: parent.remove(self.__menu_items) popover = Popover.new(button) popover.set_position(Gtk.PositionType.BOTTOM) popover.add(self.__menu_items) popover.popup() def _on_convert_toggled(self, widget): """ Save option @param widget as Gtk.RadioButton """ if widget.get_active(): encoder = widget.get_name() if encoder == "convert_none": self.__switch_normalize.set_sensitive(False) self.__mtp_sync.db.set_normalize(False) self.__mtp_sync.db.set_encoder("convert_none") else: self.__switch_normalize.set_sensitive(True) self.__mtp_sync.db.set_encoder(encoder) def _on_normalize_state_set(self, widget, state): """ Save option @param widget as Gtk.Switch @param state as bool """ self.__mtp_sync.db.set_normalize(state) ####################### # PRIVATE # ####################### def __append_playlists(self, playlists, synced_ids): """ Append a playlist @param playlists as [(int, str)] @param synced_ids as [int] """ if playlists: playlist = playlists.pop(0) selected = playlist[0] in synced_ids self.__model.append([selected, playlist[1], playlist[0]]) GLib.idle_add(self.__append_playlists, playlists, synced_ids) def __append_albums(self, albums): """ Append albums @param albums as [int] """ if albums: album = Album(albums.pop(0)) synced = App().albums.get_synced(album.id) # Do not sync youtube albums if synced != Type.NONE: if album.artist_ids[0] == Type.COMPILATIONS: name = GLib.markup_escape_text(album.name) else: artists = ", ".join(album.artists) name = "<b>%s</b> - %s" % (GLib.markup_escape_text( artists), GLib.markup_escape_text(album.name)) self.__model.append([synced, name, album.id]) GLib.idle_add(self.__append_albums, albums) def __populate_albums_playlist(self, album_id, toggle): """ Populate hidden albums playlist @param album_id as int @param toggle as bool """ App().albums.set_synced(album_id, toggle) def __on_column0_clicked(self, column): """ Select/Unselect all playlists @param column as Gtk.TreeViewColumn """ selected = False for item in self.__model: if item[0]: selected = True for item in self.__model: item[0] = not selected if self.__column1.get_visible(): self.__populate_albums_playlist(item[2], item[0]) else: App().playlists.set_synced(item[2], item[0]) def __on_item_toggled(self, view, path): """ When item is toggled, set model @param widget as cell renderer @param path as str representation of Gtk.TreePath """ iterator = self.__model.get_iter(path) toggle = not self.__model.get_value(iterator, 0) self.__model.set_value(iterator, 0, toggle) item_id = self.__model.get_value(iterator, 2) if self.__column1.get_visible(): self.__populate_albums_playlist(item_id, toggle) else: App().playlists.set_synced(item_id, toggle) def __on_size_allocate(self, widget, allocation, child_widget): """ Set child widget size @param widget as Gtk.Widget @param allocation as Gtk.Allocation @param child_widget as Gtk.Widget """ width = max(400, allocation.width / 2) child_widget.set_size_request(width, -1) def __on_sync_progress(self, mtp_sync, value): """ Update progress bar @param mtp_sync as MtpSync @param value as float """ App().window.container.progress.set_fraction(value, self) def __on_sync_finished(self, mtp_sync): """ Emit finished signal @param mtp_sync as MtpSync """ App().window.container.progress.set_fraction(1.0, self) self.__view.set_sensitive(True) self.__menu.set_sensitive(True)
def __init__(self, parent): """ Init widget @param device as Device @param parent as Gtk.Widget """ Gtk.Bin.__init__(self) MtpSync.__init__(self) self.__parent = parent self.__stop = False self._uri = None builder = Gtk.Builder() builder.add_from_resource('/org/gnome/Lollypop/DeviceManagerWidget.ui') widget = builder.get_object('widget') self.__error_label = builder.get_object('error-label') self.__switch_albums = builder.get_object('switch_albums') self.__switch_albums.set_state(Lp().settings.get_value('sync-albums')) self.__switch_mp3 = builder.get_object('switch_mp3') self.__switch_normalize = builder.get_object('switch_normalize') if not self._check_encoder_status(): self.__switch_mp3.set_sensitive(False) self.__switch_normalize.set_sensitive(False) self.__switch_mp3.set_tooltip_text(_("You need to install " + "gstreamer-plugins-ugly")) else: self.__switch_mp3.set_state(Lp().settings.get_value('convert-mp3')) self.__menu_items = builder.get_object('menu-items') self.__menu = builder.get_object('menu') self.__model = Gtk.ListStore(bool, str, int) self.__selection_list = SelectionList(False) self.__selection_list.connect('item-selected', self.__on_item_selected) widget.attach(self.__selection_list, 1, 1, 1, 1) self.__selection_list.set_hexpand(True) self.__view = builder.get_object('view') self.__view.set_model(self.__model) builder.connect_signals(self) self.add(widget) self.__infobar = builder.get_object('infobar') self.__infobar_label = builder.get_object('infobarlabel') renderer0 = Gtk.CellRendererToggle() renderer0.set_property('activatable', True) renderer0.connect('toggled', self.__on_item_toggled) column0 = Gtk.TreeViewColumn(" ✓", renderer0, active=0) column0.set_clickable(True) column0.connect('clicked', self.__on_column0_clicked) renderer1 = CellRendererAlbum() self.__column1 = Gtk.TreeViewColumn("", renderer1, album=2) renderer2 = Gtk.CellRendererText() renderer2.set_property('ellipsize-set', True) renderer2.set_property('ellipsize', Pango.EllipsizeMode.END) self.__column2 = Gtk.TreeViewColumn("", renderer2, markup=1) self.__column2.set_expand(True) self.__view.append_column(column0) self.__view.append_column(self.__column1) self.__view.append_column(self.__column2)
def _on_finished(self): """ Emit finished signal """ MtpSync._on_finished(self) self.emit('sync-finished')