def __init__(self): self.__client = Client()
def __init__(self, client=None): super(MainWindow, self).__init__() if client is None: client = Client() def channel_compare_cb(model, a, b): a, = model.get(a, 0) b, = model.get(b, 0) return (cmp(a.title, b.title) or cmp(a.tags, b.tags) or cmp(a.station.title, b.station.title)) channels = gtk.ListStore(object) channels.set_sort_func(0, channel_compare_cb) channels.set_sort_column_id(0, gtk.SORT_ASCENDING) tag_completion = TagsCompletion(client.get_tags()) self.__current_title = None def read_wishlist(): filename = get_config_filename('wishlist') wishlist = [] try: text = file(filename).read().strip() wishlist = text and text.split('\n') or [] except IOError: pass return dict(zip(wishlist, range(len(wishlist)))) self.__wishlist = read_wishlist() def channel_added_cb(client, channel): tree_iter = channels.insert(-1, (channel, )) tag_completion.add(channel.tags) if (channel == client.current_channel or (channel.uri == self.__config.channel_uri and client.current_channel is None)): model = tree_view.get_model() tree_iter = model.convert_child_iter_to_iter(tree_iter) tree_view.get_selection().select_iter(tree_iter) def state_changed_cb(client): if client.is_playing: self.__config.channel_uri = client.current_channel.uri self.__play_button.set_active(True) stream_tags_changed_cb(client) else: self.__pause_button.set_active(True) self.__stream_info.hide() tree_view.queue_draw() def stream_tags_changed_cb(client): self.__current_title = client.stream_tags.get( 'title').strip() or None org = client.stream_tags.get('organization').strip() or None markup = [] if self.__current_title: markup.append('<b>%s</b>' % glib.markup_escape_text(self.__current_title)) if org: markup.append('<small>%s</small>' % glib.markup_escape_text(org)) if markup: self.__stream_info.set_markup(' - '.join(markup)) self.__stream_info.set_tooltip_markup('\n'.join(markup)) self.__stream_info.show() else: self.__stream_info.set_markup('') self.__stream_info.hide() self.__favorite_button.set_sensitive(bool(self.__current_title)) self.__favorite_button.set_active( self.__current_title in self.__wishlist) self.__client = client self.__client.connect('channel-added', channel_added_cb) self.__client.connect('state-changed', state_changed_cb) self.__client.connect('stream-tags-changed', stream_tags_changed_cb) self.__client.wait(Client.STATE_STATIONS_LOADED) self.__filter_timeout = 0 self.__current_tags = [] self.__config = Configuration() def channel_visible_cb(model, iter): channel, = model.get(iter, 0) return channel.matches(self.__current_tags) matching_channels = gtk.TreeModel.filter_new(channels) matching_channels.set_visible_func(channel_visible_cb) self.set_title('WebRadio') self.set_default_size(500, 400) self.set_icon_name('rhythmbox') self.connect('destroy', gtk.main_quit) vbox = gtk.VBox() self.add(vbox) toolbar = gtk.Toolbar() toolbar.set_show_arrow(False) vbox.pack_start(toolbar, expand=False) def play_button_clicked_cb(button): if not button.get_active(): self.__client.pause() return model, tree_iter = tree_view.get_selection().get_selected() channel = None if model and tree_iter: channel, = model.get(tree_iter, 0) if channel is not None: if channel == self.__client.current_channel: self.__client.resume() else: self.__client.play(channel) def favorite_button_clicked_cb(button): if not self.__current_title: return if button.get_active(): self.__wishlist[self.__current_title] = True else: self.__wishlist.pop(self.__current_title, False) wishlist_text = '\n'.join(self.__wishlist.keys()) + '\n' filename = get_config_filename('wishlist') file(filename, 'w').write(wishlist_text) self.__play_button = gtk.RadioToolButton(None, gtk.STOCK_MEDIA_PLAY) self.__play_button.connect('clicked', play_button_clicked_cb) self.__play_button.set_is_important(True) toolbar.insert(self.__play_button, -1) self.__pause_button = gtk.RadioToolButton(self.__play_button, gtk.STOCK_MEDIA_PAUSE) toolbar.insert(self.__pause_button, -1) self.__favorite_button = gtk.ToggleToolButton(gtk.STOCK_ABOUT) self.__favorite_button.connect('clicked', favorite_button_clicked_cb) toolbar.insert(self.__favorite_button, -1) item = gtk.SeparatorToolItem() item.set_expand(True) item.set_draw(False) toolbar.insert(item, -1) item = gtk.ToolItem() toolbar.insert(item, -1) def filter_timeout_cb(entry): self.__current_tags = filter(None, entry.get_text().split(' ')) matching_channels.refilter() self.__filter_timeout = 0 return False def filter_entry_changed_cb(entry, *args): if self.__filter_timeout: glib.source_remove(self.__filter_timeout) self.__filter_timeout = glib.timeout_add(200, filter_timeout_cb, entry) self.__filter_entry = gtk.Entry() self.__filter_entry.set_width_chars(40) self.__filter_entry.set_completion(tag_completion) self.__filter_entry.connect('changed', filter_entry_changed_cb) item.add(self.__filter_entry) scrolled = gtk.ScrolledWindow() scrolled.set_shadow_type(gtk.SHADOW_IN) scrolled.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) vbox.pack_start(scrolled, expand=True) def row_activated_cb(view, path, column): model = view.get_model() channel, = model.get(model.get_iter(path), 0) self.__client.play(channel) tree_view = gtk.TreeView(matching_channels) tree_view.set_headers_visible(False) tree_view.connect('row-activated', row_activated_cb) scrolled.add(tree_view) def adjustment_cb(adjustment): model, tree_iter = tree_view.get_selection().get_selected() if model and tree_iter: path = model.get_path(tree_iter) tree_view.scroll_to_cell(path, None, True, 0.5, 0.5) tree_view.get_vadjustment().connect('changed', adjustment_cb) def icon_cell_data_cb(column, cell, model, iter): channel, = model.get(iter, 0) if channel != self.__client.current_channel: cell.set_property('stock-id', None) elif self.__client.is_playing: cell.set_property('stock-id', gtk.STOCK_MEDIA_PLAY) else: cell.set_property('stock-id', gtk.STOCK_MEDIA_PAUSE) def text_cell_data_cb(column, cell, model, iter): channel, = model.get(iter, 0) title, tags = channel.title, channel.tags tags = [channel.station.id] + list(tags) details = title, ' '.join(tags), channel.station.title details = tuple(map(glib.markup_escape_text, details)) markup = '<b>%s</b>\n<small>%s - %s</small>' % details cell.set_property('markup', markup) cell = gtk.CellRendererPixbuf() cell.set_properties(stock_size=gtk.ICON_SIZE_MENU) column = gtk.TreeViewColumn('Icon', cell) column.set_cell_data_func(cell, icon_cell_data_cb) column.set_expand(False) tree_view.insert_column(column, -1) cell = gtk.CellRendererText() cell.set_properties(ellipsize=pango.ELLIPSIZE_END) column = gtk.TreeViewColumn(None, cell) column.set_cell_data_func(cell, text_cell_data_cb) tree_view.insert_column(column, -1) self.__stream_info = MarqueLabel() self.__stream_info.set_no_show_all(True) vbox.pack_start(self.__stream_info, expand=False) stream_tags_changed_cb(self.__client) state_changed_cb(self.__client) tags = (self.__config.tags or '').strip() self.__filter_entry.grab_focus() self.__filter_entry.set_text(tags + ' ') self.__filter_entry.set_position(-1) for station in self.__client.get_stations(): for channel in station.channels: channel_added_cb(self.__client, channel) self.get_child().show_all()