Exemple #1
0
    def __init__(self, parent, error_text):
        main_text = _("Submit Error Report")
        secondary_text = _(
            "Various details regarding the error and your system will be send "
            "to a third party online service "
            "(<a href='https://www.sentry.io'>www.sentry.io</a>). You can "
            "review the data before sending it below.")

        secondary_text += u"\n\n"

        secondary_text += _(
            "(optional) Please provide a short description of what happened "
            "when the error occurred:")

        super(SubmitErrorDialog, self).__init__(modal=True,
                                                text=main_text,
                                                secondary_text=secondary_text,
                                                secondary_use_markup=True)

        self.set_transient_for(parent)
        self.add_button(_("_Cancel"), Gtk.ResponseType.CANCEL)
        self.add_button(_("_Send"), self.RESPONSE_SUBMIT)
        self.set_default_response(Gtk.ResponseType.CANCEL)

        area = self.get_message_area()

        self._entry = UndoEntry()
        self._entry.set_placeholder_text(_("Short description…"))
        area.pack_start(self._entry, False, True, 0)

        expand = TextExpander(_("Data to be sent:"), error_text)
        area.pack_start(expand, False, True, 0)
        area.show_all()

        self.get_widget_for_response(Gtk.ResponseType.CANCEL).grab_focus()
Exemple #2
0
    def __init__(self, parent, title, text, okbutton=Gtk.STOCK_OPEN):
        super(GetStringDialog, self).__init__(title=title,
                                              transient_for=parent,
                                              use_header_bar=True)

        self.set_border_width(6)
        self.set_default_size(width=self._WIDTH, height=0)
        self.set_resizable(True)
        self.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, okbutton,
                         Gtk.ResponseType.OK)
        self.vbox.set_spacing(6)
        self.set_default_response(Gtk.ResponseType.OK)

        box = Gtk.VBox(spacing=6)
        lab = Gtk.Label(label=text)
        box.set_border_width(6)
        lab.set_line_wrap(True)
        lab.set_justify(Gtk.Justification.CENTER)
        box.pack_start(lab, True, True, 0)

        self._val = UndoEntry()
        box.pack_start(self._val, True, True, 0)

        self.vbox.pack_start(box, True, True, 0)
        self.get_child().show_all()
Exemple #3
0
    def __init__(self, parent, title, text,
                 button_label=_("_OK"), button_icon=Icons.DOCUMENT_OPEN,
                 tooltip=None):
        super().__init__(
            title=title, transient_for=parent, use_header_bar=True)

        self.set_border_width(6)
        self.set_resizable(True)
        self.add_button(_("_Cancel"), Gtk.ResponseType.CANCEL)
        self.add_icon_button(button_label, button_icon, Gtk.ResponseType.OK)
        self.vbox.set_spacing(6)
        self.set_default_response(Gtk.ResponseType.OK)

        box = Gtk.VBox(spacing=6)
        lab = Gtk.Label(label=text)
        box.set_border_width(6)
        lab.set_line_wrap(True)
        lab.set_justify(Gtk.Justification.CENTER)
        box.pack_start(lab, True, True, 0)

        self._val = UndoEntry()
        if tooltip:
            self._val.set_tooltip_text(tooltip)
        self._val.set_max_width_chars(50)
        box.pack_start(self._val, True, True, 0)

        self.vbox.pack_start(box, True, True, 0)
        self.get_child().show_all()
Exemple #4
0
    def PluginPreferences(self, win):
        box = Gtk.VBox(spacing=12)

        # api key section
        def key_changed(entry, *args):
            config.set("plugins", "fingerprint_acoustid_api_key",
                entry.get_text())

        button = Button(_("Request API key"), Icons.NETWORK_WORKGROUP)
        button.connect("clicked",
            lambda s: util.website("https://acoustid.org/api-key"))
        key_box = Gtk.HBox(spacing=6)
        entry = UndoEntry()
        entry.set_text(get_api_key())
        entry.connect("changed", key_changed)
        label = Gtk.Label(label=_("API _key:"))
        label.set_use_underline(True)
        label.set_mnemonic_widget(entry)
        key_box.pack_start(label, False, True, 0)
        key_box.pack_start(entry, True, True, 0)
        key_box.pack_start(button, False, True, 0)

        box.pack_start(Frame(_("AcoustID Web Service"),
                       child=key_box), True, True, 0)

        return box
class ExportToFolderDialog(Dialog):
    """A dialog to collect export settings"""

    def __init__(self, parent, pattern):
        super(ExportToFolderDialog, self).__init__(
            title=_("Export Playlist to Folder"),
            transient_for=parent, use_header_bar=True)

        self.set_default_size(400, -1)
        self.set_resizable(True)
        self.set_border_width(6)
        self.vbox.set_spacing(6)

        self.add_button(_("_Cancel"), Gtk.ResponseType.CANCEL)
        self.add_button(_("_Export"), Gtk.ResponseType.OK)
        self.set_default_response(Gtk.ResponseType.OK)

        box = Gtk.VBox(spacing=6)

        destination_label = Gtk.Label(_("Destination folder:"))
        destination_label.set_line_wrap(True)
        destination_label.set_xalign(0.0)
        box.pack_start(destination_label, False, False, 0)

        frame = Gtk.Frame()
        self.directory_chooser = Gtk.FileChooserWidget(
            action=Gtk.FileChooserAction.SELECT_FOLDER)
        self.directory_chooser.set_select_multiple(False)
        self.directory_chooser.set_border_width(1)
        frame.add(self.directory_chooser)
        frame.set_shadow_type(Gtk.ShadowType.IN)
        frame.set_border_width(0)
        box.pack_start(frame, True, True, 0)

        pattern_label = Gtk.Label(_("Filename pattern:"))
        pattern_label.set_line_wrap(True)
        pattern_label.set_xalign(0.0)
        box.pack_start(pattern_label, False, False, 0)

        self.pattern_entry = UndoEntry()
        self.pattern_entry.set_text(pattern)
        box.pack_start(self.pattern_entry, False, False, 0)

        self.vbox.pack_start(box, True, True, 0)

        self.set_response_sensitive(Gtk.ResponseType.OK, False)

        def changed(*args):
            has_directory = self.directory_chooser.get_filename() is not None
            self.set_response_sensitive(Gtk.ResponseType.OK, has_directory)

            pattern_text = self.pattern_entry.get_text()
            has_pattern = bool(pattern_text)
            self.set_response_sensitive(Gtk.ResponseType.OK, has_pattern)

        self.directory_chooser.connect("selection-changed", changed)
        self.pattern_entry.connect("changed", changed)

        self.get_child().show_all()
class ExportToFolderDialog(Dialog):
    """A dialog to collect export settings"""
    def __init__(self, parent, pattern):
        super(ExportToFolderDialog,
              self).__init__(title=_("Export Playlist to Folder"),
                             transient_for=parent,
                             use_header_bar=True)

        self.set_default_size(400, -1)
        self.set_resizable(True)
        self.set_border_width(6)
        self.vbox.set_spacing(6)

        self.add_button(_("_Cancel"), Gtk.ResponseType.CANCEL)
        self.add_button(_("_Export"), Gtk.ResponseType.OK)
        self.set_default_response(Gtk.ResponseType.OK)

        box = Gtk.VBox(spacing=6)

        destination_label = Gtk.Label(_("Destination folder:"))
        destination_label.set_line_wrap(True)
        destination_label.set_xalign(0.0)
        box.pack_start(destination_label, False, False, 0)

        frame = Gtk.Frame()
        self.directory_chooser = Gtk.FileChooserWidget(
            action=Gtk.FileChooserAction.SELECT_FOLDER)
        self.directory_chooser.set_select_multiple(False)
        self.directory_chooser.set_border_width(1)
        frame.add(self.directory_chooser)
        frame.set_shadow_type(Gtk.ShadowType.IN)
        frame.set_border_width(0)
        box.pack_start(frame, True, True, 0)

        pattern_label = Gtk.Label(_("Filename pattern:"))
        pattern_label.set_line_wrap(True)
        pattern_label.set_xalign(0.0)
        box.pack_start(pattern_label, False, False, 0)

        self.pattern_entry = UndoEntry()
        self.pattern_entry.set_text(pattern)
        box.pack_start(self.pattern_entry, False, False, 0)

        self.vbox.pack_start(box, True, True, 0)

        self.set_response_sensitive(Gtk.ResponseType.OK, False)

        def changed(*args):
            has_directory = self.directory_chooser.get_filename() is not None
            self.set_response_sensitive(Gtk.ResponseType.OK, has_directory)

            pattern_text = self.pattern_entry.get_text()
            has_pattern = bool(pattern_text)
            self.set_response_sensitive(Gtk.ResponseType.OK, has_pattern)

        self.directory_chooser.connect("selection-changed", changed)
        self.pattern_entry.connect("changed", changed)

        self.get_child().show_all()
Exemple #7
0
    def __init__(self):
        super(Preferences, self).__init__(spacing=12)

        self.set_border_width(6)

        ccb = pconfig.ConfigCheckButton(_("Hide main window on close"), "window_hide", populate=True)
        self.pack_start(ccb, False, True, 0)

        def on_scroll_changed(button, new_state):
            if button.get_active():
                pconfig.set("modifier_swap", new_state)

        modifier_swap = pconfig.getboolean("modifier_swap")

        scrollwheel_box = Gtk.VBox(spacing=0)
        group = Gtk.RadioButton(group=None, label=_("Scroll wheel adjusts volume"), use_underline=True)
        group.connect("toggled", on_scroll_changed, False)
        group.set_active(not modifier_swap)
        scrollwheel_box.pack_start(group, False, True, 0)
        group = Gtk.RadioButton(group=group, label=_("Scroll wheel changes song"), use_underline=True)
        group.connect("toggled", on_scroll_changed, True)
        group.set_active(modifier_swap)
        scrollwheel_box.pack_start(group, False, True, 0)

        self.pack_start(qltk.Frame(_("Scroll _Wheel"), child=scrollwheel_box), True, True, 0)

        box = Gtk.VBox(spacing=12)

        entry_box = Gtk.HBox(spacing=6)

        entry = UndoEntry()
        entry_box.pack_start(entry, True, True, 0)

        def on_reverted(*args):
            pconfig.reset("tooltip")
            entry.set_text(pconfig.gettext("tooltip"))

        revert = Gtk.Button()
        revert.add(Gtk.Image.new_from_icon_name(Icons.DOCUMENT_REVERT, Gtk.IconSize.BUTTON))
        revert.connect("clicked", on_reverted)
        entry_box.pack_start(revert, False, True, 0)

        box.pack_start(entry_box, False, True, 0)

        preview = Gtk.Label()
        preview.set_line_wrap(True)
        frame = Gtk.Frame()
        frame.add(preview)
        box.pack_start(frame, False, True, 0)

        frame = qltk.Frame(_("Tooltip Display"), child=box)
        frame.get_label_widget().set_mnemonic_widget(entry)
        self.pack_start(frame, True, True, 0)

        entry.connect("changed", self.__changed_entry, preview, frame)
        entry.set_text(pconfig.gettext("tooltip"))

        for child in self.get_children():
            child.show_all()
 def create_pattern():
     hbox = Gtk.HBox(spacing=6)
     hbox.set_border_width(6)
     label = Gtk.Label(label=_("Default filename pattern:"))
     hbox.pack_start(label, False, True, 0)
     entry = UndoEntry()
     if CONFIG.default_pattern:
         entry.set_text(CONFIG.default_pattern)
     entry.connect('changed', changed)
     hbox.pack_start(entry, True, True, 0)
     return hbox
    def PluginPreferences(self, parent):
        outer_vb = Gtk.VBox(spacing=12)
        vb = Gtk.VBox(spacing=12)

        # Naming Pattern
        hb = Gtk.HBox(spacing=6)
        entry = UndoEntry()
        entry.set_text(self.config_get(self.CFG_PAT_PLAYING,
                                       self.DEFAULT_PAT))
        entry.connect('changed',
                      self.config_entry_changed,
                      self.CFG_PAT_PLAYING)
        lbl = Gtk.Label(label=_("Naming pattern:"))
        entry.set_tooltip_markup(_("File path based off of tags "
                                   "to move a file after update. "
                                   "Accepts QL Patterns e.g. %s") %
                                 util.monospace(util.escape("<~artist" +
                                                            "~title>")))
        lbl.set_mnemonic_widget(entry)
        hb.pack_start(lbl, False, True, 0)
        hb.pack_start(entry, True, True, 0)
        vb.pack_start(hb, True, True, 0)

        # Frame
        frame = qltk.Frame(_("New File Location/Name"), child=vb)
        outer_vb.pack_start(frame, False, True, 0)

        return outer_vb
    def __init__(self):
        super(Preferences, self).__init__(spacing=12)

        correct_browser = not isinstance(app.browser, AudioFeeds)

        table = Gtk.Table(2, 2)
        table.set_col_spacings(6)
        table.set_row_spacings(6)

        labels = {}
        entries = {}
        for idx, key in enumerate(["gpodder.net/name",
                                   "gpodder.net/password",
                                   "gpodder.net/device"]):
            text, tooltip = _SETTINGS[key][:2]
            label = Gtk.Label(label=text)
            entry = UndoEntry()
            entry.set_text(get_cfg(key))
            if key == "gpodder.net/password":
                entry.set_visibility(False)
            entries[key] = entry
            labels[key] = label
            labels[key].set_mnemonic_widget(entry)
            label.set_tooltip_text(tooltip)
            label.set_alignment(0.0, 0.5)
            label.set_padding(0, 6)
            label.set_use_underline(True)
            table.attach(label, 0, 1, idx, idx+1,
                         xoptions=Gtk.AttachOptions.FILL |
                         Gtk.AttachOptions.SHRINK)
            table.attach(entry, 1, 2, idx, idx+1,
                         xoptions=Gtk.AttachOptions.FILL |
                         Gtk.AttachOptions.SHRINK)
        # value, lower, upper, step_increment, page_increment

        def gpodder_go(button):
            for key in entries:
                value = entries[key].get_text()
                set_cfg(key, value)
            name = get_cfg("gpodder.net/name")
            password = get_cfg("gpodder.net/password")
            device = get_cfg("gpodder.net/device")
            fetch_gpodder(name, password, device)

        button = Gtk.Button(label=_("Fetch!" if correct_browser else "(Fetch) Please switch to a different browser!"), sensitive=correct_browser)
        button.connect("pressed", gpodder_go)
        table.attach(button, 0, 2, idx+1, idx+2)

        self.pack_start(qltk.Frame("Preferences", child=table),
                        True, True, 0)
Exemple #11
0
        def tag_editing_vbox(self):
            """Returns a new VBox containing all tag editing widgets"""
            vbox = Gtk.VBox(spacing=6)
            cb = CCB(_("Auto-save tag changes"),
                     'editing',
                     'auto_save_changes',
                     populate=True,
                     tooltip=_("Save changes to tags without confirmation "
                               "when editing multiple files"))
            vbox.pack_start(cb, False, True, 0)
            hb = Gtk.HBox(spacing=6)
            e = UndoEntry()
            e.set_text(config.get("editing", "split_on"))
            e.connect('changed', self.__changed, 'editing', 'split_on')
            e.set_tooltip_text(
                _("A list of separators to use when splitting tag values. "
                  "The list is space-separated"))

            def do_revert_split(button, section, option):
                config.reset(section, option)
                e.set_text(config.get(section, option))

            split_revert = Button(_("_Revert"), Icons.DOCUMENT_REVERT)
            split_revert.connect("clicked", do_revert_split, "editing",
                                 "split_on")
            l = Gtk.Label(label=_("Split _on:"))
            l.set_use_underline(True)
            l.set_mnemonic_widget(e)
            hb.pack_start(l, False, True, 0)
            hb.pack_start(e, True, True, 0)
            hb.pack_start(split_revert, False, True, 0)
            vbox.pack_start(hb, False, True, 0)
            return vbox
Exemple #12
0
    def __init__(
        self, parent, title, text, options=[], okbutton=gtk.STOCK_OPEN):
        super(GetStringDialog, self).__init__(title, parent)
        self.set_border_width(6)
        self.set_has_separator(False)
        self.set_resizable(False)
        self.add_buttons(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
                         okbutton, gtk.RESPONSE_OK)
        self.vbox.set_spacing(6)
        self.set_default_response(gtk.RESPONSE_OK)

        box = gtk.VBox(spacing=6)
        lab = gtk.Label(text)
        box.set_border_width(6)
        lab.set_line_wrap(True)
        lab.set_justify(gtk.JUSTIFY_CENTER)
        box.pack_start(lab)

        if options:
            self._entry = gtk.combo_box_entry_new_text()
            for o in options: self._entry.append_text(o)
            self._val = self._entry.child
            box.pack_start(self._entry)
        else:
            self._val = UndoEntry()
            box.pack_start(self._val)

        self.vbox.pack_start(box)
        self.child.show_all()
Exemple #13
0
    def __init__(self, parent, title, text,
                 button_label=_("_OK"), button_icon=Icons.DOCUMENT_OPEN,
                 tooltip=None):
        super(GetStringDialog, self).__init__(
            title=title, transient_for=parent, use_header_bar=True)

        self.set_border_width(6)
        self.set_resizable(True)
        self.add_button(_("_Cancel"), Gtk.ResponseType.CANCEL)
        self.add_icon_button(button_label, button_icon, Gtk.ResponseType.OK)
        self.vbox.set_spacing(6)
        self.set_default_response(Gtk.ResponseType.OK)

        box = Gtk.VBox(spacing=6)
        lab = Gtk.Label(label=text)
        box.set_border_width(6)
        lab.set_line_wrap(True)
        lab.set_justify(Gtk.Justification.CENTER)
        box.pack_start(lab, True, True, 0)

        self._val = UndoEntry()
        if tooltip:
            self._val.set_tooltip_text(tooltip)
        self._val.set_max_width_chars(50)
        box.pack_start(self._val, True, True, 0)

        self.vbox.pack_start(box, True, True, 0)
        self.get_child().show_all()
Exemple #14
0
    def __init__(self, parent, error_text):
        main_text = _("Submit Error Report")
        secondary_text = _(
            "Various details regarding the error and your system will be send "
            "to a third party online service "
            "(<a href='https://www.sentry.io'>www.sentry.io</a>). You can "
            "review the data before sending it below.")

        secondary_text += u"\n\n"

        secondary_text += _(
            "(optional) Please provide a short description of what happened "
            "when the error occurred:")

        super(SubmitErrorDialog, self).__init__(
            modal=True, text=main_text, secondary_text=secondary_text,
            secondary_use_markup=True)

        self.set_transient_for(parent)
        self.add_button(_("_Cancel"), Gtk.ResponseType.CANCEL)
        self.add_button(_("_Send"), self.RESPONSE_SUBMIT)
        self.set_default_response(Gtk.ResponseType.CANCEL)

        area = self.get_message_area()

        self._entry = UndoEntry()
        self._entry.set_placeholder_text(_("Short description…"))
        area.pack_start(self._entry, False, True, 0)

        expand = TextExpander(_("Data to be sent:"), error_text)
        area.pack_start(expand, False, True, 0)
        area.show_all()

        self.get_widget_for_response(Gtk.ResponseType.CANCEL).grab_focus()
Exemple #15
0
    def PluginPreferences(klass, win):
        def entry_changed(entry):
            config.set('plugins', 'lastfmsync_username', entry.get_text())

        label = Gtk.Label(label=_("_Username:"******"Account"), child=hbox)
Exemple #16
0
 def create_visible_columns_frame():
     buttons = {}
     vbox = Gtk.VBox(spacing=12)
     table = Gtk.Table.new(3, 3, True)
     for i, (k, t) in enumerate(self.PREDEFINED_TAGS):
         x, y = i % 3, i / 3
         buttons[k] = Gtk.CheckButton(label=t, use_underline=True)
         table.attach(buttons[k], x, x + 1, y, y + 1)
     vbox.pack_start(table, False, True, 0)
     # Other columns
     hbox = Gtk.HBox(spacing=6)
     l = Gtk.Label(label=_("_Others:"), use_underline=True)
     hbox.pack_start(l, False, True, 0)
     self.others = others = UndoEntry()
     others.set_sensitive(False)
     # Stock edit doesn't have ellipsis chars.
     edit_button = Gtk.Button(
         label=_(u"_Edit…"), use_underline=True)
     edit_button.connect("clicked", self.__config_cols, buttons)
     edit_button.set_tooltip_text(
         _("Add or remove additional column "
           "headers"))
     l.set_mnemonic_widget(edit_button)
     l.set_use_underline(True)
     hbox.pack_start(others, True, True, 0)
     vbox.pack_start(hbox, False, True, 0)
     b = Gtk.HButtonBox()
     b.set_layout(Gtk.ButtonBoxStyle.END)
     b.pack_start(edit_button, True, True, 0)
     vbox.pack_start(b, True, True, 0)
     return qltk.Frame(_("Visible Columns"), child=vbox), buttons
Exemple #17
0
        def tag_editing_vbox(self):
            """Returns a new VBox containing all tag editing widgets"""
            vbox = Gtk.VBox(spacing=6)
            cb = CCB(_("Auto-save tag changes"), 'editing',
                     'auto_save_changes', populate=True,
                     tooltip=_("Save changes to tags without confirmation "
                               "when editing multiple files"))
            vbox.pack_start(cb, False, True, 0)
            hb = Gtk.HBox(spacing=6)
            e = UndoEntry()
            e.set_text(config.get("editing", "split_on"))
            e.connect('changed', self.__changed, 'editing', 'split_on')
            e.set_tooltip_text(
                _("A list of separators to use when splitting tag values. "
                  "The list is space-separated"))

            def do_revert_split(button, section, option):
                config.reset(section, option)
                e.set_text(config.get(section, option))

            split_revert = Button(_("_Revert"), Icons.DOCUMENT_REVERT)
            split_revert.connect("clicked", do_revert_split, "editing",
                                 "split_on")
            l = Gtk.Label(label=_("Split _on:"))
            l.set_use_underline(True)
            l.set_mnemonic_widget(e)
            hb.pack_start(l, False, True, 0)
            hb.pack_start(e, True, True, 0)
            hb.pack_start(split_revert, False, True, 0)
            vbox.pack_start(hb, False, True, 0)
            return vbox
Exemple #18
0
    def PluginPreferences(self, *args):
        grid = Gtk.Grid(row_spacing=6, column_spacing=6)

        label = Gtk.Label(label=_("_Database path:"), use_underline=True)
        label.set_alignment(0.0, 0.5)
        grid.attach(label, 0, 0, 1, 1)

        entry = UndoEntry()
        entry.set_hexpand(True)
        entry.set_text(BansheeImport.DEF_PATH)

        def path_activate(entry, *args):
            path = text2fsn(entry.get_text())
            if BansheeImport.USR_PATH != path:
                BansheeImport.USR_PATH = path

        entry.connect_after("activate", path_activate)
        entry.connect_after("focus-out-event", path_activate)
        grid.attach_next_to(entry, label, Gtk.PositionType.RIGHT, 1, 1)

        path_revert = Gtk.Button()
        path_revert.add(Gtk.Image.new_from_icon_name(
                        Icons.DOCUMENT_REVERT, Gtk.IconSize.MENU))

        def path_revert_cb(button, entry):
            entry.set_text(BansheeImport.DEF_PATH)
            entry.emit("activate")

        path_revert.connect("clicked", path_revert_cb, entry)
        grid.attach_next_to(path_revert, entry, Gtk.PositionType.RIGHT, 1, 1)

        button = Gtk.Button(label=_("Start Import"))

        def clicked_cb(button):
            do_import(button, app.library)

        button.connect("clicked", clicked_cb)

        box = Gtk.VBox(spacing=12)

        box.pack_start(grid, True, True, 0)
        box.pack_start(button, False, False, 0)

        return box
        def build_alternate_search_widget():
            vb2 = Gtk.VBox(spacing=3)

            hb = Gtk.HBox(spacing=6)

            def on_entry_changed(entry, *args):
                self.Conf.alternate_search_url = entry.get_text()

            URL_entry = UndoEntry()
            URL_entry.set_text(self.Conf.alternate_search_url)
            URL_entry.connect("changed", on_entry_changed)

            l1 = ConfigLabel(_("URL:"), URL_entry)

            URL_revert = Gtk.Button()
            URL_revert.add(Gtk.Image.new_from_icon_name(
                Icons.DOCUMENT_REVERT, Gtk.IconSize.MENU))
            URL_revert.set_tooltip_text(_("Revert to default"))

            connect_obj(URL_revert, "clicked", URL_entry.set_text,
                DEFAULT_ALTERNATE_SEARCH_URL)

            hb.pack_start(l1, False, True, 0)
            hb.pack_start(URL_entry, True, True, 0)
            hb.pack_start(URL_revert, False, True, 0)

            vb2.pack_start(hb, False, True, 0)

            def on_alternate_search_toggled(button, *args):
                self.Conf.alternate_search_enabled = button.get_active()

            alternate_search_enabled = Gtk.CheckButton(
                label=_("Search via above URL if the lyrics "
                        "couldn't be found in LyricsWikia."),
                use_underline=True)
            alternate_search_enabled.set_active(
                self.Conf.alternate_search_enabled)
            alternate_search_enabled.connect("toggled",
                on_alternate_search_toggled)

            vb2.pack_start(alternate_search_enabled, False, True, 0)

            return vb2
Exemple #20
0
    def __init__(self):
        super(Preferences, self).__init__(spacing=12)

        correct_browser = not isinstance(app.browser, AudioFeeds)

        table = Gtk.Table(2, 2)
        table.set_col_spacings(6)
        table.set_row_spacings(6)

        labels = {}
        entries = {}
        for idx, key in enumerate(
            ["gpodder.net/name", "gpodder.net/password",
             "gpodder.net/device"]):
            text, tooltip = _SETTINGS[key][:2]
            label = Gtk.Label(label=text)
            entry = UndoEntry()
            entry.set_text(get_cfg(key))
            if key == "gpodder.net/password":
                entry.set_visibility(False)
            entries[key] = entry
            labels[key] = label
            labels[key].set_mnemonic_widget(entry)
            label.set_tooltip_text(tooltip)
            label.set_alignment(0.0, 0.5)
            label.set_padding(0, 6)
            label.set_use_underline(True)
            table.attach(label,
                         0,
                         1,
                         idx,
                         idx + 1,
                         xoptions=Gtk.AttachOptions.FILL
                         | Gtk.AttachOptions.SHRINK)
            table.attach(entry,
                         1,
                         2,
                         idx,
                         idx + 1,
                         xoptions=Gtk.AttachOptions.FILL
                         | Gtk.AttachOptions.SHRINK)
        # value, lower, upper, step_increment, page_increment

        def gpodder_go(button):
            for key in entries:
                value = entries[key].get_text()
                set_cfg(key, value)
            name = get_cfg("gpodder.net/name")
            password = get_cfg("gpodder.net/password")
            device = get_cfg("gpodder.net/device")
            fetch_gpodder(name, password, device)

        button = Gtk.Button(
            label=_("Fetch!" if correct_browser else
                    "(Fetch) Please switch to a different browser!"),
            sensitive=correct_browser)
        button.connect("pressed", gpodder_go)
        table.attach(button, 0, 2, idx + 1, idx + 2)

        self.pack_start(qltk.Frame("Preferences", child=table), True, True, 0)
Exemple #21
0
    def PluginPreferences(self, win):
        box = Gtk.VBox(spacing=12)

        # api key section
        def key_changed(entry, *args):
            config.set("plugins", "fingerprint_acoustid_api_key",
                       entry.get_text())

        button = Button(_("Request API key"), Gtk.STOCK_NETWORK)
        button.connect("clicked",
                       lambda s: util.website("https://acoustid.org/api-key"))
        key_box = Gtk.HBox(spacing=6)
        entry = UndoEntry()
        entry.set_text(get_api_key())
        entry.connect("changed", key_changed)
        label = Gtk.Label(label=_("API _key:"))
        label.set_use_underline(True)
        label.set_mnemonic_widget(entry)
        key_box.pack_start(label, False, True, 0)
        key_box.pack_start(entry, True, True, 0)
        key_box.pack_start(button, False, True, 0)

        box.pack_start(Frame(_("Acoustid Web Service"), child=key_box), True,
                       True, 0)

        return box
Exemple #22
0
    def PluginPreferences(self, *args):
        vbox = Gtk.VBox(spacing=12)

        label = Gtk.Label(label=_("Visualiser executable:"))

        def edited(widget):
            self.executable = widget.get_text()
        entry = UndoEntry()
        entry.connect('changed', edited)
        entry.set_text(self.executable)
        hbox = Gtk.HBox(spacing=6)
        hbox.pack_start(label, False, False, 0)
        hbox.pack_start(entry, True, True, 0)
        vbox.pack_start(hbox, True, True, 0)

        def refresh_clicked(widget):
            self.disabled()
            self.enabled()
        refresh_button = Button(_("Reload"), Icons.VIEW_REFRESH)
        refresh_button.connect('clicked', refresh_clicked)
        vbox.pack_start(refresh_button, False, False, 0)
        return vbox
    def __init__(self, parent):
        if self.is_not_unique(): return
        super(PreferencesWindow, self).__init__()
        self.set_title(_("Ex Falso Preferences"))
        self.set_border_width(12)
        self.set_resizable(False)
        self.set_transient_for(parent)

        vbox = gtk.VBox(spacing=6)
        hb = gtk.HBox(spacing=6)
        e = UndoEntry()
        e.set_text(config.get("editing", "split_on"))
        e.connect('changed', self.__changed, 'editing', 'split_on')
        l = gtk.Label(_("Split _on:"))
        l.set_use_underline(True)
        l.set_mnemonic_widget(e)
        hb.pack_start(l, expand=False)
        hb.pack_start(e)
        cb = ConfigCheckButton(
            _("Show _programmatic tags"), 'editing', 'alltags')
        cb.set_active(config.getboolean("editing", 'alltags'))
        vbox.pack_start(hb, expand=False)
        vbox.pack_start(cb, expand=False)
        f = qltk.Frame(_("Tag Editing"), child=vbox)

        close = gtk.Button(stock=gtk.STOCK_CLOSE)
        close.connect_object('clicked', lambda x: x.destroy(), self)
        button_box = gtk.HButtonBox()
        button_box.set_layout(gtk.BUTTONBOX_END)
        button_box.pack_start(close)

        main_vbox = gtk.VBox(spacing=12)
        main_vbox.pack_start(f)
        main_vbox.pack_start(button_box, expand=False)
        self.add(main_vbox)

        self.connect_object('destroy', PreferencesWindow.__destroy, self)
        self.show_all()
Exemple #24
0
    def __init__(self, parent):
        if self.is_not_unique():
            return
        super(PreferencesWindow, self).__init__()
        self.set_title(_("Ex Falso Preferences"))
        self.set_border_width(12)
        self.set_resizable(False)
        self.set_transient_for(parent)

        vbox = Gtk.VBox(spacing=6)
        hb = Gtk.HBox(spacing=6)
        e = UndoEntry()
        e.set_text(config.get("editing", "split_on"))
        e.connect('changed', self.__changed, 'editing', 'split_on')
        l = Gtk.Label(label=_("Split _on:"))
        l.set_use_underline(True)
        l.set_mnemonic_widget(e)
        hb.pack_start(l, False, True, 0)
        hb.pack_start(e, True, True, 0)
        vbox.pack_start(hb, False, True, 0)
        f = qltk.Frame(_("Tag Editing"), child=vbox)

        close = Button(_("_Close"), Icons.WINDOW_CLOSE)
        connect_obj(close, 'clicked', lambda x: x.destroy(), self)
        button_box = Gtk.HButtonBox()
        button_box.set_layout(Gtk.ButtonBoxStyle.END)
        button_box.pack_start(close, True, True, 0)

        main_vbox = Gtk.VBox(spacing=12)
        main_vbox.pack_start(f, True, True, 0)
        self.use_header_bar()
        if not self.has_close_button():
            main_vbox.pack_start(button_box, False, True, 0)
        self.add(main_vbox)

        connect_obj(self, 'destroy', PreferencesWindow.__destroy, self)
        self.get_child().show_all()
Exemple #25
0
 def create_pattern():
     hbox = Gtk.HBox(spacing=6)
     hbox.set_border_width(6)
     label = Gtk.Label(label=_("Default filename pattern:"))
     hbox.pack_start(label, False, True, 0)
     entry = UndoEntry()
     if CONFIG.default_pattern:
         entry.set_text(CONFIG.default_pattern)
     entry.connect('changed', changed)
     hbox.pack_start(entry, True, True, 0)
     return hbox
Exemple #26
0
 def config_table_for(self, config_data):
     t = Gtk.Table(n_rows=2, n_columns=len(config_data))
     t.set_col_spacings(6)
     t.set_row_spacings(6)
     for i, (label, cfg, tooltip) in enumerate(config_data):
         entry = (ValidatingEntry(
             validator=validator) if self._is_pattern(cfg) else UndoEntry())
         entry.set_text(str(self.config_get(*cfg)))
         entry.connect('changed', self._on_changed, cfg)
         lbl = Gtk.Label(label=label + ":")
         lbl.set_size_request(140, -1)
         lbl.set_alignment(xalign=0.0, yalign=0.5)
         entry.set_tooltip_markup(tooltip)
         lbl.set_mnemonic_widget(entry)
         t.attach(lbl, 0, 1, i, i + 1, xoptions=FILL)
         t.attach(entry, 1, 2, i, i + 1, xoptions=FILL | EXPAND)
     return t
Exemple #27
0
        def tag_editing_vbox(self):
            """Returns a new VBox containing all tag editing widgets"""
            vbox = Gtk.VBox(spacing=6)
            cb = CCB(_("Auto-save tag changes"),
                     'editing',
                     'auto_save_changes',
                     populate=True,
                     tooltip=_("Save changes to tags without confirmation "
                               "when editing multiple files"))
            vbox.pack_start(cb, False, True, 0)
            cb = CCB(_("Show _programmatic tags"),
                     'editing',
                     'alltags',
                     populate=True,
                     tooltip=_("Access all tags, including machine-generated "
                               "ones e.g. MusicBrainz or Replay Gain tags"))
            vbox.pack_start(cb, False, True, 0)
            hb = Gtk.HBox(spacing=6)
            e = UndoEntry()
            e.set_text(config.get("editing", "split_on"))
            e.connect('changed', self.__changed, 'editing', 'split_on')
            e.set_tooltip_text(
                _("A list of separators to use when splitting tag values. "
                  "The list is space-separated"))

            def do_revert_split(button, section, option):
                config.reset(section, option)
                e.set_text(config.get(section, option))

            split_revert = Gtk.Button()
            split_revert.add(
                Gtk.Image.new_from_stock(Gtk.STOCK_REVERT_TO_SAVED,
                                         Gtk.IconSize.MENU))
            split_revert.connect("clicked", do_revert_split, "editing",
                                 "split_on")
            l = Gtk.Label(label=_("Split _on:"))
            l.set_use_underline(True)
            l.set_mnemonic_widget(e)
            hb.pack_start(l, False, True, 0)
            hb.pack_start(e, True, True, 0)
            hb.pack_start(split_revert, False, True, 0)
            vbox.pack_start(hb, False, True, 0)
            return vbox
Exemple #28
0
def _config(section, option, label, tooltip, getter):
    def on_changed(entry, *args):
        config.set(section, option, entry.get_text())

    entry = UndoEntry()
    entry.set_tooltip_text(tooltip)
    entry.set_text(decode(config.get(section, option)))
    entry.connect("changed", on_changed)

    def on_reverted(*args):
        config.reset(section, option)
        entry.set_text(decode(config.get(section, option)))

    revert = Gtk.Button()
    revert.add(Gtk.Image.new_from_icon_name(
        Icons.DOCUMENT_REVERT, Gtk.IconSize.BUTTON))
    revert.connect("clicked", on_reverted)

    return (Gtk.Label(label=label), entry, revert)
Exemple #29
0
    def PluginPreferences(cls, window):
        def key_changed(entry):
            cls.key_expression = None
            cls.config_set(cls._CFG_KEY_KEY, entry.get_text().strip())

        vb = Gtk.VBox(spacing=10)
        vb.set_border_width(0)
        hbox = Gtk.HBox(spacing=6)
        # TODO: construct a decent validator and use ValidatingEntry
        e = UndoEntry()
        e.set_text(cls.get_key_expression())
        e.connect("changed", key_changed)
        e.set_tooltip_markup(
            _("Accepts QL tag expressions like "
              "<tt>~artist~title</tt> or <tt>musicbrainz_track_id</tt>"))
        lbl = Gtk.Label(label=_("_Group duplicates by:"))
        lbl.set_mnemonic_widget(e)
        lbl.set_use_underline(True)
        hbox.pack_start(lbl, False, True, 0)
        hbox.pack_start(e, True, True, 0)
        frame = qltk.Frame(label=_("Duplicate Key"), child=hbox)
        vb.pack_start(frame, True, True, 0)

        # Matching Option
        toggles = [
            (cls._CFG_REMOVE_WHITESPACE, _("Remove _Whitespace")),
            (cls._CFG_REMOVE_DIACRITICS, _("Remove _Diacritics")),
            (cls._CFG_REMOVE_PUNCTUATION, _("Remove _Punctuation")),
            (cls._CFG_CASE_INSENSITIVE, _("Case _Insensitive")),
        ]
        vb2 = Gtk.VBox(spacing=6)
        for key, label in toggles:
            ccb = ConfigCheckButton(label, 'plugins', cls._config_key(key))
            ccb.set_active(cls.config_get_bool(key))
            vb2.pack_start(ccb, True, True, 0)

        frame = qltk.Frame(label=_("Matching options"), child=vb2)
        vb.pack_start(frame, False, True, 0)

        vb.show_all()
        return vb
def _config(section, option, label, tooltip, getter):
    def on_changed(entry, *args):
        config.set(section, option, entry.get_text())

    entry = UndoEntry()
    entry.set_tooltip_text(tooltip)
    entry.set_text(decode(config.get(section, option)))
    entry.connect("changed", on_changed)

    def on_reverted(*args):
        config.reset(section, option)
        entry.set_text(decode(config.get(section, option)))

    revert = Gtk.Button()
    revert.add(Gtk.Image.new_from_icon_name(Icons.DOCUMENT_REVERT, Gtk.IconSize.BUTTON))
    revert.connect("clicked", on_reverted)

    return (Gtk.Label(label=label), entry, revert)
def _config(section, option, label, tooltip=None, getter=None):
    def on_changed(entry, *args):
        config.settext(section, option, entry.get_text())

    entry = UndoEntry()
    if tooltip:
        entry.set_tooltip_text(tooltip)
    entry.set_text(config.gettext(section, option))
    entry.connect("changed", on_changed)

    def on_reverted(*args):
        config.reset(section, option)
        entry.set_text(config.gettext(section, option))

    revert = Gtk.Button()
    revert.add(Gtk.Image.new_from_icon_name(
        Icons.DOCUMENT_REVERT, Gtk.IconSize.BUTTON))
    revert.connect("clicked", on_reverted)

    lbl = Gtk.Label(label=label, use_underline=True)
    lbl.set_mnemonic_widget(entry)

    return (lbl, entry, revert)
Exemple #32
0
    def PluginPreferences(klass, win):
        def entry_changed(entry):
            config.set('plugins', 'lastfmsync_username', entry.get_text())

        label = Gtk.Label(label=_("_Username:"******"Account"), child=hbox)
Exemple #33
0
 def _new_widget(self, key, val):
     """
     Creates a Gtk.Entry subclass
     appropriate for a field named `key` with value `val`
     """
     callback = signal = None
     if isinstance(val, bool):
         entry = Gtk.CheckButton()
         callback = self.__toggled_widget
         signal = "toggled"
     elif isinstance(val, int):
         adj = Gtk.Adjustment.new(0, 0, 9999, 1, 10, 0)
         entry = Gtk.SpinButton(adjustment=adj)
         entry.set_numeric(True)
         callback = self.__changed_numeric_widget
     elif "pattern" in key:
         entry = ValidatingEntry(validator=Query.validator)
     else:
         entry = UndoEntry()
     entry.connect(signal or "changed", callback or self.__changed_widget,
                   key)
     return entry
Exemple #34
0
    def PluginPreferences(cls, window):
        def key_changed(entry):
            cls.key_expression = None
            cls.config_set(cls._CFG_KEY_KEY, entry.get_text().strip())

        vb = Gtk.VBox(spacing=10)
        vb.set_border_width(0)
        hbox = Gtk.HBox(spacing=6)
        # TODO: construct a decent validator and use ValidatingEntry
        e = UndoEntry()
        e.set_text(cls.get_key_expression())
        e.connect("changed", key_changed)
        e.set_tooltip_markup(_("Accepts QL tag expressions like "
                "<tt>~artist~title</tt> or <tt>musicbrainz_track_id</tt>"))
        lbl = Gtk.Label(label=_("_Group duplicates by:"))
        lbl.set_mnemonic_widget(e)
        lbl.set_use_underline(True)
        hbox.pack_start(lbl, False, True, 0)
        hbox.pack_start(e, True, True, 0)
        frame = qltk.Frame(label=_("Duplicate Key"), child=hbox)
        vb.pack_start(frame, True, True, 0)

        # Matching Option
        toggles = [
            (cls._CFG_REMOVE_WHITESPACE, _("Remove _Whitespace")),
            (cls._CFG_REMOVE_DIACRITICS, _("Remove _Diacritics")),
            (cls._CFG_REMOVE_PUNCTUATION, _("Remove _Punctuation")),
            (cls._CFG_CASE_INSENSITIVE, _("Case _Insensitive")),
        ]
        vb2 = Gtk.VBox(spacing=6)
        for key, label in toggles:
            ccb = ConfigCheckButton(label, 'plugins', cls._config_key(key))
            ccb.set_active(cls.config_get_bool(key))
            vb2.pack_start(ccb, True, True, 0)

        frame = qltk.Frame(label=_("Matching options"), child=vb2)
        vb.pack_start(frame, False, True, 0)

        vb.show_all()
        return vb
Exemple #35
0
        def build_alternate_search_widget():
            vb2 = Gtk.VBox(spacing=3)

            hb = Gtk.HBox(spacing=6)

            def on_entry_changed(entry, *args):
                self.Conf.alternate_search_url = entry.get_text()

            URL_entry = UndoEntry()
            URL_entry.set_text(self.Conf.alternate_search_url)
            URL_entry.connect("changed", on_entry_changed)

            l1 = ConfigLabel(_("URL:"), URL_entry)

            URL_revert = Gtk.Button()
            URL_revert.add(
                Gtk.Image.new_from_icon_name(Icons.DOCUMENT_REVERT,
                                             Gtk.IconSize.MENU))
            URL_revert.set_tooltip_text(_("Revert to default"))

            connect_obj(URL_revert, "clicked", URL_entry.set_text,
                        DEFAULT_ALTERNATE_SEARCH_URL)

            hb.pack_start(l1, False, True, 0)
            hb.pack_start(URL_entry, True, True, 0)
            hb.pack_start(URL_revert, False, True, 0)

            vb2.pack_start(hb, False, True, 0)

            def on_alternate_search_toggled(button, *args):
                self.Conf.alternate_search_enabled = button.get_active()

            alternate_search_enabled = Gtk.CheckButton(label=_(
                "Search via above URL if the lyrics "
                "couldn't be found in LyricsWikia."),
                                                       use_underline=True)
            alternate_search_enabled.set_active(
                self.Conf.alternate_search_enabled)
            alternate_search_enabled.connect("toggled",
                                             on_alternate_search_toggled)

            vb2.pack_start(alternate_search_enabled, False, True, 0)

            return vb2
Exemple #36
0
    def __init__(self, parent, title, text, okbutton=Gtk.STOCK_OPEN):
        super(GetStringDialog, self).__init__(
            title=title, transient_for=parent, use_header_bar=True)

        self.set_border_width(6)
        self.set_default_size(width=self._WIDTH, height=0)
        self.set_resizable(True)
        self.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
                         okbutton, Gtk.ResponseType.OK)
        self.vbox.set_spacing(6)
        self.set_default_response(Gtk.ResponseType.OK)

        box = Gtk.VBox(spacing=6)
        lab = Gtk.Label(label=text)
        box.set_border_width(6)
        lab.set_line_wrap(True)
        lab.set_justify(Gtk.Justification.CENTER)
        box.pack_start(lab, True, True, 0)

        self._val = UndoEntry()
        box.pack_start(self._val, True, True, 0)

        self.vbox.pack_start(box, True, True, 0)
        self.get_child().show_all()
    def __init__(self, parent):
        if self.is_not_unique():
            return
        super(PreferencesWindow, self).__init__()
        self.set_title(_("Ex Falso Preferences"))
        self.set_border_width(12)
        self.set_resizable(False)
        self.set_transient_for(parent)

        vbox = Gtk.VBox(spacing=6)
        hb = Gtk.HBox(spacing=6)
        e = UndoEntry()
        e.set_text(config.get("editing", "split_on"))
        e.connect('changed', self.__changed, 'editing', 'split_on')
        l = Gtk.Label(label=_("Split _on:"))
        l.set_use_underline(True)
        l.set_mnemonic_widget(e)
        hb.pack_start(l, False, True, 0)
        hb.pack_start(e, True, True, 0)
        cb = ConfigCheckButton(
            _("Show _programmatic tags"),
            'editing',
            'alltags',
            tooltip=_("Access all tags, including machine-generated "
                      "ones e.g. MusicBrainz or Replay Gain tags"))
        cb.set_active(config.getboolean("editing", 'alltags'))
        vbox.pack_start(hb, False, True, 0)
        vbox.pack_start(cb, False, True, 0)
        f = qltk.Frame(_("Tag Editing"), child=vbox)

        close = Gtk.Button(stock=Gtk.STOCK_CLOSE)
        close.connect_object('clicked', lambda x: x.destroy(), self)
        button_box = Gtk.HButtonBox()
        button_box.set_layout(Gtk.ButtonBoxStyle.END)
        button_box.pack_start(close, True, True, 0)

        main_vbox = Gtk.VBox(spacing=12)
        main_vbox.pack_start(f, True, True, 0)
        main_vbox.pack_start(button_box, False, True, 0)
        self.add(main_vbox)

        self.connect_object('destroy', PreferencesWindow.__destroy, self)
        self.get_child().show_all()
Exemple #38
0
    def __init__(self, parent):
        if self.is_not_unique():
            return
        super(PreferencesWindow, self).__init__()
        self.set_title(_("Ex Falso Preferences"))
        self.set_border_width(12)
        self.set_resizable(False)
        self.set_transient_for(parent)

        vbox = Gtk.VBox(spacing=6)
        hb = Gtk.HBox(spacing=6)
        e = UndoEntry()
        e.set_text(config.get("editing", "split_on"))
        e.connect('changed', self.__changed, 'editing', 'split_on')
        l = Gtk.Label(label=_("Split _on:"))
        l.set_use_underline(True)
        l.set_mnemonic_widget(e)
        hb.pack_start(l, False, True, 0)
        hb.pack_start(e, True, True, 0)
        vbox.pack_start(hb, False, True, 0)
        f = qltk.Frame(_("Tag Editing"), child=vbox)

        close = Button(_("_Close"), Icons.WINDOW_CLOSE)
        connect_obj(close, 'clicked', lambda x: x.destroy(), self)
        button_box = Gtk.HButtonBox()
        button_box.set_layout(Gtk.ButtonBoxStyle.END)
        button_box.pack_start(close, True, True, 0)

        main_vbox = Gtk.VBox(spacing=12)
        main_vbox.pack_start(f, True, True, 0)
        self.use_header_bar()
        if not self.has_close_button():
            main_vbox.pack_start(button_box, False, True, 0)
        self.add(main_vbox)

        connect_obj(self, 'destroy', PreferencesWindow.__destroy, self)
        self.get_child().show_all()
Exemple #39
0
    def PluginPreferences(self, *args):
        vbox = Gtk.VBox(spacing=12)

        label = Gtk.Label(label=_("Visualiser executable:"))

        def edited(widget):
            self.executable = widget.get_text()

        entry = UndoEntry()
        entry.connect('changed', edited)
        entry.set_text(self.executable)
        hbox = Gtk.HBox(spacing=6)
        hbox.pack_start(label, False, False, 0)
        hbox.pack_start(entry, True, True, 0)
        vbox.pack_start(hbox, True, True, 0)

        def refresh_clicked(widget):
            self.disabled()
            self.enabled()

        refresh_button = Button(_("Reload"), Icons.VIEW_REFRESH)
        refresh_button.connect('clicked', refresh_clicked)
        vbox.pack_start(refresh_button, False, False, 0)
        return vbox
Exemple #40
0
    def __init__(self, player, debug=False):
        super().__init__(spacing=6)

        e = UndoEntry()
        e.set_tooltip_text(
            _("The GStreamer output pipeline used for "
              "playback. Leave blank for the default pipeline. "
              "In case the pipeline contains a sink, "
              "it will be used instead of the default one."))

        e.set_text(config.get('player', 'gst_pipeline'))

        def changed(entry):
            config.set('player', 'gst_pipeline', entry.get_text())

        e.connect('changed', changed)

        pipe_label = Gtk.Label(label=_('_Output pipeline:'))
        pipe_label.set_use_underline(True)
        pipe_label.set_mnemonic_widget(e)

        apply_button = Button(_("_Apply"))

        def format_buffer(scale, value):
            return _("%.1f seconds") % value

        def scale_changed(scale):
            duration_msec = int(scale.get_value() * 1000)
            player._set_buffer_duration(duration_msec)

        duration = config.getfloat("player", "gst_buffer")
        scale = Gtk.HScale.new(
            Gtk.Adjustment(value=duration, lower=0.2, upper=10))
        scale.set_value_pos(Gtk.PositionType.RIGHT)
        scale.set_show_fill_level(True)
        scale.connect('format-value', format_buffer)
        scale.connect('value-changed', scale_changed)

        buffer_label = Gtk.Label(label=_('_Buffer duration:'))
        buffer_label.set_use_underline(True)
        buffer_label.set_mnemonic_widget(scale)

        def rebuild_pipeline(*args):
            player._rebuild_pipeline()

        apply_button.connect('clicked', rebuild_pipeline)

        gapless_button = ConfigCheckButton(
            _('Disable _gapless playback'),
            "player",
            "gst_disable_gapless",
            populate=True,
            tooltip=_(
                "Disabling gapless playback can avoid track changing problems "
                "with some GStreamer versions"))

        jack_button = ConfigCheckButton(
            _('Use JACK for playback if available'),
            "player",
            "gst_use_jack",
            populate=True,
            tooltip=_(
                "Uses `jackaudiosink` for playbin sink if it can be detected"))
        jack_connect = ConfigCheckButton(
            _('Auto-connect to JACK output devices'),
            "player",
            "gst_jack_auto_connect",
            populate=True,
            tooltip=_("Tells `jackaudiosink` to auto-connect"))

        def _jack_toggled(widget: ConfigCheckButton) -> None:
            jack_connect.set_sensitive(widget.get_active())

        jack_button.connect("clicked", _jack_toggled)
        _jack_toggled(jack_button)
        widgets = [(pipe_label, e, apply_button), (buffer_label, scale, None)]

        table = Gtk.Table(n_rows=len(widgets) + 3, n_columns=3)
        table.set_col_spacings(6)
        table.set_row_spacings(6)
        for i, (left, middle, right) in enumerate(widgets):
            left.set_alignment(0.0, 0.5)
            table.attach(left,
                         0,
                         1,
                         i,
                         i + 1,
                         xoptions=Gtk.AttachOptions.FILL
                         | Gtk.AttachOptions.SHRINK)
            if right:
                table.attach(middle, 1, 2, i, i + 1)
                table.attach(right,
                             2,
                             3,
                             i,
                             i + 1,
                             xoptions=Gtk.AttachOptions.FILL
                             | Gtk.AttachOptions.SHRINK)
            else:
                table.attach(middle, 1, 3, i, i + 1)

        table.attach(gapless_button, 0, 3, 2, 3)
        table.attach(jack_button, 0, 3, 3, 4)
        table.attach(jack_connect, 0, 3, 4, 5)

        self.pack_start(table, True, True, 0)

        if debug:

            def print_bin(player):
                player._print_pipeline()

            b = Button("Print Pipeline", Icons.DIALOG_INFORMATION)
            connect_obj(b, 'clicked', print_bin, player)
            self.pack_start(b, True, True, 0)
Exemple #41
0
    def __init__(self, player, debug=False):
        super(GstPlayerPreferences, self).__init__(spacing=6)

        e = UndoEntry()
        e.set_tooltip_text(_("The GStreamer output pipeline used for "
                "playback. Leave blank for the default pipeline. "
                "In case the pipeline contains a sink, "
                "it will be used instead of the default one."))

        e.set_text(config.get('player', 'gst_pipeline'))

        def changed(entry):
            config.set('player', 'gst_pipeline', entry.get_text())
        e.connect('changed', changed)

        pipe_label = Gtk.Label(label=_('_Output pipeline:'))
        pipe_label.set_use_underline(True)
        pipe_label.set_mnemonic_widget(e)

        apply_button = Gtk.Button(stock=Gtk.STOCK_APPLY)

        def format_buffer(scale, value):
            return _("%.1f seconds") % value

        def scale_changed(scale):
            duration_msec = int(scale.get_value() * 1000)
            player._set_buffer_duration(duration_msec)

        duration = config.getfloat("player", "gst_buffer")
        scale = Gtk.HScale.new(
            Gtk.Adjustment(value=duration, lower=0.2, upper=10))
        scale.set_value_pos(Gtk.PositionType.RIGHT)
        scale.set_show_fill_level(True)
        scale.connect('format-value', format_buffer)
        scale.connect('value-changed', scale_changed)

        buffer_label = Gtk.Label(label=_('_Buffer duration:'))
        buffer_label.set_use_underline(True)
        buffer_label.set_mnemonic_widget(scale)

        def rebuild_pipeline(*args):
            player._rebuild_pipeline()
        apply_button.connect('clicked', rebuild_pipeline)

        gapless_button = ConfigCheckButton(
            _('Disable _gapless playback'),
            "player", "gst_disable_gapless", populate=True)
        gapless_button.set_alignment(0.0, 0.5)
        gapless_button.set_tooltip_text(
            _("Disabling gapless playback can avoid track changing problems "
              "with some GStreamer versions."))

        widgets = [(pipe_label, e, apply_button),
                   (buffer_label, scale, None),
        ]

        table = Gtk.Table(n_rows=len(widgets), n_columns=3)
        table.set_col_spacings(6)
        table.set_row_spacings(6)
        for i, (left, middle, right) in enumerate(widgets):
            left.set_alignment(0.0, 0.5)
            table.attach(left, 0, 1, i, i + 1,
                         xoptions=Gtk.AttachOptions.FILL |
                         Gtk.AttachOptions.SHRINK)
            if right:
                table.attach(middle, 1, 2, i, i + 1)
                table.attach(right, 2, 3, i, i + 1,
                             xoptions=Gtk.AttachOptions.FILL |
                             Gtk.AttachOptions.SHRINK)
            else:
                table.attach(middle, 1, 3, i, i + 1)

        table.attach(gapless_button, 0, 3, 2, 3)

        self.pack_start(table, True, True, 0)

        if debug:
            def print_bin(player):
                player._print_pipeline()

            b = Button("Print Pipeline", Gtk.STOCK_DIALOG_INFO)
            connect_obj(b, 'clicked', print_bin, player)
            self.pack_start(b, True, True, 0)
Exemple #42
0
        def ratings_vbox(self):
            """Returns a new VBox containing all ratings widgets"""
            vb = Gtk.VBox(spacing=6)

            # Default Rating
            model = Gtk.ListStore(float)
            default_combo = Gtk.ComboBox(model=model)
            default_lab = Gtk.Label(label=_("_Default rating:"))
            default_lab.set_use_underline(True)
            default_lab.set_alignment(0, 0.5)

            def draw_rating(column, cell, model, it, data):
                num = model[it][0]
                text = "%0.2f: %s" % (num, util.format_rating(num))
                cell.set_property('text', text)

            def default_rating_changed(combo, model):
                it = combo.get_active_iter()
                if it is None:
                    return
                RATINGS.default = model[it][0]

            def populate_default_rating_model(combo, num):
                model = combo.get_model()
                model.clear()
                deltas = []
                default = RATINGS.default
                precision = RATINGS.precision
                for i in range(0, num + 1):
                    r = i * precision
                    model.append(row=[r])
                    deltas.append((abs(default - r), i))
                active = sorted(deltas)[0][1]
                print_d("Choosing #%d (%.2f), closest to current %.2f"
                        % (active, precision * active, default))
                combo.set_active(active)

            cell = Gtk.CellRendererText()
            default_combo.pack_start(cell, True)
            default_combo.set_cell_data_func(cell, draw_rating, None)
            default_combo.connect('changed', default_rating_changed, model)
            default_lab.set_mnemonic_widget(default_combo)

            def refresh_default_combo(num):
                populate_default_rating_model(default_combo, num)

            # Rating Scale
            model = Gtk.ListStore(int)
            scale_combo = Gtk.ComboBox(model=model)
            scale_lab = Gtk.Label(label=_("Rating _Scale:"))
            scale_lab.set_use_underline(True)
            scale_lab.set_mnemonic_widget(scale_combo)

            cell = Gtk.CellRendererText()
            scale_combo.pack_start(cell, False)
            num = RATINGS.number
            for i in [1, 2, 3, 4, 5, 6, 8, 10]:
                it = model.append(row=[i])
                if i == num:
                    scale_combo.set_active_iter(it)

            def draw_rating_scale(column, cell, model, it, data):
                num_stars = model[it][0]
                text = "%d: %s" % (num_stars, RATINGS.full_symbol * num_stars)
                cell.set_property('text', text)

            def rating_scale_changed(combo, model):
                it = combo.get_active_iter()
                if it is None:
                    return
                RATINGS.number = num = model[it][0]
                refresh_default_combo(num)

            refresh_default_combo(RATINGS.number)
            scale_combo.set_cell_data_func(cell, draw_rating_scale, None)
            scale_combo.connect('changed', rating_scale_changed, model)

            default_align = Gtk.Alignment(xalign=0, xscale=0)
            default_align.add(default_lab)
            default_combo_align = Gtk.Alignment(xalign=0, xscale=0)
            default_combo_align.add(default_combo)
            scale_align = Gtk.Alignment(xalign=0, xscale=0)
            scale_align.add(scale_lab)

            grid = Gtk.Grid(column_spacing=6, row_spacing=6)
            grid.add(scale_align)
            grid.add(scale_combo)
            grid.attach(default_align, 0, 1, 1, 1)
            grid.attach(default_combo_align, 1, 1, 1, 1)
            vb.pack_start(grid, False, False, 6)

            # Bayesian Factor
            bayesian_factor = config.getfloat("settings",
                                              "bayesian_rating_factor", 0.0)
            adj = Gtk.Adjustment.new(bayesian_factor, 0.0, 10.0, 0.5, 0.5, 0.0)
            bayes_spin = Gtk.SpinButton(adjustment=adj, numeric=True)
            bayes_spin.set_digits(1)
            bayes_spin.connect('changed', self.__changed_and_signal_library,
                               'settings', 'bayesian_rating_factor')
            bayes_spin.set_tooltip_text(
                _("Bayesian Average factor (C) for aggregated ratings.\n"
                  "0 means a conventional average, higher values mean that "
                  "albums with few tracks will have less extreme ratings. "
                  "Changing this value triggers a re-calculation for all "
                  "albums."))
            bayes_label = Gtk.Label(label=_("_Bayesian averaging amount:"))
            bayes_label.set_use_underline(True)
            bayes_label.set_mnemonic_widget(bayes_spin)

            # Save Ratings
            hb = Gtk.HBox(spacing=6)
            hb.pack_start(bayes_label, False, True, 0)
            hb.pack_start(bayes_spin, False, True, 0)
            vb.pack_start(hb, True, True, 0)
            cb = CCB(_("Save ratings and play _counts"),
                     "editing", "save_to_songs", populate=True)
            vb.pack_start(cb, True, True, 0)
            hb = Gtk.HBox(spacing=6)
            lab = Gtk.Label(label=_("_Email:"))
            entry = UndoEntry()
            entry.set_tooltip_text(_("Ratings and play counts will be set "
                                     "for this email address"))
            entry.set_text(config.get("editing", "save_email"))
            entry.connect('changed', self.__changed, 'editing', 'save_email')
            hb.pack_start(lab, False, True, 0)
            hb.pack_start(entry, True, True, 0)
            lab.set_mnemonic_widget(entry)
            lab.set_use_underline(True)
            vb.pack_start(hb, True, True, 0)

            return vb
Exemple #43
0
        def __init__(self):
            super(PreferencesWindow.SongList, self).__init__(spacing=12)
            self.set_border_width(12)
            self.title = _("Song List")

            # Behaviour
            vbox = Gtk.VBox(spacing=6)
            c = CCB(_("_Jump to playing song automatically"),
                    'settings', 'jump', populate=True,
                    tooltip=_("When the playing song changes, "
                              "scroll to it in the song list"))
            vbox.pack_start(c, False, True, 0)
            frame = qltk.Frame(_("Behavior"), child=vbox)
            self.pack_start(frame, False, True, 0)

            # Columns
            vbox = Gtk.VBox(spacing=12)
            buttons = {}
            table = Gtk.Table.new(3, 3, True)
            cols = get_columns()

            for i, (k, t) in enumerate(self.PREDEFINED_TAGS):
                x, y = i % 3, i / 3
                buttons[k] = Gtk.CheckButton(label=t, use_underline=True)
                if k in cols:
                    buttons[k].set_active(True)
                    cols.remove(k)
                table.attach(buttons[k], x, x + 1, y, y + 1)
            vbox.pack_start(table, False, True, 0)
            if "~current" in cols:
                cols.remove("~current")
            self.other_cols = cols

            # Other columns
            hbox = Gtk.HBox(spacing=6)
            l = Gtk.Label(label=_("_Others:"), use_underline=True)
            hbox.pack_start(l, False, True, 0)
            self.others = others = UndoEntry()
            others.set_sensitive(False)
            # Stock edit doesn't have ellipsis chars.
            edit_button = Gtk.Button(label=_("_Edit..."), use_underline=True)
            edit_button.connect("clicked", self.__config_cols)
            edit_button.set_tooltip_text(_("Add or remove additional column "
                                           "headers"))
            l.set_mnemonic_widget(edit_button)
            l.set_use_underline(True)
            hbox.pack_start(others, True, True, 0)
            hbox.pack_start(edit_button, False, True, 0)
            vbox.pack_start(hbox, False, True, 0)

            frame = qltk.Frame(_("Visible Columns"), child=vbox)
            self.pack_start(frame, False, True, 0)

            # Column preferences
            tiv = Gtk.CheckButton(label=_("Title includes _version"),
                                  use_underline=True)
            aio = Gtk.CheckButton(label=_("Artist includes all _people"),
                                  use_underline=True)
            aip = Gtk.CheckButton(label=_("Album includes _disc subtitle"),
                                  use_underline=True)
            fip = Gtk.CheckButton(label=_("Filename includes _folder"),
                                  use_underline=True)
            self._toggle_data = [
                (tiv, "title", "~title~version"),
                (aip, "album", "~album~discsubtitle"),
                (fip, "~basename", "~filename"),
                (aio, "artist", "~people")
            ]
            # Turn on the toggles if the toggled version is detected in config
            for (check, off, on) in self._toggle_data:
                if on in cols:
                    buttons[off].set_active(True)
                    check.set_active(True)
                    cols.remove(on)

            # Update text once to exclude ticked columns, munged or not
            others.set_text(", ".join(cols))
            t = Gtk.Table.new(2, 2, True)
            t.attach(tiv, 0, 1, 0, 1)
            t.attach(aip, 0, 1, 1, 2)
            t.attach(aio, 1, 2, 0, 1)
            t.attach(fip, 1, 2, 1, 2)
            frame = qltk.Frame(_("Column Preferences"), child=t)
            self.pack_start(frame, False, True, 0)

            # Apply button
            vbox = Gtk.VBox(spacing=12)
            apply = Gtk.Button(stock=Gtk.STOCK_APPLY)
            apply.set_tooltip_text(_("Apply current configuration to song "
                                     "list, adding new columns to the end"))
            b = Gtk.HButtonBox()
            b.set_layout(Gtk.ButtonBoxStyle.END)
            b.pack_start(apply, True, True, 0)
            vbox.pack_start(b, True, True, 0)
            self.pack_start(vbox, True, True, 0)
            apply.connect('clicked', self.__apply, buttons, tiv, aip, fip,
                          aio)
            # Apply on destroy, else config gets mangled
            self.connect('destroy', self.__apply, buttons, tiv, aip, fip, aio)

            for child in self.get_children():
                child.show_all()
Exemple #44
0
    def PluginPreferences(self, parent):
        outer_vb = Gtk.VBox(spacing=12)
        vb = Gtk.VBox(spacing=12)

        # Playing
        hb = Gtk.HBox(spacing=6)
        entry = UndoEntry()
        entry.set_text(self.config_get(self.CFG_PAT_PLAYING,
                                       self.DEFAULT_PAT))
        entry.connect('changed', self.config_entry_changed,
                      self.CFG_PAT_PLAYING)
        lbl = Gtk.Label(label=_("Playing:"))
        entry.set_tooltip_markup(_("Status text when a song is started. "
                                 "Accepts QL Patterns e.g. %s")
                                 % util.monospace(
                                        util.escape("<~artist~title>")))
        lbl.set_mnemonic_widget(entry)
        hb.pack_start(lbl, False, True, 0)
        hb.pack_start(entry, True, True, 0)
        vb.pack_start(hb, True, True, 0)

        # Paused
        hb = Gtk.HBox(spacing=6)
        entry = UndoEntry()
        entry.set_text(self.config_get(self.CFG_PAT_PAUSED,
                                    self.DEFAULT_PAT_PAUSED))
        entry.connect('changed', self.config_entry_changed,
                      self.CFG_PAT_PAUSED)
        lbl = Gtk.Label(label=_("Paused:"))
        entry.set_tooltip_markup(_("Status text when a song is paused. "
                                   "Accepts QL Patterns e.g. %s")
                                   % util.monospace(
                                        util.escape("<~artist~title>")))
        lbl.set_mnemonic_widget(entry)
        hb.pack_start(lbl, False, True, 0)
        hb.pack_start(entry, True, True, 0)
        vb.pack_start(hb, True, True, 0)

        # No Song
        hb = Gtk.HBox(spacing=6)
        entry = UndoEntry()
        entry.set_text(self.config_get(self.CFG_STATUS_SONGLESS, ""))
        entry.connect('changed', self.config_entry_changed,
                      self.CFG_STATUS_SONGLESS)
        entry.set_tooltip_text(
                _("Plain text for status when there is no current song"))
        lbl = Gtk.Label(label=_("No song:"))
        lbl.set_mnemonic_widget(entry)
        hb.pack_start(lbl, False, True, 0)
        hb.pack_start(entry, True, True, 0)
        vb.pack_start(hb, True, True, 0)

        # Frame
        frame = qltk.Frame(_("Status Patterns"), child=vb)
        outer_vb.pack_start(frame, False, True, 0)

        return outer_vb
Exemple #45
0
        def __init__(self):
            super(PreferencesWindow.Browsers, self).__init__(spacing=12)
            self.set_border_width(12)
            self.title = _("Browsers")

            # Search
            vb = Gtk.VBox(spacing=6)
            hb = Gtk.HBox(spacing=6)
            l = Gtk.Label(label=_("_Global filter:"))
            l.set_use_underline(True)
            e = ValidatingEntry(Query.is_valid_color)
            e.set_text(config.get("browsers", "background"))
            e.connect('changed', self._entry, 'background', 'browsers')
            e.set_tooltip_text(_("Apply this query in addition to all others"))
            l.set_mnemonic_widget(e)
            hb.pack_start(l, False, True, 0)
            hb.pack_start(e, True, True, 0)
            vb.pack_start(hb, False, True, 0)

            # Translators: The heading of the preference group, no action
            f = qltk.Frame(Q_("heading|Search"), child=vb)
            self.pack_start(f, False, True, 0)

            # Ratings
            vb = Gtk.VBox(spacing=6)
            c1 = CCB(_("Confirm _multiple ratings"),
                     'browsers', 'rating_confirm_multiple', populate=True,
                     tooltip=_("Ask for confirmation before changing the "
                               "rating of multiple songs at once"))

            c2 = CCB(_("Enable _one-click ratings"),
                     'browsers', 'rating_click', populate=True,
                     tooltip=_("Enable rating by clicking on the rating "
                               "column in the song list"))

            vbox = Gtk.VBox(spacing=6)
            vbox.pack_start(c1, False, True, 0)
            vbox.pack_start(c2, False, True, 0)
            f = qltk.Frame(_("Ratings"), child=vbox)
            self.pack_start(f, False, True, 0)

            # Album Art
            vb = Gtk.VBox(spacing=6)
            c = CCB(_("_Use rounded corners on thumbnails"),
                    'albumart', 'round', populate=True,
                    tooltip=_("Round the corners of album artwork thumbnail "
                              "images. May require restart to take effect."))
            vb.pack_start(c, False, True, 0)

            # Filename choice algorithm config
            cb = CCB(_("Prefer _embedded art"),
                     'albumart', 'prefer_embedded', populate=True,
                     tooltip=_("Choose to use artwork embedded in the audio "
                               "(where available) over other sources"))
            vb.pack_start(cb, False, True, 0)

            hb = Gtk.HBox(spacing=3)
            cb = CCB(_("_Fixed image filename:"),
                     'albumart', 'force_filename', populate=True,
                     tooltip=_("The single image filename to use if "
                               "selected"))
            hb.pack_start(cb, False, True, 0)

            entry = UndoEntry()
            entry.set_tooltip_text(
                    _("The album art image file to use when forced"))
            entry.set_text(config.get("albumart", "filename"))
            entry.connect('changed', self.__changed_text, 'filename')
            # Disable entry when not forcing
            entry.set_sensitive(cb.get_active())
            cb.connect('toggled', self.__toggled_force_filename, entry)
            hb.pack_start(entry, True, True, 0)
            vb.pack_start(hb, False, True, 0)

            f = qltk.Frame(_("Album Art"), child=vb)
            self.pack_start(f, False, True, 0)

            for child in self.get_children():
                child.show_all()
Exemple #46
0
    def PluginPreferences(cls, parent):
        def value_changed(entry, key):
            if entry.get_property('sensitive'):
                cls.server.config[key] = entry.get_text()
                config.set("plugins", "squeezebox_" + key, entry.get_text())

        vb = Gtk.VBox(spacing=12)
        if not cls.server:
            cls.init_server()
        cfg = cls.server.config

        # Server settings Frame
        cfg_frame = Gtk.Frame(label=_("<b>Squeezebox Server</b>"))
        cfg_frame.set_shadow_type(Gtk.ShadowType.NONE)
        cfg_frame.get_label_widget().set_use_markup(True)
        cfg_frame_align = Gtk.Alignment.new(0, 0, 1, 1)
        cfg_frame_align.set_padding(6, 6, 12, 12)
        cfg_frame.add(cfg_frame_align)

        # Tabulate all settings for neatness
        table = Gtk.Table(n_rows=3, n_columns=2)
        table.set_col_spacings(6)
        table.set_row_spacings(6)
        rows = []

        ve = UndoEntry()
        ve.set_text(cfg["hostname"])
        ve.connect('changed', value_changed, 'server_hostname')
        rows.append((Gtk.Label(label=_("Hostname:")), ve))

        ve = UndoEntry()
        ve.set_width_chars(5)
        ve.set_text(str(cfg["port"]))
        ve.connect('changed', value_changed, 'server_port')
        rows.append((Gtk.Label(label=_("Port:")), ve))

        ve = UndoEntry()
        ve.set_text(cfg["user"])
        ve.connect('changed', value_changed, 'server_user')
        rows.append((Gtk.Label(label=_("Username:"******"password"]))
        ve.connect('changed', value_changed, 'server_password')
        rows.append((Gtk.Label(label=_("Password:"******"library_dir"]))
        ve.set_tooltip_text(_("Library directory the server connects to."))
        ve.connect('changed', value_changed, 'server_library_dir')
        rows.append((Gtk.Label(label=_("Library path:")), ve))

        for (row, (label, entry)) in enumerate(rows):
            label.set_alignment(0.0, 0.5)
            table.attach(label, 0, 1, row, row + 1,
                         xoptions=Gtk.AttachOptions.FILL)
            table.attach(entry, 1, 2, row, row + 1)

        # Add verify button
        button = Gtk.Button(label=_("_Verify settings"), use_underline=True)
        button.set_sensitive(cls.server is not None)
        button.connect('clicked', cls.check_settings)
        table.attach(button, 0, 2, row + 1, row + 2)

        cfg_frame_align.add(table)
        vb.pack_start(cfg_frame, True, True, 0)
        debug = cls.ConfigCheckButton(_("Debug"), "debug")
        vb.pack_start(debug, True, True, 0)
        return vb
Exemple #47
0
        def ratings_vbox(self):
            """Returns a new VBox containing all ratings widgets"""
            vb = Gtk.VBox(spacing=6)

            # Default Rating
            model = Gtk.ListStore(float)
            default_combo = Gtk.ComboBox(model=model)
            default_lab = Gtk.Label(label=_("_Default rating:"))
            default_lab.set_use_underline(True)
            default_lab.set_alignment(0, 0.5)

            def draw_rating(column, cell, model, it, data):
                num = model[it][0]
                text = "%0.2f: %s" % (num, util.format_rating(num))
                cell.set_property('text', text)

            def default_rating_changed(combo, model):
                it = combo.get_active_iter()
                if it is None:
                    return
                RATINGS.default = model[it][0]
                qltk.redraw_all_toplevels()

            def populate_default_rating_model(combo, num):
                model = combo.get_model()
                model.clear()
                deltas = []
                default = RATINGS.default
                precision = RATINGS.precision
                for i in range(0, num + 1):
                    r = i * precision
                    model.append(row=[r])
                    deltas.append((abs(default - r), i))
                active = sorted(deltas)[0][1]
                print_d("Choosing #%d (%.2f), closest to current %.2f"
                        % (active, precision * active, default))
                combo.set_active(active)

            cell = Gtk.CellRendererText()
            default_combo.pack_start(cell, True)
            default_combo.set_cell_data_func(cell, draw_rating, None)
            default_combo.connect('changed', default_rating_changed, model)
            default_lab.set_mnemonic_widget(default_combo)

            def refresh_default_combo(num):
                populate_default_rating_model(default_combo, num)

            # Rating Scale
            model = Gtk.ListStore(int)
            scale_combo = Gtk.ComboBox(model=model)
            scale_lab = Gtk.Label(label=_("Rating _scale:"))
            scale_lab.set_use_underline(True)
            scale_lab.set_mnemonic_widget(scale_combo)

            cell = Gtk.CellRendererText()
            scale_combo.pack_start(cell, False)
            num = RATINGS.number
            for i in [1, 2, 3, 4, 5, 6, 8, 10]:
                it = model.append(row=[i])
                if i == num:
                    scale_combo.set_active_iter(it)

            def draw_rating_scale(column, cell, model, it, data):
                num_stars = model[it][0]
                text = "%d: %s" % (num_stars, RATINGS.full_symbol * num_stars)
                cell.set_property('text', text)

            def rating_scale_changed(combo, model):
                it = combo.get_active_iter()
                if it is None:
                    return
                RATINGS.number = num = model[it][0]
                refresh_default_combo(num)

            refresh_default_combo(RATINGS.number)
            scale_combo.set_cell_data_func(cell, draw_rating_scale, None)
            scale_combo.connect('changed', rating_scale_changed, model)

            default_align = Align(halign=Gtk.Align.START)
            default_align.add(default_lab)
            scale_align = Align(halign=Gtk.Align.START)
            scale_align.add(scale_lab)

            grid = Gtk.Grid(column_spacing=6, row_spacing=6)
            grid.add(scale_align)
            grid.add(scale_combo)
            grid.attach(default_align, 0, 1, 1, 1)
            grid.attach(default_combo, 1, 1, 1, 1)
            vb.pack_start(grid, False, False, 6)

            # Bayesian Factor
            bayesian_factor = config.getfloat("settings",
                                              "bayesian_rating_factor", 0.0)
            adj = Gtk.Adjustment.new(bayesian_factor, 0.0, 10.0, 0.5, 0.5, 0.0)
            bayes_spin = Gtk.SpinButton(adjustment=adj, numeric=True)
            bayes_spin.set_digits(1)
            bayes_spin.connect('changed', self.__changed_and_signal_library,
                               'settings', 'bayesian_rating_factor')
            bayes_spin.set_tooltip_text(
                _("Bayesian Average factor (C) for aggregated ratings.\n"
                  "0 means a conventional average, higher values mean that "
                  "albums with few tracks will have less extreme ratings. "
                  "Changing this value triggers a re-calculation for all "
                  "albums."))
            bayes_label = Gtk.Label(label=_("_Bayesian averaging amount:"))
            bayes_label.set_use_underline(True)
            bayes_label.set_mnemonic_widget(bayes_spin)

            # Save Ratings
            hb = Gtk.HBox(spacing=6)
            hb.pack_start(bayes_label, False, True, 0)
            hb.pack_start(bayes_spin, False, True, 0)
            vb.pack_start(hb, True, True, 0)
            cb = CCB(_("Save ratings and play _counts"),
                     "editing", "save_to_songs", populate=True)
            vb.pack_start(cb, True, True, 0)
            hb = Gtk.HBox(spacing=6)
            lab = Gtk.Label(label=_("_Email:"))
            entry = UndoEntry()
            entry.set_tooltip_text(_("Ratings and play counts will be set "
                                     "for this email address"))
            entry.set_text(config.get("editing", "save_email"))
            entry.connect('changed', self.__changed, 'editing', 'save_email')
            hb.pack_start(lab, False, True, 0)
            hb.pack_start(entry, True, True, 0)
            lab.set_mnemonic_widget(entry)
            lab.set_use_underline(True)
            vb.pack_start(hb, True, True, 0)

            return vb
    def PluginPreferences(self, parent):
        def changed(entry, key):
            if entry.get_property('sensitive'):
                plugin_config.set(key, entry.get_text())

        def combo_changed(widget, urlent):
            service = widget.get_active_text()
            plugin_config.set("service", service)
            urlent.set_sensitive((service not in SERVICES))
            urlent.set_text(config_get_url())

        def check_login(*args):
            queue = QLSubmitQueue()
            queue.changed()
            status = queue.send_handshake(show_dialog=True)
            if status:
                queue.quick_dialog(_("Authentication successful."),
                    Gtk.MessageType.INFO)

        box = Gtk.VBox(spacing=12)

        # first frame
        table = Gtk.Table(n_rows=5, n_columns=2)
        table.props.expand = False
        table.set_col_spacings(6)
        table.set_row_spacings(6)

        labels = []
        label_names = [_("_Service:"), _("_URL:"), _("User_name:"),
            _("_Password:"******"Other…")
        for idx, serv in enumerate(sorted(SERVICES.keys()) + [other_label]):
            service_combo.append_text(serv)
            if cur_service == serv:
                service_combo.set_active(idx)
        if service_combo.get_active() == -1:
            service_combo.set_active(0)
        labels[row].set_mnemonic_widget(service_combo)
        row += 1

        # url
        entry = UndoEntry()
        entry.set_text(plugin_config.get('url'))
        entry.connect('changed', changed, 'url')
        service_combo.connect('changed', combo_changed, entry)
        service_combo.emit('changed')
        table.attach(entry, 1, 2, row, row + 1)
        labels[row].set_mnemonic_widget(entry)
        row += 1

        # username
        entry = UndoEntry()
        entry.set_text(plugin_config.get('username'))
        entry.connect('changed', changed, 'username')
        table.attach(entry, 1, 2, row, row + 1)
        labels[row].set_mnemonic_widget(entry)
        row += 1

        # password
        entry = UndoEntry()
        entry.set_text(plugin_config.get('password'))
        entry.set_visibility(False)
        entry.connect('changed', changed, 'password')
        table.attach(entry, 1, 2, row, row + 1)
        labels[row].set_mnemonic_widget(entry)
        row += 1

        # verify data
        button = qltk.Button(_("_Verify account data"),
                             Icons.DIALOG_INFORMATION)
        button.connect('clicked', check_login)
        table.attach(button, 0, 2, 4, 5)

        box.pack_start(qltk.Frame(_("Account"), child=table), True, True, 0)

        # second frame
        table = Gtk.Table(n_rows=4, n_columns=2)
        table.props.expand = False
        table.set_col_spacings(6)
        table.set_row_spacings(6)

        label_names = [_("_Artist pattern:"), _("_Title pattern:"),
            _("Exclude _filter:")]

        labels = []
        for idx, name in enumerate(label_names):
            label = Gtk.Label(label=name)
            label.set_alignment(0.0, 0.5)
            label.set_use_underline(True)
            table.attach(label, 0, 1, idx, idx + 1,
                         xoptions=Gtk.AttachOptions.FILL |
                         Gtk.AttachOptions.SHRINK)
            labels.append(label)

        row = 0
        # artist pattern
        entry = UndoEntry()
        entry.set_text(plugin_config.get('artistpat'))
        entry.connect('changed', changed, 'artistpat')
        table.attach(entry, 1, 2, row, row + 1)
        entry.set_tooltip_text(_("The pattern used to format "
            "the artist name for submission. Leave blank for default."))
        labels[row].set_mnemonic_widget(entry)
        row += 1

        # title pattern
        entry = UndoEntry()
        entry.set_text(plugin_config.get('titlepat'))
        entry.connect('changed', changed, 'titlepat')
        table.attach(entry, 1, 2, row, row + 1)
        entry.set_tooltip_text(_("The pattern used to format "
            "the title for submission. Leave blank for default."))
        labels[row].set_mnemonic_widget(entry)
        row += 1

        # exclude filter
        entry = ValidatingEntry(Query.validator)
        entry.set_text(plugin_config.get('exclude'))
        entry.set_tooltip_text(
                _("Songs matching this filter will not be submitted."))
        entry.connect('changed', changed, 'exclude')
        table.attach(entry, 1, 2, row, row + 1)
        labels[row].set_mnemonic_widget(entry)
        row += 1

        # offline mode
        offline = plugin_config.ConfigCheckButton(
                _("_Offline mode (don't submit anything)"),
                'offline', populate=True)
        table.attach(offline, 0, 2, row, row + 1)

        box.pack_start(qltk.Frame(_("Submission"), child=table), True, True, 0)

        return box
Exemple #49
0
        def __init__(self):
            def create_display_frame():
                vbox = Gtk.VBox(spacing=6)
                model = Gtk.ListStore(str, str)

                def on_changed(combo):
                    it = combo.get_active_iter()
                    if it is None:
                        return
                    DURATION.format = model[it][0]
                    app.window.songlist.info.refresh()
                    app.window.qexpander.refresh()
                    # TODO: refresh info windows ideally too (but see #2019)

                def draw_duration(column, cell, model, it, data):
                    df, example = model[it]
                    cell.set_property('text', example)

                for df in sorted(DurationFormat.values):
                    # 4954s == longest ever CD, FWIW
                    model.append([df, format_time_preferred(4954, df)])
                duration = Gtk.ComboBox(model=model)
                cell = Gtk.CellRendererText()
                duration.pack_start(cell, True)
                duration.set_cell_data_func(cell, draw_duration, None)
                index = sorted(DurationFormat.values).index(DURATION.format)
                duration.set_active(index)
                duration.connect('changed', on_changed)
                hbox = Gtk.HBox(spacing=6)
                label = Gtk.Label(label=_("Duration totals") + ":",
                                  use_underline=True)
                label.set_mnemonic_widget(duration)
                hbox.pack_start(label, False, True, 0)
                hbox.pack_start(duration, False, True, 0)

                vbox.pack_start(hbox, False, True, 0)
                return qltk.Frame(_("Display"), child=vbox)

            def create_search_frame():
                vb = Gtk.VBox(spacing=6)
                hb = Gtk.HBox(spacing=6)
                l = Gtk.Label(label=_("_Global filter:"))
                l.set_use_underline(True)
                e = ValidatingEntry(Query.validator)
                e.set_text(config.get("browsers", "background"))
                e.connect('changed', self._entry, 'background', 'browsers')
                e.set_tooltip_text(
                    _("Apply this query in addition to all others"))
                l.set_mnemonic_widget(e)
                hb.pack_start(l, False, True, 0)
                hb.pack_start(e, True, True, 0)
                vb.pack_start(hb, False, True, 0)
                # Translators: The heading of the preference group, no action
                return qltk.Frame(C_("heading", "Search"), child=vb)

            super(PreferencesWindow.Browsers, self).__init__(spacing=12)
            self.set_border_width(12)
            self.title = _("Browsers")
            self.pack_start(create_search_frame(), False, True, 0)
            self.pack_start(create_display_frame(), False, True, 0)

            # Ratings
            vb = Gtk.VBox(spacing=6)
            c1 = CCB(_("Confirm _multiple ratings"),
                     'browsers', 'rating_confirm_multiple', populate=True,
                     tooltip=_("Ask for confirmation before changing the "
                               "rating of multiple songs at once"))

            c2 = CCB(_("Enable _one-click ratings"),
                     'browsers', 'rating_click', populate=True,
                     tooltip=_("Enable rating by clicking on the rating "
                               "column in the song list"))

            vbox = Gtk.VBox(spacing=6)
            vbox.pack_start(c1, False, True, 0)
            vbox.pack_start(c2, False, True, 0)
            f = qltk.Frame(_("Ratings"), child=vbox)
            self.pack_start(f, False, True, 0)

            vb = Gtk.VBox(spacing=6)

            # Filename choice algorithm config
            cb = CCB(_("Prefer _embedded art"),
                     'albumart', 'prefer_embedded', populate=True,
                     tooltip=_("Choose to use artwork embedded in the audio "
                               "(where available) over other sources"))
            vb.pack_start(cb, False, True, 0)

            hb = Gtk.HBox(spacing=3)
            cb = CCB(_("_Fixed image filename:"),
                     'albumart', 'force_filename', populate=True,
                     tooltip=_("The single image filename to use if "
                               "selected"))
            hb.pack_start(cb, False, True, 0)

            entry = UndoEntry()
            entry.set_tooltip_text(
                    _("The album art image file to use when forced"))
            entry.set_text(config.get("albumart", "filename"))
            entry.connect('changed', self.__changed_text, 'filename')
            # Disable entry when not forcing
            entry.set_sensitive(cb.get_active())
            cb.connect('toggled', self.__toggled_force_filename, entry)
            hb.pack_start(entry, True, True, 0)
            vb.pack_start(hb, False, True, 0)

            f = qltk.Frame(_("Album Art"), child=vb)
            self.pack_start(f, False, True, 0)

            for child in self.get_children():
                child.show_all()
Exemple #50
0
    def __init__(self, parent, plugin_instance):
        GObject.GObject.__init__(self, spacing=12)
        self.plugin_instance = plugin_instance

        # notification text settings
        table = Gtk.Table(n_rows=2, n_columns=3)
        table.set_col_spacings(6)
        table.set_row_spacings(6)

        text_frame = qltk.Frame(_("Notification text"), child=table)

        title_entry = UndoEntry()
        title_entry.set_text(pconfig.gettext("titlepattern"))

        def on_entry_changed(entry, cfgname):
            pconfig.settext(cfgname, entry.get_text())

        title_entry.connect("changed", on_entry_changed, "titlepattern")
        table.attach(title_entry, 1, 2, 0, 1)

        title_label = Gtk.Label(label=_("_Title:"))
        title_label.set_use_underline(True)
        title_label.set_alignment(0, 0.5)
        title_label.set_mnemonic_widget(title_entry)
        table.attach(title_label,
                     0,
                     1,
                     0,
                     1,
                     xoptions=Gtk.AttachOptions.FILL
                     | Gtk.AttachOptions.SHRINK)

        title_revert = Gtk.Button()
        title_revert.add(
            Gtk.Image.new_from_icon_name(Icons.DOCUMENT_REVERT,
                                         Gtk.IconSize.MENU))
        title_revert.set_tooltip_text(_("Revert to default pattern"))
        title_revert.connect(
            "clicked", lambda *x: title_entry.set_text(
                pconfig.defaults.gettext("titlepattern")))
        table.attach(title_revert,
                     2,
                     3,
                     0,
                     1,
                     xoptions=Gtk.AttachOptions.SHRINK)

        body_textbuffer = TextBuffer()
        body_textview = TextView(buffer=body_textbuffer)
        body_textview.set_size_request(-1, 85)
        body_textview.get_buffer().set_text(pconfig.gettext("bodypattern"))

        def on_textbuffer_changed(text_buffer, cfgname):
            start, end = text_buffer.get_bounds()
            text = text_buffer.get_text(start, end, True)
            pconfig.settext(cfgname, text)

        body_textbuffer.connect("changed", on_textbuffer_changed,
                                "bodypattern")
        body_scrollarea = Gtk.ScrolledWindow()
        body_scrollarea.set_policy(Gtk.PolicyType.AUTOMATIC,
                                   Gtk.PolicyType.AUTOMATIC)
        body_scrollarea.set_shadow_type(Gtk.ShadowType.ETCHED_OUT)
        body_scrollarea.add(body_textview)
        table.attach(body_scrollarea, 1, 2, 1, 2)

        body_label = Gtk.Label(label=_("_Body:"))
        body_label.set_padding(0, 3)
        body_label.set_use_underline(True)
        body_label.set_alignment(0, 0)
        body_label.set_mnemonic_widget(body_textview)
        table.attach(body_label, 0, 1, 1, 2, xoptions=Gtk.AttachOptions.SHRINK)

        body_revert = Gtk.Button()
        body_revert.add(
            Gtk.Image.new_from_icon_name(Icons.DOCUMENT_REVERT,
                                         Gtk.IconSize.MENU))
        body_revert.set_tooltip_text(_("Revert to default pattern"))
        body_revert.connect(
            "clicked", lambda *x: body_textbuffer.set_text(
                pconfig.defaults.gettext("bodypattern")))
        table.attach(body_revert,
                     2,
                     3,
                     1,
                     2,
                     xoptions=Gtk.AttachOptions.SHRINK,
                     yoptions=Gtk.AttachOptions.FILL
                     | Gtk.AttachOptions.SHRINK)

        # preview button
        preview_button = qltk.Button(_("_Show notification"), Icons.SYSTEM_RUN)
        preview_button.set_sensitive(app.player.info is not None)
        preview_button.connect("clicked", self.on_preview_button_clicked)
        self.qlplayer_connected_signals = [
            app.player.connect("paused", self.on_player_state_changed,
                               preview_button),
            app.player.connect("unpaused", self.on_player_state_changed,
                               preview_button),
        ]

        table.attach(preview_button,
                     0,
                     3,
                     2,
                     3,
                     xoptions=Gtk.AttachOptions.FILL
                     | Gtk.AttachOptions.SHRINK)

        self.pack_start(text_frame, True, True, 0)

        # notification display settings
        display_box = Gtk.VBox(spacing=12)
        display_frame = qltk.Frame(_("Show notifications"), child=display_box)

        radio_box = Gtk.VBox(spacing=6)
        display_box.pack_start(radio_box, True, True, 0)

        only_user_radio = Gtk.RadioButton(
            label=_("Only on <i>_manual</i> song changes"), use_underline=True)
        only_user_radio.get_child().set_use_markup(True)
        only_user_radio.connect("toggled", self.on_radiobutton_toggled,
                                "show_notifications", "user")
        radio_box.pack_start(only_user_radio, True, True, 0)

        only_auto_radio = Gtk.RadioButton(
            group=only_user_radio,
            label=_("Only on <i>_automatic</i> song changes"),
            use_underline=True)
        only_auto_radio.get_child().set_use_markup(True)
        only_auto_radio.connect("toggled", self.on_radiobutton_toggled,
                                "show_notifications", "auto")
        radio_box.pack_start(only_auto_radio, True, True, 0)

        all_radio = Gtk.RadioButton(group=only_user_radio,
                                    label=_("On <i>a_ll</i> song changes"),
                                    use_underline=True)
        all_radio.get_child().set_use_markup(True)
        all_radio.connect("toggled", self.on_radiobutton_toggled,
                          "show_notifications", "all")
        radio_box.pack_start(all_radio, True, True, 0)

        {
            "user": only_user_radio,
            "auto": only_auto_radio,
            "all": all_radio
        }.get(pconfig.gettext("show_notifications"),
              all_radio).set_active(True)

        focus_check = Gtk.CheckButton(
            label=_("Only when the main window is not _focused"),
            use_underline=True)
        focus_check.set_active(pconfig.getboolean("show_only_when_unfocused"))
        focus_check.connect("toggled", self.on_checkbutton_toggled,
                            "show_only_when_unfocused")
        display_box.pack_start(focus_check, True, True, 0)

        show_next = Gtk.CheckButton(label=_("Show \"_Next\" button"),
                                    use_underline=True)
        show_next.set_active(pconfig.getboolean("show_next_button"))
        show_next.connect("toggled", self.on_checkbutton_toggled,
                          "show_next_button")
        display_box.pack_start(show_next, True, True, 0)

        self.pack_start(display_frame, True, True, 0)

        self.show_all()
        self.connect("destroy", self.on_destroyed)
Exemple #51
0
    def PluginPreferences(self, parent):
        outer_vb = Gtk.VBox(spacing=12)
        vb = Gtk.VBox(spacing=12)

        # Playing
        hb = Gtk.HBox(spacing=6)
        entry = UndoEntry()
        entry.set_text(self.config_get(self.CFG_PAT_PLAYING,
                                       self.DEFAULT_PAT))
        entry.connect('changed', self.config_entry_changed,
                      self.CFG_PAT_PLAYING)
        lbl = Gtk.Label(label=_("Playing:"))
        entry.set_tooltip_markup(_("Status text when a song is started. "
                                 "Accepts QL Patterns e.g. %s")
                                 % util.monospace(
                                        util.escape("<~artist~title>")))
        lbl.set_mnemonic_widget(entry)
        hb.pack_start(lbl, False, True, 0)
        hb.pack_start(entry, True, True, 0)
        vb.pack_start(hb, True, True, 0)

        # Paused
        hb = Gtk.HBox(spacing=6)
        entry = UndoEntry()
        entry.set_text(self.config_get(self.CFG_PAT_PAUSED,
                                    self.DEFAULT_PAT_PAUSED))
        entry.connect('changed', self.config_entry_changed,
                      self.CFG_PAT_PAUSED)
        lbl = Gtk.Label(label=_("Paused:"))
        entry.set_tooltip_markup(_("Status text when a song is paused. "
                                   "Accepts QL Patterns e.g. %s")
                                   % util.monospace(
                                        util.escape("<~artist~title>")))
        lbl.set_mnemonic_widget(entry)
        hb.pack_start(lbl, False, True, 0)
        hb.pack_start(entry, True, True, 0)
        vb.pack_start(hb, True, True, 0)

        # No Song
        hb = Gtk.HBox(spacing=6)
        entry = UndoEntry()
        entry.set_text(self.config_get(self.CFG_STATUS_SONGLESS, ""))
        entry.connect('changed', self.config_entry_changed,
                      self.CFG_STATUS_SONGLESS)
        entry.set_tooltip_text(
                _("Plain text for status when there is no current song"))
        lbl = Gtk.Label(label=_("No song:"))
        lbl.set_mnemonic_widget(entry)
        hb.pack_start(lbl, False, True, 0)
        hb.pack_start(entry, True, True, 0)
        vb.pack_start(hb, True, True, 0)

        # Frame
        frame = qltk.Frame(_("Status Patterns"), child=vb)
        outer_vb.pack_start(frame, False, True, 0)

        return outer_vb
Exemple #52
0
    def PluginPreferences(self, parent):
        table = Gtk.Table(n_rows=2, n_columns=3)
        table.set_col_spacings(6)
        table.set_row_spacings(6)

        label = Gtk.Label(label=_("_Port:"), use_underline=True)
        label.set_alignment(0.0, 0.5)
        table.attach(label, 0, 1, 0, 1, xoptions=Gtk.AttachOptions.FILL | Gtk.AttachOptions.SHRINK)

        entry = UndoEntry()
        entry.set_text(str(get_port_num()))

        def validate_port(entry, text, *args):
            try:
                int(text)
            except ValueError:
                entry.stop_emission("insert-text")

        entry.connect("insert-text", validate_port)

        def port_activate(entry, *args):
            try:
                port_num = int(entry.get_text())
            except ValueError as e:
                print_w(str(e))
            else:
                if get_port_num() != port_num:
                    set_port_num(port_num)
                    self._refresh()

        entry.connect_after("activate", port_activate)
        entry.connect_after("focus-out-event", port_activate)

        table.attach(entry, 1, 2, 0, 1)

        port_revert = Gtk.Button()
        port_revert.add(Gtk.Image.new_from_stock(Gtk.STOCK_REVERT_TO_SAVED, Gtk.IconSize.MENU))

        def port_revert_cb(button, entry):
            entry.set_text(str(DEFAULT_PORT))
            entry.emit("activate")

        port_revert.connect("clicked", port_revert_cb, entry)
        table.attach(port_revert, 2, 3, 0, 1, xoptions=Gtk.AttachOptions.SHRINK)

        label = Gtk.Label(label=_("Local _IP:"), use_underline=True)
        label.set_alignment(0.0, 0.5)
        table.attach(label, 0, 1, 1, 2, xoptions=Gtk.AttachOptions.FILL | Gtk.AttachOptions.SHRINK)

        entry = UndoEntry()
        entry.set_text("...")
        entry.set_editable(False)
        table.attach(entry, 1, 3, 1, 2)

        threading.Thread(target=fill_ip, args=(entry,)).start()

        box = Gtk.VBox(spacing=12)

        clients = Gtk.Label()
        clients.set_padding(6, 6)
        clients.set_markup(
            u"""\
\u2022 <a href="https://play.google.com/store/apps/details?id=com.\
namelessdev.mpdroid">MPDroid 1.06</a> (Android)<small>

</small>\u2022 <a href="http://sonata.berlios.de/">Sonata 1.6</a> (Linux)\
"""
        )
        clients.set_alignment(0, 0)

        box.pack_start(qltk.Frame(_("Connection"), child=table), False, True, 0)
        box.pack_start(qltk.Frame(_("Tested Clients"), child=clients), True, True, 0)
        return box
Exemple #53
0
        def __init__(self):
            super(PreferencesWindow.Tagging, self).__init__(spacing=12)
            self.set_border_width(12)
            self.title = _("Tags")

            vbox = gtk.VBox(spacing=6)

            cb = ConfigCheckButton(_("Auto-save tag changes"),
                                   'editing', 'auto_save_changes',
                                   populate=True)
            cb.set_tooltip_text(_("Save changes to tags without confirmation "
                                  "when editing multiple files"))
            vbox.pack_start(cb, expand=False)

            cb = ConfigCheckButton(_("Show _programmatic tags"),
                                   'editing', 'alltags', populate=True)
            cb.set_tooltip_text(
                    _("Access all tags, including machine-generated ones "
                      "e.g. MusicBrainz or Replay Gain tags"))
            vbox.pack_start(cb, expand=False)

            hb = gtk.HBox(spacing=6)
            e = UndoEntry()
            e.set_text(config.get("editing", "split_on"))
            e.connect('changed', self.__changed, 'editing', 'split_on')
            e.set_tooltip_text(
                    _("A list of separators to use when splitting tag values. "
                      "The list is space-separated"))
            l = gtk.Label(_("Split _on:"))
            l.set_use_underline(True)
            l.set_mnemonic_widget(e)
            hb.pack_start(l, expand=False)
            hb.pack_start(e)
            vbox.pack_start(hb, expand=False)

            vb2 = gtk.VBox(spacing=6)
            cb = ConfigCheckButton(_("Save ratings and play _counts"),
                                   "editing", "save_to_songs", populate=True)
            vb2.pack_start(cb)
            hb = gtk.HBox(spacing=6)
            lab = gtk.Label(_("_Email:"))
            entry = UndoEntry()
            entry.set_tooltip_text(_("Ratings and play counts will be set "
                                     "for this email address"))
            entry.set_text(config.get("editing", "save_email"))
            entry.connect('changed', self.__changed, 'editing', 'save_email')
            hb.pack_start(lab, expand=False)
            hb.pack_start(entry)
            lab.set_mnemonic_widget(entry)
            lab.set_use_underline(True)
            vb2.pack_start(hb)

            f = qltk.Frame(_("Tag Editing"), child=vbox)
            self.pack_start(f, expand=False)

            f = qltk.Frame(_("Ratings"), child=vb2)
            self.pack_start(f, expand=False)

            self.show_all()
Exemple #54
0
        def __init__(self):
            super(PreferencesWindow.Browsers, self).__init__(spacing=12)
            self.set_border_width(12)
            self.title = _("Browsers")

            # Search
            vb = Gtk.VBox(spacing=6)
            hb = Gtk.HBox(spacing=6)
            l = Gtk.Label(label=_("_Global filter:"))
            l.set_use_underline(True)
            e = ValidatingEntry(QueryValidator)
            e.set_text(config.get("browsers", "background"))
            e.connect('changed', self._entry, 'background', 'browsers')
            e.set_tooltip_text(_("Apply this query in addition to all others"))
            l.set_mnemonic_widget(e)
            hb.pack_start(l, False, True, 0)
            hb.pack_start(e, True, True, 0)
            vb.pack_start(hb, False, True, 0)

            # Translators: The heading of the preference group, no action
            f = qltk.Frame(C_("heading", "Search"), child=vb)
            self.pack_start(f, False, True, 0)

            # Ratings
            vb = Gtk.VBox(spacing=6)
            c1 = CCB(_("Confirm _multiple ratings"),
                     'browsers', 'rating_confirm_multiple', populate=True,
                     tooltip=_("Ask for confirmation before changing the "
                               "rating of multiple songs at once"))

            c2 = CCB(_("Enable _one-click ratings"),
                     'browsers', 'rating_click', populate=True,
                     tooltip=_("Enable rating by clicking on the rating "
                               "column in the song list"))

            vbox = Gtk.VBox(spacing=6)
            vbox.pack_start(c1, False, True, 0)
            vbox.pack_start(c2, False, True, 0)
            f = qltk.Frame(_("Ratings"), child=vbox)
            self.pack_start(f, False, True, 0)

            vb = Gtk.VBox(spacing=6)

            # Filename choice algorithm config
            cb = CCB(_("Prefer _embedded art"),
                     'albumart', 'prefer_embedded', populate=True,
                     tooltip=_("Choose to use artwork embedded in the audio "
                               "(where available) over other sources"))
            vb.pack_start(cb, False, True, 0)

            hb = Gtk.HBox(spacing=3)
            cb = CCB(_("_Fixed image filename:"),
                     'albumart', 'force_filename', populate=True,
                     tooltip=_("The single image filename to use if "
                               "selected"))
            hb.pack_start(cb, False, True, 0)

            entry = UndoEntry()
            entry.set_tooltip_text(
                    _("The album art image file to use when forced"))
            entry.set_text(config.get("albumart", "filename"))
            entry.connect('changed', self.__changed_text, 'filename')
            # Disable entry when not forcing
            entry.set_sensitive(cb.get_active())
            cb.connect('toggled', self.__toggled_force_filename, entry)
            hb.pack_start(entry, True, True, 0)
            vb.pack_start(hb, False, True, 0)

            f = qltk.Frame(_("Album Art"), child=vb)
            self.pack_start(f, False, True, 0)

            for child in self.get_children():
                child.show_all()
 def setUp(self):
     self.entry = UndoEntry()
Exemple #56
0
class GetStringDialog(Dialog):
    """Simple dialog to return a string from the user"""
    _WIDTH = 300

    def __init__(self, parent, title, text, okbutton=Gtk.STOCK_OPEN):
        super(GetStringDialog, self).__init__(title=title,
                                              transient_for=parent,
                                              use_header_bar=True)

        self.set_border_width(6)
        self.set_default_size(width=self._WIDTH, height=0)
        self.set_resizable(True)
        self.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, okbutton,
                         Gtk.ResponseType.OK)
        self.vbox.set_spacing(6)
        self.set_default_response(Gtk.ResponseType.OK)

        box = Gtk.VBox(spacing=6)
        lab = Gtk.Label(label=text)
        box.set_border_width(6)
        lab.set_line_wrap(True)
        lab.set_justify(Gtk.Justification.CENTER)
        box.pack_start(lab, True, True, 0)

        self._val = UndoEntry()
        box.pack_start(self._val, True, True, 0)

        self.vbox.pack_start(box, True, True, 0)
        self.get_child().show_all()

    def _verify_clipboard(self, text):
        """Return an altered text or None if the content was invalid."""
        return

    def run(self, text="", clipboard=False, test=False):
        """Shows the dialog and returns the entered value.

        If clipboard is set, the initial value will be pulled from the
        clipboard and can be verified/altered by _verify_clipboard. In case the
        verification fails text will be used as fallback"""

        self.show()
        if clipboard:
            clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
            clip = clipboard.wait_for_text()
            if clip is not None:
                clip = self._verify_clipboard(clip)
            if clip is not None:
                text = clip

        self._val.set_text(text)
        self._val.set_activates_default(True)
        self._val.grab_focus()
        resp = Gtk.ResponseType.OK
        if not test:
            resp = super(GetStringDialog, self).run()
        if resp == Gtk.ResponseType.OK:
            value = self._val.get_text()
        else:
            value = None
        self.destroy()
        return value
Exemple #57
0
    def __init__(self, parent, plugin_instance):
        GObject.GObject.__init__(self, spacing=12)
        self.plugin_instance = plugin_instance

        # notification text settings
        table = Gtk.Table(n_rows=2, n_columns=3)
        table.set_col_spacings(6)
        table.set_row_spacings(6)

        text_frame = qltk.Frame(_("Notification text"), child=table)

        title_entry = UndoEntry()
        title_entry.set_text(pconfig.gettext("titlepattern"))

        def on_entry_changed(entry, cfgname):
            pconfig.settext(cfgname, entry.get_text())

        title_entry.connect("changed", on_entry_changed, "titlepattern")
        table.attach(title_entry, 1, 2, 0, 1)

        title_label = Gtk.Label(label=_("_Title:"))
        title_label.set_use_underline(True)
        title_label.set_alignment(0, 0.5)
        title_label.set_mnemonic_widget(title_entry)
        table.attach(title_label, 0, 1, 0, 1,
                     xoptions=Gtk.AttachOptions.FILL |
                     Gtk.AttachOptions.SHRINK)

        title_revert = Gtk.Button()
        title_revert.add(Gtk.Image.new_from_icon_name(
            Icons.DOCUMENT_REVERT, Gtk.IconSize.MENU))
        title_revert.set_tooltip_text(_("Revert to default pattern"))
        title_revert.connect(
            "clicked", lambda *x: title_entry.set_text(
                pconfig.defaults.gettext("titlepattern")))
        table.attach(title_revert, 2, 3, 0, 1,
                     xoptions=Gtk.AttachOptions.SHRINK)

        body_textbuffer = TextBuffer()
        body_textview = TextView(buffer=body_textbuffer)
        body_textview.set_size_request(-1, 85)
        body_textview.get_buffer().set_text(pconfig.gettext("bodypattern"))

        def on_textbuffer_changed(text_buffer, cfgname):
            start, end = text_buffer.get_bounds()
            text = text_buffer.get_text(start, end, True)
            pconfig.settext(cfgname, text)

        body_textbuffer.connect("changed", on_textbuffer_changed,
                                "bodypattern")
        body_scrollarea = Gtk.ScrolledWindow()
        body_scrollarea.set_policy(Gtk.PolicyType.AUTOMATIC,
                                   Gtk.PolicyType.AUTOMATIC)
        body_scrollarea.set_shadow_type(Gtk.ShadowType.ETCHED_OUT)
        body_scrollarea.add(body_textview)
        table.attach(body_scrollarea, 1, 2, 1, 2)

        body_label = Gtk.Label(label=_("_Body:"))
        body_label.set_padding(0, 3)
        body_label.set_use_underline(True)
        body_label.set_alignment(0, 0)
        body_label.set_mnemonic_widget(body_textview)
        table.attach(body_label, 0, 1, 1, 2, xoptions=Gtk.AttachOptions.SHRINK)

        body_revert = Gtk.Button()
        body_revert.add(Gtk.Image.new_from_icon_name(
                        Icons.DOCUMENT_REVERT, Gtk.IconSize.MENU))
        body_revert.set_tooltip_text(_("Revert to default pattern"))
        body_revert.connect("clicked", lambda *x:
            body_textbuffer.set_text(pconfig.defaults.gettext("bodypattern")))
        table.attach(
            body_revert, 2, 3, 1, 2,
            xoptions=Gtk.AttachOptions.SHRINK,
            yoptions=Gtk.AttachOptions.FILL | Gtk.AttachOptions.SHRINK)

        # preview button
        preview_button = qltk.Button(
            _("_Show notification"), Icons.SYSTEM_RUN)
        preview_button.set_sensitive(app.player.info is not None)
        preview_button.connect("clicked", self.on_preview_button_clicked)
        self.qlplayer_connected_signals = [
            app.player.connect("paused", self.on_player_state_changed,
                             preview_button),
            app.player.connect("unpaused", self.on_player_state_changed,
                             preview_button),
        ]

        table.attach(
            preview_button, 0, 3, 2, 3,
            xoptions=Gtk.AttachOptions.FILL | Gtk.AttachOptions.SHRINK)

        self.pack_start(text_frame, True, True, 0)

        # notification display settings
        display_box = Gtk.VBox(spacing=12)
        display_frame = qltk.Frame(_("Show notifications"), child=display_box)

        radio_box = Gtk.VBox(spacing=6)
        display_box.pack_start(radio_box, True, True, 0)

        only_user_radio = Gtk.RadioButton(label=_(
            "Only on <i>_manual</i> song changes"
        ), use_underline=True)
        only_user_radio.get_child().set_use_markup(True)
        only_user_radio.connect("toggled", self.on_radiobutton_toggled,
                                "show_notifications", "user")
        radio_box.pack_start(only_user_radio, True, True, 0)

        only_auto_radio = Gtk.RadioButton(group=only_user_radio, label=_(
            "Only on <i>_automatic</i> song changes"
        ), use_underline=True)
        only_auto_radio.get_child().set_use_markup(True)
        only_auto_radio.connect("toggled", self.on_radiobutton_toggled,
                                "show_notifications", "auto")
        radio_box.pack_start(only_auto_radio, True, True, 0)

        all_radio = Gtk.RadioButton(group=only_user_radio, label=_(
            "On <i>a_ll</i> song changes"
        ), use_underline=True)
        all_radio.get_child().set_use_markup(True)
        all_radio.connect("toggled", self.on_radiobutton_toggled,
                          "show_notifications", "all")
        radio_box.pack_start(all_radio, True, True, 0)

        {
            "user": only_user_radio,
            "auto": only_auto_radio,
            "all": all_radio
        }.get(pconfig.gettext("show_notifications"),
              all_radio).set_active(True)

        focus_check = Gtk.CheckButton(
            label=_("Only when the main window is not _focused"),
            use_underline=True)
        focus_check.set_active(pconfig.getboolean("show_only_when_unfocused"))
        focus_check.connect("toggled", self.on_checkbutton_toggled,
                            "show_only_when_unfocused")
        display_box.pack_start(focus_check, True, True, 0)

        show_next = Gtk.CheckButton(
            label=_("Show \"_Next\" button"),
            use_underline=True)
        show_next.set_active(pconfig.getboolean("show_next_button"))
        show_next.connect("toggled", self.on_checkbutton_toggled,
                            "show_next_button")
        display_box.pack_start(show_next, True, True, 0)

        self.pack_start(display_frame, True, True, 0)

        self.show_all()
        self.connect("destroy", self.on_destroyed)
Exemple #58
0
class GetStringDialog(Dialog):
    """Simple dialog to return a string from the user"""

    def __init__(self, parent, title, text,
                 button_label=_("_OK"), button_icon=Icons.DOCUMENT_OPEN,
                 tooltip=None):
        super(GetStringDialog, self).__init__(
            title=title, transient_for=parent, use_header_bar=True)

        self.set_border_width(6)
        self.set_resizable(True)
        self.add_button(_("_Cancel"), Gtk.ResponseType.CANCEL)
        self.add_icon_button(button_label, button_icon, Gtk.ResponseType.OK)
        self.vbox.set_spacing(6)
        self.set_default_response(Gtk.ResponseType.OK)

        box = Gtk.VBox(spacing=6)
        lab = Gtk.Label(label=text)
        box.set_border_width(6)
        lab.set_line_wrap(True)
        lab.set_justify(Gtk.Justification.CENTER)
        box.pack_start(lab, True, True, 0)

        self._val = UndoEntry()
        if tooltip:
            self._val.set_tooltip_text(tooltip)
        self._val.set_max_width_chars(50)
        box.pack_start(self._val, True, True, 0)

        self.vbox.pack_start(box, True, True, 0)
        self.get_child().show_all()

    def _verify_clipboard(self, text):
        """Return an altered text or None if the content was invalid."""
        return

    def run(self, text="", clipboard=False, test=False):
        """Shows the dialog and returns the entered value.

        If clipboard is set, the initial value will be pulled from the
        clipboard and can be verified/altered by _verify_clipboard. In case the
        verification fails text will be used as fallback"""

        self.show()
        if clipboard:
            clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
            clip = clipboard.wait_for_text()
            if clip is not None:
                clip = self._verify_clipboard(clip)
            if clip is not None:
                text = clip

        self._val.set_text(text)
        self._val.set_activates_default(True)
        self._val.grab_focus()
        resp = Gtk.ResponseType.OK
        if not test:
            resp = super(GetStringDialog, self).run()
        if resp == Gtk.ResponseType.OK:
            value = self._val.get_text()
        else:
            value = None
        self.destroy()
        return value
Exemple #59
0
    def PluginPreferences(self, parent):
        def changed(entry, key):
            if entry.get_property('sensitive'):
                plugin_config.set(key, entry.get_text())

        def combo_changed(widget, urlent):
            service = widget.get_active_text()
            plugin_config.set("service", service)
            urlent.set_sensitive((service not in SERVICES))
            urlent.set_text(config_get_url())

        def check_login(*args):
            queue = QLSubmitQueue()
            queue.changed()
            status = queue.send_handshake(show_dialog=True)
            if status:
                queue.quick_dialog(_("Authentication successful."),
                                   Gtk.MessageType.INFO)

        box = Gtk.VBox(spacing=12)

        # first frame
        table = Gtk.Table(n_rows=5, n_columns=2)
        table.props.expand = False
        table.set_col_spacings(6)
        table.set_row_spacings(6)

        labels = []
        label_names = [
            _("_Service:"),
            _("_URL:"),
            _("User_name:"),
            _("_Password:"******"Other…")
        for idx, serv in enumerate(sorted(SERVICES.keys()) + [other_label]):
            service_combo.append_text(serv)
            if cur_service == serv:
                service_combo.set_active(idx)
        if service_combo.get_active() == -1:
            service_combo.set_active(0)
        labels[row].set_mnemonic_widget(service_combo)
        row += 1

        # url
        entry = UndoEntry()
        entry.set_text(plugin_config.get('url'))
        entry.connect('changed', changed, 'url')
        service_combo.connect('changed', combo_changed, entry)
        service_combo.emit('changed')
        table.attach(entry, 1, 2, row, row + 1)
        labels[row].set_mnemonic_widget(entry)
        row += 1

        # username
        entry = UndoEntry()
        entry.set_text(plugin_config.get('username'))
        entry.connect('changed', changed, 'username')
        table.attach(entry, 1, 2, row, row + 1)
        labels[row].set_mnemonic_widget(entry)
        row += 1

        # password
        entry = UndoEntry()
        entry.set_text(plugin_config.get('password'))
        entry.set_visibility(False)
        entry.connect('changed', changed, 'password')
        table.attach(entry, 1, 2, row, row + 1)
        labels[row].set_mnemonic_widget(entry)
        row += 1

        # verify data
        button = qltk.Button(_("_Verify account data"),
                             Icons.DIALOG_INFORMATION)
        button.connect('clicked', check_login)
        table.attach(button, 0, 2, 4, 5)

        box.pack_start(qltk.Frame(_("Account"), child=table), True, True, 0)

        # second frame
        table = Gtk.Table(n_rows=4, n_columns=2)
        table.props.expand = False
        table.set_col_spacings(6)
        table.set_row_spacings(6)

        label_names = [
            _("_Artist pattern:"),
            _("_Title pattern:"),
            _("Exclude _filter:")
        ]

        labels = []
        for idx, name in enumerate(label_names):
            label = Gtk.Label(label=name)
            label.set_alignment(0.0, 0.5)
            label.set_use_underline(True)
            table.attach(label,
                         0,
                         1,
                         idx,
                         idx + 1,
                         xoptions=Gtk.AttachOptions.FILL
                         | Gtk.AttachOptions.SHRINK)
            labels.append(label)

        row = 0
        # artist pattern
        entry = UndoEntry()
        entry.set_text(plugin_config.get('artistpat'))
        entry.connect('changed', changed, 'artistpat')
        table.attach(entry, 1, 2, row, row + 1)
        entry.set_tooltip_text(
            _("The pattern used to format "
              "the artist name for submission. Leave blank for default."))
        labels[row].set_mnemonic_widget(entry)
        row += 1

        # title pattern
        entry = UndoEntry()
        entry.set_text(plugin_config.get('titlepat'))
        entry.connect('changed', changed, 'titlepat')
        table.attach(entry, 1, 2, row, row + 1)
        entry.set_tooltip_text(
            _("The pattern used to format "
              "the title for submission. Leave blank for default."))
        labels[row].set_mnemonic_widget(entry)
        row += 1

        # exclude filter
        entry = ValidatingEntry(Query.validator)
        entry.set_text(plugin_config.get('exclude'))
        entry.set_tooltip_text(
            _("Songs matching this filter will not be submitted."))
        entry.connect('changed', changed, 'exclude')
        table.attach(entry, 1, 2, row, row + 1)
        labels[row].set_mnemonic_widget(entry)
        row += 1

        # offline mode
        offline = plugin_config.ConfigCheckButton(
            _("_Offline mode (don't submit anything)"),
            'offline',
            populate=True)
        table.attach(offline, 0, 2, row, row + 1)

        box.pack_start(qltk.Frame(_("Submission"), child=table), True, True, 0)

        return box
class TUndoEntry(TestCase):
    def setUp(self):
        self.entry = UndoEntry()

    def __equal(self, value):
        entry_val = self.entry.get_text().decode("utf-8")
        self.failUnlessEqual(value, entry_val)

    def __insert(self, text, pos):
        self.entry.insert_text(text, position=pos)
        self.entry.set_position(pos + len(text))

    def __delete_left(self, start, end):
        self.entry.set_position(start)
        self.entry.delete_text(start, end)
        self.entry.set_position(start)

    def __delete_right(self, start, end):
        self.entry.set_position(end)
        self.entry.delete_text(start, end)
        self.entry.set_position(start)

    def test_undo_reset(self):
        entry = self.entry
        self.__insert("foo", 0)
        self.__insert("bar", 0)
        entry.reset_undo()
        entry.undo()
        entry.undo()
        entry.undo()
        self.__equal("barfoo")

    def test_undo_norm(self):
        entry = self.entry
        self.__insert("foo", 0)
        entry.undo()
        self.__equal("")
        entry.redo()
        self.__equal("foo")

    def test_undo_space(self):
        entry = self.entry
        self.__insert("f", 0)
        self.__insert(" ", 1)
        self.__insert("o", 2)
        entry.undo()
        self.__equal("f ")
        entry.undo()
        self.__equal("")

    def test_undo_insert_end(self):
        entry = self.entry
        self.__insert("f", 0)
        self.__insert("o", 1)
        self.__insert("o", 2)
        entry.undo()
        self.__equal("")
        entry.redo()
        self.__equal("foo")

    def test_undo_insert_end_2(self):
        entry = self.entry
        self.__insert("f", 0)
        self.__insert("o", 1)
        self.__insert("o", 2)
        self.__insert("bar", 3)
        entry.undo()
        self.__equal("foo")
        entry.redo()
        self.__equal("foobar")

    def test_undo_insert_middle(self):
        entry = self.entry
        self.__insert("foo", 0)
        self.__insert("b", 1)
        self.__equal("fboo")
        entry.undo()
        self.__equal("foo")
        entry.undo()
        self.__equal("")

    def test_undo_delete(self):
        entry = self.entry
        self.__insert("foobar", 0)
        self.__delete_left(3, 4)
        self.__equal("fooar")
        self.__delete_right(1, 3)
        self.__equal("far")
        entry.undo()
        self.__equal("fooar")
        entry.undo()
        self.__equal("foobar")

    def test_undo_delete_space(self):
        entry = self.entry
        self.__insert("foob ar", 0)
        self.__delete_right(6, 7)
        self.__equal("foob a")
        self.__delete_right(5, 6)
        self.__delete_right(4, 5)
        self.__delete_right(3, 4)
        self.__delete_right(2, 3)
        entry.undo()
        self.__equal("foob")

    def tearDown(self):
        self.entry.destroy()