Picard: Additonal Visible Data in the Main Window - (Was UI Modifications - Attainable via Plug-in or code level?)

I’d like to separate the columnar data in the main panes to have at least the amount of tracks to be Left Justified on it’s own, as a separate column. To click/sort by would be a plus, but even just for viewing purposes. At the very least it would improve readability making it a lot easier to scan the list looking for things.

Seeing that the “Album Title” plugin adds to the UI and is a unique case implementation wise, would any UI changes fall into that classification?

If the amount of Images can be separated to it’s own column to sort by, all the better. But … It would at least easier to scan down the list too, even if it’s part of the column with the Matched Tracks since it would all be Left Justified.

Other niceties would be making them able to be sorted by status Albums by Perfect, Perfect Modified, Incomplete, or even Incomplete (Too few tracks), vs ‘Incomplete’ due to Extra Matched Files.

Curiosity got me … Looked at the Add Column Plug-in … and … !!! That’s all to add a column? That’s Nuts.

So, is there a variable that represents the number of tracks that works in that space?

…and as for why the Add Album Column can’t be disabled. But it -can- be removed. It’s literally a wedged in hack. :slight_smile:

Looking at it, and adding to it:
from picard.ui.itemviews import MainPanel #MainPanel.columns.append((N_('Matched'), 'matched')) #MainPanel.columns.append((N_('Album'), 'album'))
Dis/enable lines as desired - the biggest question being, is there a ‘variable’ that represents the number of matched tracks for that album that can be placed there? Stabbing around in the dark, just putting various things in there, that some seem to work, many do not, and a few will just crash it. :slight_smile:

Moving that into itemviews.py directly … I see how the plug-in is a literal wedged in hack.
"Hey you! Let me see your list! (/me adds something to it)
Okay, you can have it back. (snicker, he’ll never notice I added that myself! :innocent: )

  columns = [
    (N_('Title'), 'title'),
    (N_('Matched'), 'matchedtracks'), # whatever would be appropriate .. 
    (N_('Tracks'), 'totaltracks'),
    (N_('Length'), '~length'),
    (N_('Artist'), 'artist'),
    (N_('Album'), 'album'),
]

…and I presume that if a tick box in Options were applied to (N_('Album'), 'album'), that would be en/disable at will.

Which brings me to album.py

Here is where the columns are being populated.
With changes to the (x/y); x images to be only (x images) at the top and need to be added at the end.

def column(self, column):
    if column == 'title':
    
    
        if self.status is not None:

            title = self.status
        else:
        
            title = self.metadata['album']
        if self.tracks:
            linked_tracks = 0
            for track in self.tracks:
                if track.is_linked():
                    linked_tracks += 1

            text = title

#          text = '%s\u200E (%d/%d' % (title, linked_tracks, len(self.tracks))

            # CoverArt.set_metadata uses the orig_metadata.images if metadata.images is empty
            # in order to show existing cover art if there's no cover art for a release. So
            # we do the same here in order to show the number of images consistently.
            if self.metadata.images:
                metadata = self.metadata
            else:
                metadata = self.orig_metadata

            number_of_images = len(metadata.images)
            if getattr(metadata, 'has_common_images', True):
                text += ngettext(" (%i image)", " (%i images)",
                                 number_of_images) % number_of_images
            else:
                text += ngettext(" (%i image not in all tracks)", " (%i different images among tracks)",
                                 number_of_images) % number_of_images
            return  text
        else:
            return  title
            
    elif column == '~length':
        length = self.metadata.length
        if length:
            return format_time(length)
        else:
            return ''

#### This needs to get broken into two and show up in the tracks / matched columns.
#### I've gotten this far. ... But I'm up agaist a wall with this part. 

        text = '(%d/%d' % (linked_tracks, len(self.tracks))

        unmatched = self.get_num_unmatched_files()
        if unmatched:
            text += '; %d?' % (unmatched,)
        unsaved = self.get_num_unsaved_files()
        if unsaved:
            text += '; %d*' % (unsaved,)

    elif column == 'album':
        return self.metadata['album']

    elif column == 'artist':
        return self.metadata['albumartist']

    elif column == 'tracks':       
         return 	'linked_tracks'
        
    elif column == 'matched':       
        return 	'totaltracks'
        
    else:
        return ''

# Reference for putting back values in new columns
#
#                unmatched = self.get_num_unmatched_files()
#                
#                text = '%s <-> (%d|%d' % (title, linked_tracks, len(self.tracks))
#                if unmatched:
#                    text += '; %d?' % (unmatched,)
#                unsaved = self.get_num_unsaved_files()
#                if unsaved:
#                    text += '; %d*' % (unsaved,)


 `

How I interpret that is within that Definition there are two sets of things going on.

First, it populates the data for line title, with the graphic icon, the Album Name, Length and Artist Columns.

While data is being fetched from the DB Title is temporarily defined as [loading album information]

Once Album data is fetched, title is now populated as Album Name with the text for the amount of tracks matched, saved/not saved and sum of the amount of images retrieved is appended so we see
(O) Album Name (x/y; z image(s)) as a single string being echoed in the title column.

As a sub-set to the Bold Text Title Length Artist line, the album tracks are populated below in a loop form until there are no more to display.

…and then it’s done with that last return ''

So a Column added to MainPanel as above will result in that column being populated at the ‘sub-set’ point where the tracktitle etc are being echoed.

First I would like to move that Album Title from the ‘sub-set’ lines (the individual tracks) to the top line so that we see all in one line:

Title. .................... Tracks | Match | Len | Artist | Album
(O) Album Name (z image(s)).. 15 ... 14 ... 3m42s . B-52's . AlbumName
.. ♫ 01 . Track Title ......................1m02s
.. ♫ 02 . Track Title ......................2m40s

(O) Next Album (z image(s)).. 20 ... 20 ... 3m42s . B-47's . Kaboom!
… etc.

With just the quick slick wedge method I can get the tracktotal and album columns populated. I can’t find a variable that would stand in for matchedtracks.

I presume that i’ll need to add a elif column == 'matched' and then attach that value to it, which I believe is already available as matchedtracks.

Now I’m hung up on trying to restore the values to the new columns, and to get totaltracks show on the top line.

 # at the comment that says This needs to be broken up into two .. 

I’ve edited the post since I first started it but I need help with this bit.

I’m down to:

#### This needs to get broken into two and show up in the tracks / matched columns. 
#### I've gotten this far. ... But I'm up agaist a wall with this part. 

            text = '(%d/%d' % (linked_tracks, len(self.tracks))

            unmatched = self.get_num_unmatched_files()
            if unmatched:
                text += '; %d?' % (unmatched,)
            unsaved = self.get_num_unsaved_files()
            if unsaved:
                text += '; %d*' % (unsaved,)

#### The above needs to be integrated below. 
############################

        elif column == 'album':
            return self.metadata['album']

        elif column == 'artist':
            return self.metadata['albumartist']

        elif column == 'tracks':       
             return 	'linked_tracks'
            
        elif column == 'matched':       
            return 	'len(self.tracks)'
        else:
            return ''

Something like that, though I think I have the values for ‘tracks’ / ‘matched’ reversed.

This is a very accurate description, yes :slight_smile:

Regarding your problem I would probably go with a percentage completed. Something like this in def column(self, column):

elif column == '~completed':
    trackcount = len(self.tracks)
    if not trackcount:
        return ''
    return '{:03.0f}%'.format(self.get_num_matched_tracks() / trackcount * 100)

This needs a column definition like (N_('Completed'), '~completed').

The problem you will have here in all cases is sorting. Currently the columns sort by string, so sorting by numbers is not working well. Hence in my example above I decided to format the numbers as percentage with leading zeros ("100%" > "090%“, but "100%" < "90%”).

1 Like

So far here’s what I’ve got. I’d like to separate the column with the album status still. :slight_smile: But I have to figure out where that’s being done at, I see a few things about album status in album.py, but nothing I can make any sense of.

As for the sorting, interestingly it seems to be working, while I did notice issues previously it seems to have worked itself out once I prettied up things. I still need to do some cleanup on code formatting and such, but I can see how this works in the meantime. I’ll compare with the percentage method you’ve mentioned above.

…and then go read about git, as I’m still used to svn and cvs. :wink:

For that matter, my development experience is 1980’s Applesoft Basic and 6502 Assembly. Line numbers and labels. Object Oriented Programming? What the %@#! does that mean?!? :astonished:

Two weeks ago I never had looked at a line of Python. It’s a lot less persnickety than php with separators, end of lines, that kind of stuff.

But it certainly makes up for that with the indents. :rage::boom::bomb:

There’s another thread where someone asked about similar options. Once I figure out how to push the local git branch to github … as right now I don’t even see it listed on there and I thought I created it there. So…

1 Like

Looks awesome, good job. Waitin for final version. @tdiaz:

Is it possible, that additional information (catalognumber, media) was displayed also in albums not only in tracks? As below:

@hbrtkp:
Where are those extra columns coming from now? Did you add them in via plug in wedge? :wink:

@outsidecontext: I see what you meant with the sorting now that I have a large amount of examples on the right side. FWIW, even with sorting by string, the real goal of that sorting was to get all those albums that have just 1 or 2 matched tracks - that are never going to be completed as I’m only interested in that one track. … to be able to select them all at once and use the Save as Single …

Though the leading zeros would be better and make the whole thing much ‘nicer’. I’m just glad this is working well now, with the tweaks I’ve added especially.

Again, it was that 2.2 release that made me look at this whole thing a lot more seriously, and I sure have. The fubar2000 for whatever reason made no real sense to me, until I realized it was a literal string building deal from top to bottom, and I’ve never touched a lick of Python before last week. Never loaded a source file for any reason. Combine that with I fumble around with PHP frustratingly, yet Python just makes absolute sense looking at it, indents aside. :wink:

Thanks again for that release … allowing me to finally clear up a mess of files. :slight_smile:

1 Like

I wrote about it in this topic:

1 Like

For your extra columns, yes, I used the one from the repository, so that explains that.

I think your question was can you get the Catalog Number and Media up on bold faced line along with the Album / Artist /et al … What isn’t clear is if you would still want those items within the album as well? Your thread indicates you do not want them on the track level, and your reply above seems to indicate that you do want to see them in all the lines.

For some reason, whatever it may be, the media type absolutely refuses to show up on that top line even though it’s set up the exact same way as the others of the same type.

Anything that is on that top line has to be done in the source code. Any columns that are added that will not ever show up on the top line are added at the moment via the plugin.

With all those columns in there, I’m pretty sure that it would be a good idea to add something in the options to select which ones you’d want to see … and even if possible, figure out how to split that between the left and the right so that you can have less on one side than the other. At the moment you can simply move the columns you want over to the leading edge of the window and let the others stay out of the view. But with Picard not saving the column positions when closing, that also makes having all those not select-able a bit much to deal with.

For things to do on this:
Save column positions at quit time.
Sizes, window placement and such are saved, just the column order is not saved.
Add UI options to select which columns you want to see.
Bonus for above - Have them separately configurable for which you want to see on either side. Right now columns are added to both sides no matter what.

I have a few other things I need to figure out why they are happening… I’ll make a different post for that later.

What isn’t clear is if you would still want those items within the album as well? Your thread indicates you do not want them on the track level, and your reply above seems to indicate that you do want to see them in all the lines.

It’s old topic, but i think these days it would be cool to have both (in track and album level).

I think, extra columns should be native functionality and should work in a similar way as in eg jdownloader (rmb and enable / disable what you want):

I totally agree on the availability. I had intended to see about adding more columns based on what I’d been looking for while using Picard.

I find that I spent a lot of time clicking / arrow keying around to see the filenames and path at the bottom of the window - where it gets wiped out by importing/downloading messages :wink: …and to be able to see the file type, a lot more handy on the left side than right, but when on the right and choosing which tracks to use to make that ‘perfect’ album, I wanted to choose by types when I had multiple to pick from.