示例#1
0
文件: blafm.py 项目: nkoep/blaplay
    def submit_track(self, player):
        if (not blacfg.getstring("lastfm", "user") or
            not self.get_session_key(create=True)):
            return
        gobject.source_remove(self.__tid)

        # We request track submission on track changes. We don't have to check
        # here if a track passes the ignore settings as this is done when the
        # __uri attribute of the instance is set further down below.
        self.__submit_last_track()

        self.__elapsed = 0
        self.__iterations = 0
        track = player.get_track()
        if not track or player.radio or player.video:
            return

        if self.__passes_ignore(track):
            self.__uri = track.uri
            self.__start_time = int(time.time())
            self.__tid = gobject.timeout_add(1000, self.__query_status)
        else:
            self.__uri = None
            artist, title = track[ARTIST], track[TITLE]
            if artist and title:
                item = "%s - %s" % (artist, title)
            else:
                item = os.path.basename(track.uri)
            print_d("Not submitting \"%s\" to the scrobbler queue" % item)
示例#2
0
        def __init__(self):
            super(BlaPreferences.Keybindings, self).__init__(
                "Global keybindings")

            from blakeys import BlaKeys
            blakeys = BlaKeys()

            actions = [
                ("Play/Pause", "playpause"),
                ("Pause", "pause"),
                ("Stop", "stop"),
                ("Previous track", "previous"),
                ("Next track", "next"),
                ("Volume up", "volup"),
                ("Volume down", "voldown"),
                ("Mute", "mute")
            ]
            bindings = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
            for label, action in actions:
                accel = blacfg.getstring("keybindings", action)
                bindings.append([label, accel])

            treeview = gtk.TreeView()
            treeview.set_property("rules_hint", True)
            treeview.insert_column_with_attributes(
                -1, "Action", gtk.CellRendererText(), text=0)

            def edited(renderer, path, key, mod, *args):
                action = actions[int(path)][-1]
                accel = gtk.accelerator_name(key, mod)
                blakeys.bind(action, accel)
                bindings.set_value(bindings.get_iter(path), 1, accel)
                blacfg.set("keybindings", action, accel)

            def cleared(renderer, path):
                bindings.set_value(bindings.get_iter(path), 1, None)
                action = actions[int(path)][-1]
                blakeys.unbind(blacfg.getstring("keybindings", action))
                blacfg.set("keybindings", action, "")

            renderer = gtk.CellRendererAccel()
            renderer.set_property("editable", True)
            renderer.connect("accel_edited", edited)
            renderer.connect("accel_cleared", cleared)
            treeview.insert_column_with_attributes(
                -1, "Binding", renderer, text=1)
            treeview.set_model(bindings)

            sw = BlaScrolledWindow()
            sw.set_shadow_type(gtk.SHADOW_IN)
            sw.add(treeview)

            self.pack_start(sw, expand=True)
            if not blakeys.can_bind():
                label = gtk.Label()
                label.set_markup(
                    "<b>Note</b>: The <i>keybinder</i> module is not "
                    "available on the system.\nAs a result, the settings on "
                    "this page will have no effect.")
                self.pack_start(label, expand=False, padding=20)
示例#3
0
文件: blakeys.py 项目: nkoep/blaplay
    def __init__(self):
        if not self.can_bind():
            return

        for action in self.__ACTIONS.iterkeys():
            accel = blacfg.getstring("keybindings", action)
            if accel:
                self.bind(action, accel)
示例#4
0
        def __get_filter():
            # This returns a filter function which URIs have to pass in order
            # for them to be considered in the library browser.
            def get_regexp(string):
                tokens = [t.replace(".", "\.").replace("*", ".*")
                          for t in map(str.strip, string.split(","))]
                return re.compile(r"(%s)" % "|".join(tokens))

            restrict_re = get_regexp(
                blacfg.getstring("library", "restrict.to").strip())
            exclude_string = blacfg.getstring("library", "exclude").strip()
            if exclude_string:
                exclude_re = get_regexp(exclude_string)
                def filt(s):
                    return restrict_re.match(s) and not exclude_re.match(s)
            else:
                filt = restrict_re.match
            return filt
示例#5
0
        def __init__(self):
            super(BlaPreferences.LastfmSettings, self).__init__("last.fm")

            self.connect("destroy", self.__save)

            scrobble = gtk.CheckButton("Enable scrobbling")
            scrobble.set_active(blacfg.getboolean("lastfm", "scrobble"))
            scrobble.connect("toggled", self.__scrobble_changed)

            self.__user_entry = gtk.Entry()
            self.__user_entry.set_text(blacfg.getstring("lastfm", "user"))

            self.__ignore_entry = gtk.Entry()
            self.__ignore_entry.set_text(
                    blacfg.getstring("lastfm", "ignore.pattern"))
            self.__ignore_entry.set_tooltip_text("Comma-separated list")

            nowplaying = gtk.CheckButton("Submit \"Listening now\" messages")
            nowplaying.set_active(blacfg.getboolean("lastfm", "now.playing"))
            nowplaying.connect("toggled", self.__nowplaying_changed)

            count = 0
            pairs = [
                ("Username", self.__user_entry),
                ("Ignore pattern", self.__ignore_entry)
            ]

            table = gtk.Table(rows=len(pairs), columns=2, homogeneous=False)
            count = 0
            for label, widget in pairs:
                label = gtk.Label("%s:" % label)
                label.set_alignment(xalign=0.0, yalign=0.5)
                table.attach(label, 0, 1, count, count+1, xoptions=gtk.FILL,
                             xpadding=5)
                table.attach(widget, 1, 2, count, count+1)
                count += 1

            self.pack_start(scrobble, expand=False)
            self.pack_start(table, expand=False)
            self.pack_start(nowplaying, expand=False)
示例#6
0
    def __change_location(self, button, location):
        diag = blaguiutils.BlaDialog(title="Change location")

        # Country list
        country = blacfg.getstring("general", "events.country")
        entry1 = gtk.Entry()
        entry1.set_text(country)

        city = blacfg.getstring("general", "events.city")
        entry2 = gtk.Entry()
        entry2.set_text(city)

        table = gtk.Table(rows=2, columns=2, homogeneous=False)
        table.set_border_width(10)

        items = [("Country", entry1), ("City", entry2)]
        for idx, (label, entry) in enumerate(items):
            entry.connect(
                "activate", lambda *x: diag.response(gtk.RESPONSE_OK))
            label = gtk.Label("%s:" % label)
            label.set_alignment(xalign=0.0, yalign=0.5)
            table.attach(label, idx, idx+1, 0, 1)
            table.attach(entry, idx, idx+1, 1, 2)

        diag.vbox.pack_start(table)
        diag.show_all()
        response = diag.run()

        if response == gtk.RESPONSE_OK:
            country = entry1.get_text()
            city = entry2.get_text()
        diag.destroy()

        if not city:
            location.set_markup("<i>Unspecified</i>")
        else:
            location.set_text(
                ", ".join([city, country] if country else [city]))
        blacfg.set("general", "events.country", country)
        blacfg.set("general", "events.city", city)
示例#7
0
文件: blafm.py 项目: nkoep/blaplay
 def __passes_ignore(self, track):
     tokens = map(
         str.strip,
         filter(None,
                blacfg.getstring("lastfm", "ignore.pattern").split(",")))
     res = [re.compile(t.decode("utf-8"), re.UNICODE | re.IGNORECASE)
            for t in tokens]
     for r in res:
         search = r.search
         for identifier in [ARTIST, TITLE]:
             if search(track[identifier]):
                 return False
     return True
示例#8
0
文件: blafm.py 项目: nkoep/blaplay
def create_popup_menu(track=None):
    user = blacfg.getstring("lastfm", "user")
    if not user:
        return None

    menu = gtk.Menu()

    # User profile
    m = gtk.MenuItem("View your profile")
    m.connect("activate",
              lambda *x: blautil.open_url("http://last.fm/user/%s" % user))
    menu.append(m)

    # Love/Unlove song
    artist = title = track_label = None
    if track is None:
        track = player.get_track()
    try:
        artist = track[ARTIST].replace(" ", "+")
        title =  track[TITLE].replace(" ", "+")
    except TypeError:
        return menu

    limit = 40
    track_label = "%s - %s" % (track[ARTIST], track[TITLE])
    if len(track_label) > limit:
        track_label = "%s..." % track_label[:limit]

    m = gtk.MenuItem("Love song \"%s\"" % track_label)
    m.connect("activate", lambda *x: love_unlove_song(track, unlove=False))
    menu.append(m)

    m = gtk.MenuItem("Unlove song \"%s\"" % track_label)
    m.connect("activate", lambda *x: love_unlove_song(track, unlove=True))
    menu.append(m)

    m = gtk.MenuItem("View song profile of \"%s\"" % track_label)
    m.connect(
        "activate",
        lambda *x: blautil.open_url("http://last.fm/music/%s/_/%s" %
                                    (artist, title)))
    menu.append(m)

    m = gtk.MenuItem("View artist profile of \"%s\"" % track[ARTIST])
    m.connect(
        "activate",
        lambda *x: blautil.open_url("http://last.fm/music/%s" % artist))
    menu.append(m)

    return menu
示例#9
0
文件: blafm.py 项目: nkoep/blaplay
def get_new_releases(recommended=False):
    user = blacfg.getstring("lastfm", "user")
    if not user:
        return []

    url = "%s&method=user.getNewReleases&user=%s&userecs=%d" % (
        blaconst.LASTFM_BASEURL, user, int(recommended))
    url = quote_url(url)
    response = get_response(url, "albums")
    if isinstance(response, ResponseError):
        print_d("Failed to get new releases: %s" % response)
        return None
    response = response.content

    return response["album"]
示例#10
0
    def enable_equalizer(self, state):
        values = None
        if state:
            try:
                values = blacfg.getlistfloat(
                    "equalizer.profiles",
                    blacfg.getstring("player", "equalizer.profile"))
            except:
                pass

        if not values:
            values = [0.0] * blaconst.EQUALIZER_BANDS
        try:
            for band, value in enumerate(values):
                self.__equalizer.set_property("band%d" % band, value)
        except AttributeError:
            pass
示例#11
0
    def __button_press_event(self, event):
        if event.button not in (1, 2, 3):
            return True

        try:
            path = self.__treeview.get_path_at_pos(
                *map(int, [event.x, event.y]))[0]
        except TypeError:
            return False

        model = self.__treeview.get_model()
        release = model[path][0]
        if not isinstance(release, BlaRelease):
            return True
        if event.button in (1, 2):
            if event.type in (gtk.gdk._2BUTTON_PRESS, gtk.gdk._3BUTTON_PRESS):
                return True
            return False

        release_url = release.release_url
        artist_url = release.artist_url

        items = [
            ("View release page", lambda *x: blautil.open_url(release_url)),
            ("View artist profile", lambda *x: blautil.open_url(artist_url))
        ]

        user = blacfg.getstring("lastfm", "user")
        if user:
            artist_history_url = os.path.basename(release.artist_url)
            artist_history_url = (
                "http://www.last.fm/user/%s/library/music/%s" %
                (user, artist_history_url))
            items.append(("View artist history",
                          lambda *x: blautil.open_url(artist_history_url)))

        menu = gtk.Menu()
        for label, callback in items:
            m = gtk.MenuItem(label)
            m.connect("activate", callback)
            menu.append(m)

        menu.show_all()
        menu.popup(None, None, None, event.button, event.time)
        return False
示例#12
0
文件: blafm.py 项目: nkoep/blaplay
    def get_session_key(cls, create=False):
        session_key = blacfg.getstring("lastfm", "sessionkey")
        if session_key:
            return session_key
        if not create or cls.__requested_authorization:
            return None

        if not cls.__token:
            cls.__token = get_request_token()
            if not cls.__token:
                return None
            cls.__request_authorization()
            return None

        # FIXME: on start when there are unsubmitted scrobbles and no session
        #        key but a user name the request auth window will pop up which
        #        causes the statusbar to not update properly

        # TODO: check this more than once

        # We have a token, but it still might be unauthorized, i.e. we can't
        # create a session key from it. If that is the case ignore the
        # situation until the next start of blaplay. In order to avoid sending
        # requests to last.fm all the time we set an escape variable when we
        # encounter an unauthorized token.
        method = "auth.getSession"
        params = [
            ("method", method), ("api_key", blaconst.LASTFM_APIKEY),
            ("token", cls.__token)
        ]
        api_signature = sign_api_call(params)
        string = "&".join(["%s=%s" % p for p in params])
        url = "%s&api_sig=%s&%s" % (
            blaconst.LASTFM_BASEURL, api_signature, string)
        response = get_response(url, "session")
        if isinstance(response, ResponseError):
            session_key = None
            cls.__requested_authorization = True
        else:
            session_key = response.content["key"]
            blacfg.set("lastfm", "sessionkey", session_key)
        return session_key
示例#13
0
文件: blafm.py 项目: nkoep/blaplay
def love_unlove_song(track, unlove=False):
    if (not blacfg.getstring("lastfm", "user") or not track[ARTIST] or
        not track[TITLE]):
        return
    session_key = BlaScrobbler.get_session_key(create=True)
    if not session_key:
        return

    method = "track.unlove" if unlove else "track.love"
    params = [
        ("method", method), ("api_key", blaconst.LASTFM_APIKEY),
        ("artist", track[ARTIST]), ("track", track[TITLE]),
        ("sk", session_key)
    ]

    # Sign API call.
    api_signature = sign_api_call(params)
    params.append(("api_sig", api_signature))
    response = post_message(params)
    if isinstance(response, ResponseError):
        print_d("Failed to love/unlove song: %s" %  response)
示例#14
0
    def __update_models(self):
        def set_sensitive(state):
            self.__hbox.set_sensitive(state)
            self.__treeview.set_sensitive(state)
            return False
        gobject.idle_add(set_sensitive, False)

        with self.__lock:
            images = set()

            active = blacfg.getint("general", "events.filter")
            limit = blacfg.getint("general", "events.limit")
            country = blacfg.getstring("general", "events.country")
            city = blacfg.getstring("general", "events.city")

            events = (blafm.get_events(limit=limit, recommended=True),
                      blafm.get_events(limit=limit, recommended=False,
                                       country=country, city=city))
            if events[0]:
                self.__count_recommended = len(events[0])
            if events[1]:
                self.__count_all = len(events[1])
            items = [
                (blaconst.EVENTS_RECOMMENDED, events[0] or []),
                (blaconst.EVENTS_ALL, events[1] or [])
            ]
            for filt, events in items:
                model = gtk.ListStore(gobject.TYPE_PYOBJECT)
                previous_date = None
                for event in events:
                    event = BlaEvent(event)
                    date = event.date
                    if previous_date != date:
                        previous_date = date
                        model.append(
                            ["\n<span size=\"larger\"><b>%s</b></span>\n" %
                             date])
                    model.append([event])
                    path = event.get_image()
                    if path:
                        images.add(path)
                self.__models[filt] = model

            # Get rid of images for events that don't show up anymore.
            for image in set(blautil.discover(blaconst.EVENTS)).difference(
                images):
                try:
                    os.unlink(image)
                except OSError:
                    pass

            gobject.idle_add(set_sensitive, True)
            # TODO: Only set the model when we verified that we successfully
            #       retrieved event information. This avoids that we delete a
            #       restored model.
            gobject.idle_add(self.__treeview.set_model, self.__models[active])

            if active == blaconst.EVENTS_RECOMMENDED:
                count = self.__count_recommended
            else:
                count = self.__count_all
            gobject.idle_add(
                self.emit, "count_changed", blaconst.VIEW_EVENTS, count)
            return True
示例#15
0
        def __init__(self):
            super(BlaPreferences.LibraryBrowsersSettings, self).__init__(
                "Library/Browsers")

            restrict_string = blacfg.getstring("library", "restrict.to")
            exclude_string = blacfg.getstring("library", "exclude")
            def destroy(*args):
                if (restrict_string !=
                    blacfg.getstring("library", "restrict.to") or
                    exclude_string != blacfg.getstring("library", "exclude")):
                    library.sync()
            self.connect("destroy", destroy)

            hbox = gtk.HBox(spacing=10)

            model = gtk.ListStore(gobject.TYPE_STRING)
            treeview = gtk.TreeView(model)
            treeview.set_property("rules_hint", True)
            r = gtk.CellRendererText()
            treeview.insert_column_with_attributes(
                -1, "Directories", r, text=0)

            sw = BlaScrolledWindow()
            sw.set_shadow_type(gtk.SHADOW_IN)
            sw.set_size_request(-1, 140)
            sw.add(treeview)

            directories = blacfg.getdotliststr("library", "directories")
            for f in directories:
                model.append([f])

            table = gtk.Table(rows=2, columns=1)
            items = [
                ("Add...", self.__add_directory),
                ("Remove", self.__remove_directory),
                ("Rescan all", self.__rescan_all)
            ]
            for idx, (label, callback) in enumerate(items):
                button = gtk.Button(label)
                button.connect("clicked", callback, treeview)
                table.attach(button, 0, 1, idx, idx+1, yoptions=not gtk.EXPAND)

            hbox.pack_start(sw, expand=True)
            hbox.pack_start(table, expand=False, fill=False)

            # Update library checkbutton
            update_library = gtk.CheckButton("Update library on startup")
            update_library.set_active(
                blacfg.getboolean("library", "update.on.startup"))
            update_library.connect(
                "toggled",
                lambda cb: blacfg.setboolean("library", "update.on.startup",
                                             cb.get_active()))

            # The file types
            restrict_to_entry = gtk.Entry()
            restrict_to_entry.set_tooltip_text(
                "Comma-separated list, works on filenames")
            restrict_to_entry.set_text(
                blacfg.getstring("library", "restrict.to"))
            restrict_to_entry.connect(
                "changed",
                lambda entry: blacfg.set("library", "restrict.to",
                                         entry.get_text()))

            exclude_entry = gtk.Entry()
            exclude_entry.set_tooltip_text(
                "Comma-separated list, works on filenames")
            exclude_entry.set_text(
                blacfg.getstring("library", "exclude"))
            exclude_entry.connect(
                "changed",
                lambda entry: blacfg.set("library", "exclude",
                                         entry.get_text()))

            pairs = [
                (blaconst.ACTION_SEND_TO_CURRENT, "send to current playlist"),
                (blaconst.ACTION_ADD_TO_CURRENT, "add to current playlist"),
                (blaconst.ACTION_SEND_TO_NEW, "send to new playlist"),
                (blaconst.ACTION_EXPAND_COLLAPSE, "expand/collapse")
            ]
            # FIXME: Ugly!!
            actions = [""] * 4
            for idx, label in pairs:
                actions[idx] = label
            comboboxes = []

            def cb_changed(combobox, key):
                blacfg.set("library", "%s.action" % key, combobox.get_active())

            for key in ["doubleclick", "middleclick", "return"]:
                cb = gtk.combo_box_new_text()
                map(cb.append_text, actions)
                if key == "return":
                    cb.remove_text(3)
                cb.set_active(blacfg.getint("library", "%s.action" % key))
                cb.connect("changed", cb_changed, key)
                comboboxes.append(cb)

            widgets = [restrict_to_entry, exclude_entry] + comboboxes
            labels = ["Restrict to", "Exclude", "Double-click", "Middle-click",
                      "Return"]

            action_table = gtk.Table(rows=len(labels), columns=2,
                                     homogeneous=False)

            count = 0
            for label, widget in zip(labels, widgets):
                label = gtk.Label("%s:" % label)
                label.set_alignment(xalign=0.0, yalign=0.5)
                action_table.attach(label, 0, 1, count, count+1,
                                    xoptions=gtk.FILL, xpadding=5)
                action_table.attach(widget, 1, 2, count, count+1)
                count += 1

            hbox2 = gtk.HBox(spacing=10)

            draw_tree_lines = gtk.CheckButton("Draw tree lines in browsers")
            draw_tree_lines.set_active(
                blacfg.getboolean("library", "draw.tree.lines"))
            draw_tree_lines.connect("toggled", self.__tree_lines_changed)

            custom_library_browser = gtk.CheckButton(
                "Use custom treeview as library browser")
            custom_library_browser.set_active(
                blacfg.getboolean("library", "custom.browser"))
            custom_library_browser.connect(
                "toggled", self.__custom_library_browser_changed)

            hbox2.pack_start(draw_tree_lines)
            hbox2.pack_start(custom_library_browser)

            self.pack_start(hbox, expand=False)
            self.pack_start(update_library, expand=False)
            self.pack_start(action_table, expand=False)
            self.pack_start(hbox2, expand=False)
示例#16
0
    def __init__(self):
        super(BlaEventBrowser, self).__init__()
        self.set_shadow_type(gtk.SHADOW_NONE)

        vbox = gtk.VBox()
        vbox.set_border_width(10)

        # Heading
        hbox = gtk.HBox()
        items = [
            ("<b><span size=\"xx-large\">Events</span></b>",
             0.0, 0.5, 0),
            ("<b><span size=\"x-small\">powered by</span></b>",
             1.0, 1.0, 5)
        ]
        for markup, xalign, yalign, padding in items:
            label = gtk.Label()
            label.set_markup(markup)
            alignment = gtk.Alignment(xalign, yalign)
            alignment.add(label)
            hbox.pack_start(alignment, expand=True, fill=True, padding=padding)

        image = gtk.image_new_from_file(blaconst.LASTFM_LOGO)
        alignment = gtk.Alignment(1.0, 0.5)
        alignment.add(image)
        hbox.pack_start(alignment, expand=False)
        vbox.pack_start(hbox, expand=False)

        # Location
        hbox_location = gtk.HBox(spacing=5)

        label = gtk.Label()
        label.set_markup("<b>Location:</b>")
        location = gtk.Label()
        country = blacfg.getstring("general", "events.country")
        city = blacfg.getstring("general", "events.city")
        if not city:
            location.set_markup("<i>Unspecified</i>")
        else:
            location.set_text(
                ", ".join([city, country] if country else [city]))

        button = gtk.Button("Change location")
        button.set_focus_on_click(False)
        button.connect(
            "clicked", self.__change_location, location)

        for widget, padding in [(label, 0), (location, 0), (button, 5)]:
            alignment = gtk.Alignment(0.0, 0.5)
            alignment.add(widget)
            hbox_location.pack_start(alignment, expand=False, padding=padding)
        vbox.pack_start(hbox_location, expand=False)

        # Type selector
        self.__hbox = gtk.HBox(spacing=5)
        self.__hbox.set_border_width(10)
        items = [
            ("Recommended events", blaconst.EVENTS_RECOMMENDED),
            ("All events", blaconst.EVENTS_ALL)
        ]
        active = blacfg.getint("general", "events.filter")
        radiobutton = None
        for label, filt in items:
            radiobutton = gtk.RadioButton(radiobutton, label)
            if filt == active:
                radiobutton.set_active(True)
            radiobutton.connect(
                "toggled", self.__filter_changed, filt, hbox_location)
            self.__hbox.pack_start(radiobutton, expand=False)

        button = gtk.Button("Refresh")
        button.set_focus_on_click(False)
        button.connect_object("clicked", BlaEventBrowser.__update_models, self)
        self.__hbox.pack_start(button, expand=False)
        vbox.pack_start(self.__hbox, expand=False)

        hbox = gtk.HBox(spacing=5)
        hbox.pack_start(gtk.Label("Maximum number of results:"), expand=False)
        limit = blacfg.getint("general", "events.limit")
        adjustment = gtk.Adjustment(limit, 1.0, 100.0, 1.0, 5.0, 0.0)
        spinbutton = gtk.SpinButton(adjustment)
        spinbutton.set_numeric(True)
        spinbutton.connect(
            "value_changed",
            lambda sb: blacfg.set("general", "events.limit", sb.get_value()))
        hbox.pack_start(spinbutton, expand=False)
        vbox.pack_start(hbox, expand=False)

        # Events list
        def cell_data_func_pixbuf(column, renderer, model, iterator):
            event = model[iterator][0]
            try:
                renderer.set_property("content", event.image)
            except AttributeError:
                renderer.set_property("content", event)

        def cell_data_func_text(column, renderer, model, iterator):
            event = model[iterator][0]
            # FIXME: Too much code in the try-block.
            try:
                limit = 8
                markup = "<b>%s</b>\n%%s" % event.event_name
                artists = ", ".join(event.artists[:limit])
                if len(event.artists) > limit:
                    artists += ", and more"
                markup %= artists
            except AttributeError:
                markup = ""
            renderer.set_property("markup", markup.replace("&", "&amp;"))

        def cell_data_func_text2(column, renderer, model, iterator):
            event = model[iterator][0]
            try:
                markup = "<b>%s</b>\n%s\n%s" % (
                    event.venue, event.city, event.country)
            except AttributeError:
                markup = ""
            renderer.set_property("markup", markup.replace("&", "&amp;"))

        def cell_data_func_text3(column, renderer, model, iterator):
            event = model[iterator][0]
            markup = ""
            try:
                if event.cancelled:
                    markup = "<span size=\"x-large\"><b>Cancelled</b></span>"
            except AttributeError:
                pass
            renderer.set_property("markup", markup.replace("&", "&amp;"))

        self.__treeview = blaguiutils.BlaTreeViewBase(
            set_button_event_handlers=False)
        self.__treeview.set_rules_hint(True)
        self.__treeview.get_selection().set_mode(gtk.SELECTION_SINGLE)
        self.__treeview.set_headers_visible(False)

        # Image
        r = BlaCellRendererPixbuf()
        column = gtk.TreeViewColumn()
        column.pack_start(r, expand=False)
        column.set_cell_data_func(r, cell_data_func_pixbuf)

        # Title and artists
        r = gtk.CellRendererText()
        r.set_alignment(0.0, 0.0)
        r.set_property("wrap_mode", pango.WRAP_WORD)
        r.set_property("wrap_width", 350)
        column.pack_start(r, expand=False)
        column.set_cell_data_func(r, cell_data_func_text)

        # Location
        r = gtk.CellRendererText()
        r.set_alignment(0.0, 0.0)
        r.set_property("ellipsize", pango.ELLIPSIZE_END)
        column.pack_start(r)
        column.set_cell_data_func(r, cell_data_func_text2)

        # Event cancelled status
        r = gtk.CellRendererText()
        r.set_property("ellipsize", pango.ELLIPSIZE_END)
        column.pack_start(r)
        column.set_cell_data_func(r, cell_data_func_text3)

        self.__treeview.append_column(column)
        self.__treeview.connect("row_activated", self.__row_activated)
        self.__treeview.connect_object(
            "key_press_event", BlaEventBrowser.__key_press_event, self)
        self.__treeview.connect_object(
            "button_press_event", BlaEventBrowser.__button_press_event, self)
        self.__models = map(gtk.ListStore, [gobject.TYPE_PYOBJECT] * 2)
        self.__treeview.set_model(self.__models[active])
        vbox.pack_start(self.__treeview, expand=True, padding=10)

        self.add_with_viewport(vbox)
        self.show_all()
        if active == blaconst.EVENTS_RECOMMENDED:
            hbox_location.set_visible(False)

        blaplay.bla.register_for_cleanup(self)
示例#17
0
 def __set_file_chooser_directory(self, diag):
     directory = blacfg.getstring("general", "filechooser.directory")
     if not directory or not os.path.isdir:
         directory = os.path.expanduser("~")
     diag.set_current_folder(directory)
示例#18
0
 def destroy(*args):
     if (restrict_string !=
         blacfg.getstring("library", "restrict.to") or
         exclude_string != blacfg.getstring("library", "exclude")):
         library.sync()
示例#19
0
        def __init__(self):
            super(BlaPreferences.PlayerSettings, self).__init__("Player")

            logarithmic_volume_scale = gtk.CheckButton(
                "Use logarithmic volume scale")
            logarithmic_volume_scale.set_active(
                blacfg.getboolean("player", "logarithmic.volume.scale"))
            logarithmic_volume_scale.connect(
                "toggled", self.__volume_scale_changed)

            state = blacfg.getboolean("player", "use.equalizer")
            self.__scales = []

            use_equalizer = gtk.CheckButton("Use equalizer")
            use_equalizer.set_active(state)
            use_equalizer.connect("toggled", self.__use_equalizer_changed)

            self.__profiles_box = gtk.combo_box_new_text()
            self.__profiles_box.connect("changed", self.__profile_changed)

            old_profile = blacfg.getstring("player", "equalizer.profile")
            profiles = blacfg.get_keys("equalizer.profiles")

            for idx, profile in enumerate(profiles):
                self.__profiles_box.append_text(profile[0])
                if profile[0] == old_profile:
                    self.__profiles_box.set_active(idx)

            button_table = gtk.Table(rows=1, columns=3, homogeneous=True)
            new_profile_button = gtk.Button("New")
            new_profile_button.connect(
                "clicked", self.__new_profile, self.__profiles_box)
            delete_profile_button = gtk.Button("Delete")
            delete_profile_button.connect(
                "clicked", self.__delete_profile, self.__profiles_box)
            reset_profile_button = gtk.Button("Reset")
            reset_profile_button.connect_object(
                "clicked", BlaPreferences.PlayerSettings.__reset_profile, self)
            button_table.attach(new_profile_button, 0, 1, 0, 1, xpadding=2)
            button_table.attach(delete_profile_button, 1, 2, 0, 1, xpadding=2)
            button_table.attach(reset_profile_button, 2, 3, 0, 1, xpadding=2)

            self.__button_box = gtk.HBox()
            self.__button_box.pack_start(
                gtk.Label("Profiles:"), expand=False, padding=10)
            self.__button_box.pack_start(self.__profiles_box, expand=False)
            self.__button_box.pack_start(
                button_table, expand=False, padding=16)

            table = gtk.Table(rows=2, columns=2, homogeneous=False)
            table.set_row_spacings(2)
            table.attach(logarithmic_volume_scale, 0, 2, 0, 1, xpadding=2)
            table.attach(use_equalizer, 0, 1, 1, 2, xpadding=2)
            table.attach(self.__button_box, 1, 2, 1, 2, xpadding=2)

            self.__scale_box = gtk.HBox(homogeneous=True)

            bands = [29, 59, 119, 237, 474, 947, 1889, 3770, 7523, 15011]
            values = blacfg.getlistfloat("equalizer.profiles", old_profile)
            if not values:
                values = [0] * blaconst.EQUALIZER_BANDS
            for idx, val in enumerate(values):
                box = gtk.VBox(spacing=10)
                scale = gtk.VScale(gtk.Adjustment(val, -24., 12., 0.1))
                scale.set_inverted(True)
                scale.set_update_policy(gtk.UPDATE_DISCONTINUOUS)
                scale.set_value(values[idx])
                scale.set_digits(1)
                scale.set_draw_value(True)
                scale.set_value_pos(gtk.POS_BOTTOM)
                scale.connect("value_changed", self.__equalizer_value_changed,
                              idx, self.__profiles_box)
                scale.connect("format_value", lambda *x: "%.1f dB" % x[-1])
                self.__scales.append(scale)

                label = gtk.Label("%d Hz" % bands[idx])
                box.pack_start(label, expand=False)
                box.pack_start(scale, expand=True)
                self.__scale_box.pack_start(box)

            self.pack_start(table, expand=False, padding=10)
            self.pack_start(self.__scale_box, expand=True)

            self.__use_equalizer_changed(use_equalizer)
示例#20
0
    def __init__(self, parent):
        super(BlaFileBrowser, self).__init__()

        self.__pixbufs = {
            "directory": self.__get_pixbuf(gtk.STOCK_DIRECTORY),
            "file": self.__get_pixbuf(gtk.STOCK_FILE)
        }

        self.__history = BlaFileBrowser.History()

        vbox = gtk.VBox()

        # The toolbar
        table = gtk.Table(rows=1, columns=6, homogeneous=False)

        buttons = [
            (gtk.STOCK_GO_BACK,
             lambda *x: self.__update_from_history(backwards=True)),
            (gtk.STOCK_GO_UP,
             lambda *x: self.__update_directory(
                os.path.dirname(self.__directory))),
            (gtk.STOCK_GO_FORWARD,
             lambda *x: self.__update_from_history(backwards=False)),
            (gtk.STOCK_HOME,
             lambda *x: self.__update_directory(os.path.expanduser("~")))
        ]

        def add_button(icon, callback, idx):
            button = gtk.Button()
            button.add(
                gtk.image_new_from_stock(icon, gtk.ICON_SIZE_SMALL_TOOLBAR))
            button.set_relief(gtk.RELIEF_NONE)
            button.connect("clicked", callback)
            table.attach(button, idx, idx+1, 0, 1, xoptions=not gtk.EXPAND)

        idx = 0
        for icon, callback in buttons:
            add_button(icon, callback, idx)
            idx += 1

        # Add the entry field separately.
        self.__entry = gtk.Entry()
        self.__entry.connect(
            "activate",
            lambda *x: self.__update_directory(self.__entry.get_text()))
        def key_press_event_entry(entry, event):
            if (blagui.is_accel(event, "Escape") or
                blagui.is_accel(event, "<Ctrl>L")):
                self.__entry.select_region(-1, -1)
                self.__treeview.grab_focus()
                return True
            elif (blagui.is_accel(event, "Up") or
                  blagui.is_accel(event, "Down")):
                return True
            return False
        self.__entry.connect("key_press_event", key_press_event_entry)
        table.attach(self.__entry, idx, idx+1, 0, 1)
        idx += 1

        add_button(gtk.STOCK_REFRESH,
                   lambda *x: self.__update_directory(refresh=True), idx)

        vbox.pack_start(table, expand=False, fill=False)

        # The treeview
        self.__treeview = BlaTreeView(parent=parent, multicol=True,
                                      browser_id=blaconst.BROWSER_FILESYSTEM)
        self.__treeview.set_enable_search(True)
        self.__treeview.set_search_column(2)
        self.__treeview.enable_model_drag_source(
            gtk.gdk.BUTTON1_MASK,
            [blagui.DND_TARGETS[blagui.DND_URIS]],
            gtk.gdk.ACTION_COPY)
        self.__treeview.connect_object(
            "drag_data_get", BlaFileBrowser.__drag_data_get, self)
        def key_press_event(treeview, event):
            if blagui.is_accel(event, "<Ctrl>L"):
                self.__entry.grab_focus()
                return True
            return False
        self.__treeview.connect("key_press_event", key_press_event)
        model = gtk.ListStore(*self.__layout)
        self.__filt = model.filter_new()
        self.__filt.set_visible_func(self.__visible_func)
        self.__treeview.set_model(self.__filt)
        self.__directory = blacfg.getstring("general", "filesystem.directory")

        # Name column
        c = gtk.TreeViewColumn("Name")
        c.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
        c.set_resizable(True)
        c.set_expand(True)
        c.set_fixed_width(1)

        r = gtk.CellRendererPixbuf()
        r.set_property("xalign", 0.0)
        c.pack_start(r, expand=False)
        c.add_attribute(r, "pixbuf", 1)

        r = gtk.CellRendererText()
        r.set_property("xalign", 0.0)
        c.pack_start(r)
        # TODO: Use a cdf instead.
        c.add_attribute(r, "text", 2)
        r.set_property("ellipsize", pango.ELLIPSIZE_END)

        self.__treeview.append_column(c)

        # TODO: turn this into nemo's size column (for files, display the size,
        #       for directories the number of items)
        # Last modified column
        c = gtk.TreeViewColumn()
        c.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
        c.set_resizable(True)

        title = "Last modified"
        label = gtk.Label(title)
        width = label.create_pango_layout(title).get_pixel_size()[0]
        c.set_title(title)

        r = gtk.CellRendererText()
        r.set_property("ellipsize", pango.ELLIPSIZE_END)
        c.pack_start(r)
        c.set_cell_data_func(r, self.__last_modified_cb)
        c.set_min_width(width + 12 + r.get_property("xpad"))

        self.__treeview.append_column(c)
        self.__treeview.connect("row_activated", self.__open)
        self.__update_directory(self.__directory)
        self.__treeview.columns_autosize()

        sw = BlaScrolledWindow()
        sw.add(self.__treeview)
        vbox.pack_start(sw, expand=True)

        # The search bar
        hbox = gtk.HBox()
        hbox.pack_start(gtk.Label("Filter:"), expand=False, padding=2)

        self.__filter_entry = gtk.Entry()
        self.__filter_entry.set_icon_from_stock(gtk.ENTRY_ICON_SECONDARY,
                                                gtk.STOCK_CLEAR)
        self.__filter_entry.connect(
            "icon_release", lambda *x: x[0].delete_text(0, -1))
        self.__filter_entry.connect(
            "changed", self.__filter_parameters_changed)
        self.__filter_entry.connect(
            "activate", lambda *x: self.__filt.refilter())
        hbox.pack_start(self.__filter_entry, expand=True)

        button = gtk.Button()
        button.add(
            gtk.image_new_from_stock(gtk.STOCK_FIND,
                                     gtk.ICON_SIZE_SMALL_TOOLBAR))
        button.connect("clicked", lambda *x: self.__filt.refilter())
        hbox.pack_start(button, expand=False)
        vbox.pack_start(hbox, expand=False)

        self.pack_start(vbox)
示例#21
0
 def cleared(renderer, path):
     bindings.set_value(bindings.get_iter(path), 1, None)
     action = actions[int(path)][-1]
     blakeys.unbind(blacfg.getstring("keybindings", action))
     blacfg.set("keybindings", action, "")