Example #1
0
    def __update_now_playing(self):
        try:
            track = library[self.__uri]
        except KeyError:
            return
        if (not track[ARTIST] or not track[TITLE] or track[LENGTH] < 30 or
            not blacfg.getboolean("lastfm", "scrobble") or
            not blacfg.getboolean("lastfm", "now.playing")):
            return

        session_key = self.get_session_key()
        if not session_key:
            return

        method = "track.updateNowPlaying"
        params = [
            ("method", method), ("api_key", blaconst.LASTFM_APIKEY),
            ("artist", track[ARTIST]), ("track", track[TITLE]),
            ("sk", session_key)
        ]
        if track[ALBUM]:
            params.append(("album", track[ALBUM]))
        if track[ALBUM_ARTIST]:
            params.append(("album_artist", track[ALBUM_ARTIST]))

        # 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 update nowplaying: %s" % response)
Example #2
0
        def __init__(self):
            super(BlaPreferences.GeneralSettings, self).__init__("General")

            # Tray
            tray_frame = gtk.Frame("Tray")
            tray_table = gtk.Table(rows=2, columns=2, homogeneous=False)
            tray_table.set_border_width(10)
            tray_frame.add(tray_table)

            def tray_changed(checkbutton, key):
                blacfg.setboolean("general", key, checkbutton.get_active())
            options = [
                ("Always display tray icon", "always.show.tray",
                 [0, 1, 0, 1]),
                ("Close to tray", "close.to.tray", [0, 1, 1, 2]),
                ("Show tooltip", "tray.show.tooltip", [1, 2, 0, 1])
            ]
            for label, key, coords in options:
                b = gtk.CheckButton(label)
                b.set_active(blacfg.getboolean("general", key))
                b.connect("toggled", tray_changed, key)
                tray_table.attach(b, *coords)

            # Miscellaneous
            misc_frame = gtk.Frame("Miscellaneous")
            misc_table = gtk.Table(rows=1, columns=2, homogeneous=False)
            misc_table.set_border_width(10)
            misc_frame.add(misc_table)

            cb = gtk.CheckButton("Cursor follows playback")
            cb.set_active(
                blacfg.getboolean("general", "cursor.follows.playback"))
            cb.connect("toggled", self.__follow_playback)
            misc_table.attach(cb, 0, 1, 0, 1)

            cb = gtk.CheckButton(
                "Remove track from queue on double-click or return")
            cb.set_active(blacfg.getboolean(
                "general", "queue.remove.when.activated"))
            cb.connect("toggled", self.__queue_remove)
            misc_table.attach(cb, 1, 2, 0, 1, xpadding=10)

            cb = gtk.CheckButton("Search after timeout")
            cb.set_active(
                blacfg.getboolean("general", "search.after.timeout"))
            cb.connect("toggled", self.__search_after_timeout)
            misc_table.attach(cb, 0, 2, 1, 2)

            self.pack_start(tray_frame, expand=False)
            self.pack_start(misc_frame, expand=False)
Example #3
0
    def __update_title(self):
        track = player.get_track()
        state = player.get_state()

        if state == blaconst.STATE_STOPPED or not track:
            title = "%s %s" % (blaconst.APPNAME, blaconst.VERSION)
            tooltip = "Stopped"
        else:
            if player.radio:
                title = track[TITLE] or "%s - %s" % (
                    blaconst.APPNAME, track["organization"])
            else:
                artist = track[ARTIST]
                title = track[TITLE] or "?"
                if artist and title:
                    title = "%s - %s" % (artist, title)
                else:
                    title = track.basename

            tooltip = title

        self.set_title(title)
        self.__tray.set_tooltip(tooltip)
        if not blacfg.getboolean("general", "tray.show.tooltip"):
            self.__tray.set_has_tooltip(False)
Example #4
0
 def play_item(self, treeview, path, column=None):
     model = treeview.get_model()
     iterator = model.get_iter(path)
     model[iterator][0].play()
     if blacfg.getboolean("general", "queue.remove.when.activated"):
         model.remove(iterator)
         self.update_queue_positions()
Example #5
0
 def __restore_state(self):
     if self.__is_main_window:
         self.__maximized = self.__was_maximized = blacfg.getboolean(
             "general", "maximized")
     if self.__maximized:
         self.maximize()
     else:
         self.unmaximize()
Example #6
0
 def __filter_parameters_changed(self, entry):
     filter_string = self.__filter_entry.get_text()
     if (blacfg.getboolean("general", "search.after.timeout") or
         not filter_string):
         gobject.source_remove(self.__fid)
         def activate():
             self.__filt.refilter()
             return False
         self.__fid = gobject.timeout_add(500, activate)
Example #7
0
    def __button_release_event(self, scale, event):
        if blacfg.getboolean("player", "muted"):
            return True

        if hasattr(event, "button"):
            event.button = 2
        self.__volume = self.__scale.get_value()
        player.set_volume(self.__volume)
        return False
Example #8
0
    def __volume_changed(self, scale):
        state = blacfg.getboolean("player", "muted")

        if state:
            volume = self.__volume
        else:
            volume = scale.get_value()

        blacfg.set("player", "volume", volume / 100.0)
        player.set_volume(scale.get_value())
        self.__update_icon(state)
Example #9
0
 def __query_tooltip(self, *args):
     volume = self.__scale.get_value()
     if blacfg.getboolean("player", "logarithmic.volume.scale"):
         if volume == 0:
             tooltip = "-Inf dB"
         else:
             tooltip = "%.1f dB" % (50 * (volume / 100.0 - 1))
     else:
         tooltip = "%d%%" % volume
     self.__scale.set_tooltip_text(tooltip)
     return False
Example #10
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)
Example #11
0
    def __init__(self):
        # TODO: Add support for scroll-events.

        super(BlaTray, self).__init__()
        self.set_from_icon_name(blaconst.APPNAME)
        self.set_visible(
            blacfg.getboolean("general", "always.show.tray"))
        self.set_tooltip_text("Stopped")
        self.set_has_tooltip(
            blacfg.getboolean("general", "tray.show.tooltip"))

        def config_changed(cfg, section, key):
            if section == "general":
                if key == "always.show.tray":
                    self.set_visible(blacfg.getboolean(section, key))
                elif key == "tray.show.tooltip":
                    self.set_has_tooltip(blacfg.getboolean(section, key))
        blacfg.connect("changed", config_changed)

        def activate(status_icon):
            blaplay.bla.window.toggle_hide()
        self.connect("activate", activate)
        self.connect("popup_menu", self.__tray_menu)
Example #12
0
    def update_treeview_style(self):
        column = self.__treeview.get_column(0)
        column.clear()

        if blacfg.getboolean("library", "custom.browser"):
            renderer = BlaCellRenderer()
        else:
            renderer = gtk.CellRendererText()

        def cdf(column, renderer, model, iterator):
            n_children = model.iter_n_children(iterator)
            if n_children > 0:
                text = "%s (%d)" % (model[iterator][1], n_children)
            else:
                text = model[iterator][1]
            renderer.set_property("text", text)
        column.pack_start(renderer)
        column.set_cell_data_func(renderer, cdf)
Example #13
0
    def set_volume(self, volume):
        volume /= 100.

        if blacfg.getboolean("player", "logarithmic.volume.scale"):
            volume_db = 50 * (volume - 1.0)
            if volume_db == -50:
                volume = 0
            else:
                volume = pow(10, volume_db / 20.0)

        if volume > 1.0:
            volume = 1.0
        elif volume < 0.0:
            volume = 0.0

        try:
            self.__volume.set_property("volume", volume)
        except AttributeError:
            pass
Example #14
0
    def __submit_last_track(self, shutdown=False):
        if self.__uri:
            try:
                track = library[self.__uri]
            except KeyError:
                return
            # According to the last.fm API docs, only tracks longer than 30
            # seconds should be submitted, and only if min(len[s]/2, 240)
            # seconds of the track elapsed. Submission should be performed once
            # a track stops, e.g. on track changes or playback stops (and not
            # in paused states).
            if (track[LENGTH] > 30 and track[ARTIST] and track[TITLE] and
                blacfg.getboolean("lastfm", "scrobble") and
                (self.__elapsed > track[LENGTH] / 2 or self.__elapsed > 240)):
                print_d("Submitting track to scrobbler queue")
                self.__queue.put_nowait((self.__uri, self.__start_time))

        self.__uri = None
        if shutdown:
            print_i("Saving scrobbler queue")
            self.__queue.save()
Example #15
0
    def __init__(self):
        super(VolumeControl, self).__init__(spacing=5)

        self.__volume = int(blacfg.getfloat("player", "volume") * 100)
        state = blacfg.getboolean("player", "muted")
        if not state:
            volume = self.__volume
        else:
            volume = 0.0

        # The mute button
        self.__image = gtk.Image()
        mute = gtk.ToggleButton()
        mute.add(self.__image)
        mute.set_relief(gtk.RELIEF_NONE)
        mute.set_active(state)
        mute.connect("toggled", self.__mute_toggled)

        # The volume scale
        self.__scale = gtk.HScale()
        self.__scale.set_range(0, 100)
        self.__scale.set_increments(-1, -10)
        self.__scale.set_size_request(120, 20)
        self.__scale.set_update_policy(gtk.UPDATE_CONTINUOUS)
        self.__scale.set_draw_value(False)
        self.__scale.set_value(volume)
        self.__scale.connect("value_changed", self.__volume_changed)
        self.__scale.connect("button_press_event", self.__button_press_event)
        self.__scale.connect(
            "button_release_event", self.__button_release_event)
        self.__scale.connect("scroll_event", self.__scroll_event)
        self.__scale.connect("key_press_event", lambda *x: True)
        self.__scale.connect("query_tooltip", self.__query_tooltip)
        self.__scale.set_has_tooltip(True)

        self.__update_icon(state)

        self.pack_start(mute, expand=False)
        self.pack_start(self.__scale, expand=True)
Example #16
0
    def __accept_button_event(self, column, path, event, check_expander):
        # TODO: get rid of this method and implement it only where necessary
        #       (i.e. the library browser)
        if (not blacfg.getboolean("library", "custom.browser") or
            self.__multicol or self.__renderer is None):
            return True

        renderer = column.get_cell_renderers()[self.__renderer]
        model = self.get_model()
        iterator = model.get_iter(path)

        layout = renderer.get_layout(
                self, model.get_value(iterator, self.__text_column))
        width = layout.get_pixel_size()[0]
        cell_area = self.get_cell_area(path, column)
        expander_size = self.style_get_property("expander_size")

        # check vertical position of click event
        if not (event.y >= cell_area.y+PADDING_Y and
                event.y <= cell_area.y+cell_area.height):
            return False

        # check for click on expander and if the row has children
        if (check_expander and
            event.x >= cell_area.x+PADDING_X-expander_size and
            event.x <= cell_area.x+PADDING_X and
            model.iter_has_child(iterator) and
            event.type not in [gtk.gdk._2BUTTON_PRESS,
                               gtk.gdk._3BUTTON_PRESS]):
            return True

        # check for click in the highlighted area
        if (event.x >= cell_area.x+PADDING_X and
            event.x <= cell_area.x+width):
            return True

        return False
Example #17
0
    def __init__(self):
        super(BlaStatusbar, self).__init__(rows=1, columns=3, homogeneous=True)
        type(self).__instance = self

        self.__pb = gtk.ProgressBar()
        self.__pb_label = gtk.Label("Scanning library:")

        self.__track_info = gtk.Label(self.__state_string)

        hbox = gtk.HBox(spacing=10)
        hbox.pack_start(self.__pb_label, expand=False)
        hbox.pack_start(self.__pb, expand=False, fill=True)
        hbox.pack_start(self.__track_info, expand=True)

        self.__view_info = gtk.Label("")

        # Playback order
        self.__order = gtk.combo_box_new_text()
        map(self.__order.append_text, blaconst.ORDER_LITERALS)
        self.__order.set_active(blacfg.getint("general", "play.order"))
        def order_changed(cb):
            order = cb.get_active()
            states = [False] * len(blaconst.ORDER_LITERALS)
            states[order] = True
            ui_manager = blaplay.bla.ui_manager
            for idx, order in enumerate(blaconst.MENU_ORDER):
                action = ui_manager.get_widget(order)
                action.set_active(states[idx])
        self.__order.connect("changed", order_changed)

        table = gtk.Table(rows=1, columns=3)

        table.attach(gtk.Label("Order:"), 0, 1, 0, 1, xpadding=10)
        table.attach(self.__order, 1, 2, 0, 1)
        button = gtk.Button()
        button.set_tooltip_text("Clear queue")
        from blaqueue import queue
        button.connect("clicked", lambda *x: queue.clear())
        queue.connect("count_changed",
                      lambda *x: button.set_sensitive(x[-1] > 0))
        button.add(gtk.image_new_from_stock(gtk.STOCK_CLEAR,
                                            gtk.ICON_SIZE_SMALL_TOOLBAR))
        button.set_relief(gtk.RELIEF_NONE)
        button.set_sensitive(False)
        table.attach(button, 2, 3, 0, 1),

        count = 0
        for widget, xalign in [(hbox, 0.0), (self.__view_info, 0.5),
                               (table, 1.0)]:
            alignment = gtk.Alignment(xalign, 0.5, 0.0, 0.5)
            alignment.add(widget)
            self.attach(alignment, count, count+1, 0, 1)
            count += 1

        player.connect("state_changed", self.__changed)
        library.connect("progress", self.update_progress)

        self.show_all()
        # TODO: group these two
        self.__pb.set_visible(False)
        self.__pb_label.set_visible(False)
        self.set_visible(blacfg.getboolean("general", "statusbar"))
Example #18
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)
Example #19
0
    def __init_pipeline(self):
        if not gstreamer_is_working:
            self.stop()
            from blaplay.blagui import blaguiutils
            blaguiutils.error_dialog(
                "Error", "Failed to construct GStreamer pipeline. Make sure "
                "GStreamer 0.10, its Python bindings, and gst-plugins-base "
                "and gst-plugins-good are installed.")
            return False

        audio_sink = gst.Bin()

        filt = gst.element_factory_make("capsfilter")
        filt.set_property(
            "caps", gst.caps_from_string("audio/x-raw-float,"
                                         "rate=(int)44100,"
                                         "channels=(int)2,"
                                         "width=(int)32,"
                                         "depth=(int)32,"
                                         "endianness=(int)1234"))
        self.__equalizer = gst.element_factory_make("equalizer-10bands")
        tee = gst.element_factory_make("tee")
        queue = gst.element_factory_make("queue")
        queue.set_property("silent", True)

        def new_buffer(sink):
            self.emit("new_buffer", sink.emit("pull_buffer"))
        appsink = gst.element_factory_make("appsink")
        appsink.set_property("drop", True)
        appsink.set_property("sync", True)
        appsink.set_property("emit_signals", True)
        appsink.connect("new_buffer", new_buffer)

        sink = gst.element_factory_make("autoaudiosink")

        self.__volume = gst.element_factory_make("volume")
        elements = [filt, self.__equalizer, tee, queue, appsink,
                    self.__volume, sink]
        map(audio_sink.add, elements)

        pad = elements[0].get_static_pad("sink")
        audio_sink.add_pad(gst.GhostPad("sink", pad))

        gst.element_link_many(filt, self.__equalizer, tee)
        gst.element_link_many(tee, self.__volume, sink)
        gst.element_link_many(tee, queue, appsink)

        video_sink = gst.element_factory_make("xvimagesink")
        video_sink.set_property("force_aspect_ratio", True)

        self.__bin = gst.element_factory_make("playbin2")
        self.__bin.set_property("audio_sink", audio_sink)
        self.__bin.set_property("buffer_duration", 500 * gst.MSECOND)
        self.__bin.set_property("video_sink", video_sink)

        self.__bin.connect("about_to_finish", self.__about_to_finish)
        self.__bin.set_state(gst.STATE_READY)

        bus = self.__bin.get_bus()
        bus.add_signal_watch()
        bus.enable_sync_message_emission()
        self.__message_id = bus.connect("message", self.__message)
        self.__sync_message_id = bus.connect(
            "sync-message::element", self.__sync_message)

        if blacfg.getboolean("player", "muted"):
            volume = 0
        else:
            volume = blacfg.getfloat("player", "volume") * 100
        self.set_volume(volume)

        self.enable_equalizer(blacfg.getboolean("player", "use.equalizer"))

        return True
Example #20
0
 def set_equalizer_value(self, band, value):
     if blacfg.getboolean("player", "use.equalizer"):
         try:
             self.__equalizer.set_property("band%d" % band, value)
         except AttributeError:
             pass
Example #21
0
 def config_changed(cfg, section, key):
     if section == "general":
         if key == "always.show.tray":
             self.set_visible(blacfg.getboolean(section, key))
         elif key == "tray.show.tooltip":
             self.set_has_tooltip(blacfg.getboolean(section, key))
Example #22
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)
Example #23
0
 def __delete_event(self, window, event):
     if blacfg.getboolean("general", "close.to.tray"):
         self.toggle_hide()
         return True
     blaplay.shutdown()
     return False
Example #24
0
 def raise_window(self):
     self.present()
     if not blacfg.getboolean("general", "always.show.tray"):
         self.__tray.set_visible(False)
     self.__visualization.flush_buffers()
Example #25
0
 def update_tree_lines(self):
     self.__treeview.set_enable_tree_lines(
         blacfg.getboolean("library", "draw.tree.lines"))
Example #26
0
 def __button_press_event(self, scale, event):
     if blacfg.getboolean("player", "muted"):
         return True
     if hasattr(event, "button"):
         event.button = 2
     return False
Example #27
0
    def __init__(self):
        super(BlaMainWindow, self).__init__(gtk.WINDOW_TOPLEVEL)
        self.set_resizable(True)
        self.connect("delete_event", self.__delete_event)
        self.enable_tracking(is_main_window=True)

        # Set up the fullscreen window.
        self.__fullscreen_window = gtk.Window()
        def map_(window):
            pass
        self.__fullscreen_window.connect("map", map_)
        self.__fullscreen_window.set_modal(True)
        self.__fullscreen_window.set_transient_for(self)
        self.__fullscreen_window.connect_object(
            "window_state_event", BlaMainWindow.__window_state_event, self)
        def key_press_event(window, event):
            if blagui.is_accel(event, "Escape"):
                window.child.emit("toggle_fullscreen")
            elif blagui.is_accel(event, "space"):
                player.play_pause()
            elif blagui.is_accel(event, "<Ctrl>Q"):
                blaplay.shutdown()
        self.__fullscreen_window.connect_object(
            "key_press_event", key_press_event, self.__fullscreen_window)
        # Realize the fullscreen window. If we don't do this here and reparent
        # the drawingarea to it later that in turn will get unrealized again,
        # causing bad X window errors.
        self.__fullscreen_window.realize()

        # Install a global mouse hook. If connected callbacks don't consume the
        # event by returning True this hook gets called for every widget in the
        # hierarchy that re-emits the event. We therefore cache the event's
        # timestamp to detect and ignore signal re-emissions.
        def button_press_hook(receiver, event):
            event_time = event.get_time()
            if event_time != self.__previous_event_time:
                self.__previous_event_time = event_time
                if event.button == 8:
                    player.previous()
                elif event.button == 9:
                    player.next()
            # This behaves like gobject.{timeout|idle}_add: if the callback
            # doesn't return True it's only called once. It does NOT prevent
            # signal callbacks from executing.
            return True
        self.__previous_event_time = -1
        gobject.add_emission_hook(self, "button_press_event",
                                  button_press_hook)

        # Main menu
        ui_manager = blaplay.bla.ui_manager
        self.add_accel_group(ui_manager.get_accel_group())

        actions = [
            # Menus and submenus
            ("File", None, "_File"),
            ("Edit", None, "_Edit"),
            ("Select", None, "S_elect"),
            ("Selection", None, "Se_lection"),
            ("NewPlaylistFrom", None, "_New playlist from"),
            ("PlayOrder", None, "_Order"),
            ("View", None, "_View"),
            ("Help", None, "_Help"),

            # Menu items
            ("OpenPlaylist", None, "Open playlist...", None, "",
             self.__open_playlist),
            ("AddFiles", None, "Add _files...", None, "",
             lambda *x: self.__add_tracks()),
            ("AddDirectories", None, "_Add directories...", None, "",
             lambda *x: self.__add_tracks(files=False)),
            ("SavePlaylist", None, "_Save playlist...", None, "",
             self.__save_playlist),
            ("Quit", gtk.STOCK_QUIT, "_Quit", "<Ctrl>Q", "",
             lambda *x: blaplay.shutdown()),
            ("Preferences", None, "Pre_ferences...", None, "", BlaPreferences),
            ("About", None, "_About...", None, "", BlaAbout)
        ]
        ui_manager.add_actions(actions)

        toggle_actions = [
            ("Statusbar", None, "St_atusbar", None, "",
             self.__toggle_statusbar, blacfg.getboolean("general",
                                                        "statusbar")),
            ("Visualization", None, "Visualization", None, "",
             self.__toggle_visualization,
             blacfg.getboolean("general", "show.visualization"))
        ]
        ui_manager.add_toggle_actions(toggle_actions)

        radio_actions = [
            ("OrderNormal", None, "_Normal", None, "", blaconst.ORDER_NORMAL),
            ("OrderRepeat", None, "_Repeat", None, "", blaconst.ORDER_REPEAT),
            ("OrderShuffle", None, "_Shuffle", None, "",
             blaconst.ORDER_SHUFFLE)
        ]
        # TODO: Emit "order_changed" signal in the on_change handler instead
        #       and let interested widgets handle this instead.
        ui_manager.add_radio_actions(
            radio_actions, value=blacfg.getint("general", "play.order"),
            on_change=BlaStatusbar.set_order)

        # This is the topmost box that holds all the other components.
        self.add(gtk.VBox())

        # Create instances of the main parts of the GUI.
        self.__toolbar = BlaToolbar()
        self.__browsers = BlaBrowsers()
        self.__visualization = BlaVisualization()
        self.__view = BlaView()
        self.__statusbar = BlaStatusbar()

        # Group browsers and visualization widget.
        self.__vbox_left = gtk.VBox(spacing=blaconst.WIDGET_SPACING)
        self.__vbox_left.pack_start(self.__browsers, expand=True)
        self.__vbox_left.pack_start(self.__visualization, expand=False)
        self.__vbox_left.show()

        # Pack the browser + view-widget into a gtk.HPane instance.
        hpane = gtk.HPaned()
        hpane.pack1(self.__vbox_left, resize=False, shrink=False)
        hpane.pack2(self.__view, resize=True, shrink=True)
        hpane.show()

        # Restore pane positions.
        def notify(pane, propspec, key):
            blacfg.set("general", key, str(pane.get_position()))
        for pane, side in [(hpane, "left"), (self.__view, "right")]:
            key = "pane.pos.%s" % side
            try:
                pane.set_position(blacfg.getint("general", key))
            except TypeError:
                pass
            pane.connect("notify", notify, key)

        # Create a vbox hpane and the statusbar. This allows for setting a
        # border around those items which excludes the menubar and the toolbar.
        vbox = gtk.VBox(spacing=blaconst.BORDER_PADDING)
        vbox.set_border_width(blaconst.BORDER_PADDING)
        vbox.pack_start(hpane)
        vbox.pack_start(self.__statusbar, expand=False)
        vbox.show()

        self.child.pack_start(ui_manager.get_widget("/Menu"), expand=False)
        self.child.pack_start(self.__toolbar, expand=False)
        self.child.pack_start(vbox)
        self.child.show()

        self.__tray = BlaTray()

        def update_title(*args):
            self.__update_title()
        player.connect("state_changed", update_title)
        library.connect("library_updated", update_title)
        self.__update_title()
Example #28
0
 def __scroll_event(self, scale, event):
     if blacfg.getboolean("player", "muted"):
         return True
Example #29
0
 def startup_complete(*args):
     self.set_visible(
         blacfg.getboolean("general", "show.visualization"))