Beispiel #1
0
    def insertDir(self, trackdir, target=None, drop_mode=None, highlight=False):
        '''
        Insert a directory recursively, return the iter of the first
        added element
        '''
        model = self.tree.store
        if trackdir.flat:
            new = target
        else:
            string = trackdir.dirname.replace('_', ' ')
            string = tools.htmlEscape(string)
            source_row = (icons.mediaDirMenuIcon(), string, None)

            new = self.tree.insert(target, source_row, drop_mode)
            drop_mode = gtk.TREE_VIEW_DROP_INTO_OR_AFTER
            if highlight:
                self.tree.select(new)

        dest = new
        for index, subdir in enumerate(trackdir.subdirs):
            drop = drop_mode if index == 0 else gtk.TREE_VIEW_DROP_AFTER
            dest = self.insertDir(subdir, dest, drop, highlight)

        dest = new
        for index, track in enumerate(trackdir.tracks):
            drop = drop_mode if index == 0 else gtk.TREE_VIEW_DROP_AFTER
            highlight &= trackdir.flat
            dest = self.insertTrack(track, dest, drop, highlight)

        if not trackdir.flat:
            # Open albums on the first layer
            if target is None or model.iter_depth(new) == 0:
                self.tree.expand(new)

        return new
Beispiel #2
0
    def insertDir(self, trackdir, target=None, drop_mode=None, highlight=False):
        '''
        Insert a directory recursively, return the iter of the first
        added element
        '''
        model = self.tree.store
        if trackdir.flat:
            new = target
        else:
            string = trackdir.dirname.replace('_', ' ')
            string = tools.htmlEscape(string)
            source_row = (icons.mediaDirMenuIcon(), string, None)

            new = self.tree.insert(target, source_row, drop_mode)
            drop_mode = Gtk.TreeViewDropPosition.INTO_OR_AFTER
            if highlight:
                self.tree.select(new)

        dest = new
        for index, subdir in enumerate(trackdir.subdirs):
            drop = drop_mode if index == 0 else Gtk.TreeViewDropPosition.AFTER
            dest = self.insertDir(subdir, dest, drop, highlight)

        dest = new
        for index, track in enumerate(trackdir.tracks):
            drop = drop_mode if index == 0 else Gtk.TreeViewDropPosition.AFTER
            highlight &= trackdir.flat
            dest = self.insertTrack(track, dest, drop, highlight)

        if not trackdir.flat:
            # Open albums on the first layer
            if target is None or model.iter_depth(new) == 0:
                self.tree.expand(new)

        return new
Beispiel #3
0
    def set_track_playing(self, iter, playing):
        if not iter:
            return
        track = self.tree.getTrack(iter)
        if not track:
            return

        for parent in self.tree.get_all_parents(iter):
            parent_label = self.tree.getLabel(parent)
            parent_label = tools.htmlUnescape(parent_label)
            is_bold = parent_label.startswith('<b>') and parent_label.endswith('</b>')
            if playing and not is_bold:
                parent_label = tools.htmlEscape(parent_label)
                self.tree.setLabel(parent, '<b>%s</b>' % parent_label)
            elif not playing and is_bold:
                parent_label = tools.htmlEscape(parent_label[3:-4])
                self.tree.setLabel(parent, parent_label)

        parent = self.tree.store.iter_parent(iter)
        parent_label = self.tree.getLabel(parent) if parent else None
        label = track.get_label(parent_label=parent_label, playing=playing)
        if playing:
            self.tree.setLabel(iter, label)
            self.tree.setItem(iter, ROW_ICO, icons.playMenuIcon())
            self.tree.expand(iter)
        else:
            self.tree.setLabel(iter, label)
            icon = self.tree.getItem(iter, ROW_ICO)
            has_error = (icon == icons.errorMenuIcon())
            is_dir = (icon == icons.mediaDirMenuIcon())
            if not is_dir and not has_error:
                self.tree.setItem(iter, ROW_ICO, icons.nullMenuIcon())
Beispiel #4
0
    def set_track_playing(self, iter, playing):
        if not iter:
            return
        track = self.tree.getTrack(iter)
        if not track:
            return

        for parent in self.tree.get_all_parents(iter):
            parent_label = self.tree.getLabel(parent)
            parent_label = tools.htmlUnescape(parent_label)
            is_bold = parent_label.startswith('<b>') and parent_label.endswith('</b>')
            if playing and not is_bold:
                parent_label = tools.htmlEscape(parent_label)
                self.tree.setLabel(parent, '<b>%s</b>' % parent_label)
            elif not playing and is_bold:
                parent_label = tools.htmlEscape(parent_label[3:-4])
                self.tree.setLabel(parent, parent_label)

        parent = self.tree.store.iter_parent(iter)
        parent_label = self.tree.getLabel(parent) if parent else None
        label = track.get_label(parent_label=parent_label, playing=playing)
        if playing:
            self.tree.setLabel(iter, label)
            self.tree.setItem(iter, ROW_ICO, icons.playMenuIcon())
            self.tree.expand(iter)
        else:
            self.tree.setLabel(iter, label)
            icon = self.tree.getItem(iter, ROW_ICO)
            has_error = (icon == icons.errorMenuIcon())
            is_dir = (icon == icons.mediaDirMenuIcon())
            if not is_dir and not has_error:
                self.tree.setItem(iter, ROW_ICO, icons.nullMenuIcon())
    def loadAlbums(self, tree, node, fakeChild):
        """ Initial load of the albums of the given node, assuming it is of type TYPE_ARTIST """
        rows      = []
        path      = tree.getItem(node, ROW_FULLPATH)
        artist    = tree.getItem(node, ROW_DATA)
        allAlbums = pickleLoad(os.path.join(tree.getItem(node, ROW_FULLPATH), 'albums'))

        # Filter albums if only favorites should be shown
        if self.showOnlyFavs:
            allAlbums = [album for album in allAlbums if self.isAlbumInFavorites(artist, album[ALB_NAME])]

        # Filter artists by genre if needed
        if self.currGenre is not None:
            allAlbums = [album for album in allAlbums if album[ALB_NAME] in self.allGenres[self.currGenre][artist]]

        # The icon depends on whether the album is in the favorites
        for album in allAlbums:
            if self.isAlbumInFavorites(artist, album[ALB_NAME]): icon = icons.starDirMenuIcon()
            else:                                                icon = icons.mediaDirMenuIcon()

            rows.append((icon, '[%s]' % tools.sec2str(album[ALB_LENGTH], True), '%s' % htmlEscape(album[ALB_NAME]),
                            TYPE_ALBUM, os.path.join(path, album[ALB_INDEX]), album[ALB_NAME]))

        # Add all the rows, and then add a fake child to each of them
        tree.appendRows(rows, node)
        tree.removeRow(fakeChild)
        for child in tree.iterChildren(node):
            tree.appendRow(FAKE_CHILD, child)
Beispiel #6
0
    def restoreTreeDump(self, dump, parent=None):
        """ Recursively restore the dump under the given parent (None for the root of the tree) """
        for item in dump:
            (name, track) = item[0]

            if track:
                self.tree.appendRow((icons.nullMenuIcon(), name, track), parent)
            else:
                newNode = self.tree.appendRow((icons.mediaDirMenuIcon(), name, None), parent)

                if item[1] is not None:
                    if len(item[1]) != 0:
                        # We must expand the row before adding the real children,
                        # but this works only if there is already at least one child
                        self.restoreTreeDump(item[1], newNode)
Beispiel #7
0
    def restoreTreeDump(self, dump, parent=None):
        """ Recursively restore the dump under the given parent (None for the root of the tree) """
        for item in dump:
            (name, track) = item[0]

            if track:
                self.tree.appendRow((icons.nullMenuIcon(), name, track), parent)
            else:
                newNode = self.tree.appendRow((icons.mediaDirMenuIcon(), name, None), parent)

                if item[1] is not None:
                    if len(item[1]) != 0:
                        # We must expand the row before adding the real children,
                        # but this works only if there is already at least one child
                        self.restoreTreeDump(item[1], newNode)
    def switchFavoriteStateOfSelectedItems(self, tree):
        """ Add to/remove from favorites the selected items """
        # Go through selected items and switch their state
        removed = False
        for path in tree.getSelectedPaths():
            if tree.getItem(path, ROW_TYPE) == TYPE_ALBUM:
                album  = tree.getItem(path, ROW_DATA)
                artist = tree.getItem(path[:-1], ROW_DATA)

                if self.isAlbumInFavorites(artist, album):
                    removed = True
                    tree.setItem(path, ROW_PIXBUF, icons.mediaDirMenuIcon())
                    self.removeFromFavorites(artist, album)
                else:
                    tree.setItem(path, ROW_PIXBUF, icons.starDirMenuIcon())
                    self.addToFavorites(artist, album)

        # If some favorites were removed, we may have to reload the tree
        if self.showOnlyFavs and removed:
            self.saveTreeState()
            self.loadArtists(self.tree, self.currLib)
            self.restoreTreeState()
    def showPopupMenu(self, tree, button, time, path):
        """ Show a popup menu """
        popup = gtk.Menu()

        # Play
        play = gtk.ImageMenuItem(gtk.STOCK_MEDIA_PLAY)
        popup.append(play)

        if path is None: play.set_sensitive(False)
        else:            play.connect('activate', lambda widget: self.playPaths(tree, None, True))

        # Add
        add = gtk.ImageMenuItem(gtk.STOCK_ADD)
        popup.append(add)

        if path is None: add.set_sensitive(False)
        else:            add.connect('activate', lambda widget: self.playPaths(tree, None, False))

        # Separator
        popup.append(gtk.SeparatorMenuItem())

        # Add to/remove from favorites
        favCpt    = 0
        nonFavCpt = 0
        for node in tree.getSelectedPaths():
            if tree.getItem(node, ROW_TYPE) != TYPE_ALBUM:
                favCpt    = 1
                nonFavCpt = 1
                break
            elif tree.getItem(node, ROW_PIXBUF) == icons.mediaDirMenuIcon():
                nonFavCpt += 1
            else:
                favCpt += 1

        if favCpt == 0:      favorite = gtk.ImageMenuItem(_('Add to Favorites'))
        elif nonFavCpt == 0: favorite = gtk.ImageMenuItem(_('Remove from Favorites'))
        else:                favorite = gtk.ImageMenuItem(_('Favorites'))

        favorite.get_image().set_from_pixbuf(icons.starMenuIcon())
        popup.append(favorite)

        if TYPE_ALBUM in [tree.getItem(path, ROW_TYPE) for path in tree.getSelectedPaths()]:
            favorite.connect('activate', lambda widget: self.switchFavoriteStateOfSelectedItems(tree))
        else:
            favorite.set_sensitive(False)

        # Show only favorites
        showFavorites = gtk.CheckMenuItem(_('Show Only Favorites'))
        showFavorites.set_active(self.showOnlyFavs)
        showFavorites.connect('toggled', lambda widget: self.switchFavoritesView(tree))
        popup.append(showFavorites)

        # Separator
        popup.append(gtk.SeparatorMenuItem())

        # Filter by genre
        genresMenu  = gtk.Menu()
        filterGenre = gtk.MenuItem(_("Filter by Genre"));

        filterGenre.set_submenu(genresMenu)
        popup.append(filterGenre)

        # Need to keep the mapping widget -> genre to handle activate events
        self.genreItemToName = {}

        for genre in sorted(self.allGenres):
            genreItem = gtk.CheckMenuItem(genre.capitalize())
            genreItem.set_active(genre == self.currGenre)
            self.genreItemToName[genreItem] = genre
            genreItem.connect('activate', lambda widget: self.filterByGenre(self.genreItemToName[widget]))
            genresMenu.append(genreItem)

        genresMenu.append(gtk.SeparatorMenuItem())

        genreItem = gtk.CheckMenuItem(_('Unfiltered'))
        genreItem.set_active(self.currGenre == None)
        genreItem.connect('activate', lambda widget: self.filterByGenre(None))
        genresMenu.append(genreItem)

        # Separator
        popup.append(gtk.SeparatorMenuItem())

        # Collapse all nodes
        collapse = gtk.ImageMenuItem(_('Collapse all'))
        collapse.set_image(gtk.image_new_from_stock(gtk.STOCK_CLEAR, gtk.ICON_SIZE_MENU))
        popup.append(collapse)

        enabled = False
        for child in self.tree.iterChildren(None):
            if self.tree.row_expanded(child):
                enabled = True
                break

        if enabled: collapse.connect('activate', lambda widget: self.tree.collapse_all())
        else:       collapse.set_sensitive(False)

        # Refresh the library
        refresh = gtk.ImageMenuItem(gtk.STOCK_REFRESH)
        refresh.connect('activate', lambda widget: idle_add(self.refreshLibrary(None, self.currLib, self.libraries[self.currLib][LIB_PATH]).next))
        popup.append(refresh)

        # Randomness
        randomness     = gtk.Menu()
        randomnessItem = gtk.ImageMenuItem(_('Randomness'))
        randomnessItem.get_image().set_from_icon_name('stock_shuffle', gtk.ICON_SIZE_MENU)
        randomnessItem.set_submenu(randomness)
        popup.append(randomnessItem)

        # Random album of the selected artist
        if path is not None and tree.getItem(path, ROW_TYPE) == TYPE_ARTIST:
            album = gtk.MenuItem(_('Pick an album of %(artist)s' % {'artist': tree.getItem(path, ROW_NAME).replace('&amp;', '&')}))
            album.connect('activate', lambda widget: self.pickAlbumArtist(tree, path))
            randomness.append(album)

        # Random album in the entire library
        album = gtk.MenuItem(_('Pick an album in the library'))
        album.connect('activate', lambda widget: self.pickAlbumLibrary(tree))
        randomness.append(album)

        popup.show_all()
        popup.popup(None, None, None, button, time)