Example #1
0
    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)
Example #2
0
 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, ))
Example #3
0
    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)
Example #4
0
 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')
Example #5
0
 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")
Example #6
0
 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')
Example #7
0
    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)
Example #8
0
 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')
Example #9
0
 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")
Example #10
0
    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)
Example #11
0
    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()
Example #12
0
    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)
Example #13
0
    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)
Example #14
0
    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()
Example #15
0
 def _on_finished(self):
     MtpSync._on_finished(self)
     self.emit('sync-finished')
Example #16
0
    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)
Example #17
0
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()
Example #18
0
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)
Example #19
0
    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)
Example #20
0
 def _on_finished(self):
     """
         Emit finished signal
     """
     MtpSync._on_finished(self)
     self.emit('sync-finished')