Column Sorting Ability?

Sorting By Column Contents:

On the left (cluster.py) I can sort by any column data within the Cluster. The sort acts both at the Parent (Cluster Line Level) and within the Cluster itself.


On the right (album.py) I can only sort by the Parent (Album Line Level) and not within each Album.
(e.g.: I have a Track No. and I want to sort that from in descending order instead)

Or I want to sort by bitrate, size, etc- to hand pick tracks from an Album that has duplicates within.

Where is the restriction being applied at? :slight_smile:

**I know, youā€™d like to see tickets for some of these kinds of questions / suggestions - Something changed a few weeks ago and since then the MB Jira pages are a mess for me for some reason.

Thatā€™s intentional, sorting of tracks is disabled in itemviews.py.

The sorting is for sorting albums. Combining this would be weird. I very well want to sort the album list alphabetically to faster find something specific, but that does not mean I want the track list be changed.

1 Like

I figured it would be intentional - I just want to actually break it. But also be able to use it on any of the columns. I see where that line similarly shows true in the Cluster related areas, so letā€™s go see what that doesā€¦ :slight_smile:

ā€¦and with a little more NatSort sprinkled in where neededā€¦

It actually should already support this for all columns, see the implementation of TreeItem.__lt__ in the same file. At least thatā€™s the intention :slight_smile:

1 Like

ā€¦and good deal. Yes, Itā€™s definitely ā€˜differentā€™ with that ability, but itā€™s also very flexible on at the power user level. :slight_smile:

It does not work for my Artwork or Length columns as they are, but it does on the anything else purely alpha or numerical. Hmmmā€¦


Screen Shot 2019-12-18 at 9.15.28 AM
Probably because of the way those are being done. If I can get the Length to do [XXhXXmXXs] in the Naming Script consistently then I would. I only changed it because I didnā€™t want to use the UNICODE replacement for the colon, and otherwise I get over-ridden by the Windows Compatibility setting for filenaming and would get ā€œ[XX_XX_XX]ā€ (underscores) for the time no matter what I did in the script.

Artwork? Is it the ā€œimg/imgsā€ perhaps? Iā€™m not attached to that either. Itā€™s just kind of how it was before I separated the values out.

Now maybe I can figure out how to make that ā€œStatusā€ column work, and sort based on that, too.

How does the Status Icon get to become part of the column content?
Can it be gotten on itā€™s own / and used as a sort factor? Iā€™m sure thereā€™s some kind of ā€œvalueā€ that represents whether that icon is gold or not, has the asterisk(Changed) indicator or notā€¦

e.g. Sort the column and have all Perfect/Gold Icons listed together vs. imperfect?

Having an icon is a property of any table cell in a QTreeWidget. Have a look at the AlbumItem.update method how the icon gets set depending on the state, e.g. self.setIcon(0, AlbumItem.icon_cd_saved_modified). This sets the icon on the first column with index 0.

You could add a column ~albumstatus' or whatever and set the icon there. Sorting is a different topic, you would need to implement a specific sorting for this column. Have a look at the implementations of ltandsortkeyinTreeItem`. There is already specific handling for the length.

Thatā€™s because you broke the length sorting. See TreeItem.sortkey, it assumes that length is the second logical column (index 1). If you manipulated MainPanel.columns and Length is no longer the second entry there the length sorting is broken. As far as ā€œnatural sortingā€ goes the length column in your view gets correctly sorted :wink:

Also if you put maybe the artwork column in the second place it could explain why this is not working as expected.

2 Likes

By logical column, do you mean the order in which the columns are declared in itemviews?

 columns = [
        (N_('Title'), 'title'),
        (N_('Artwork.'), 'artcount'),#amd
        (N_('Matched'), 'matchedtracks'),#amd
        (N_('Unmatch'), 'unmatchedtracks'),#amd
        (N_('Tracks'), 'albumtracks'),#amd
        (N_('Status'), 'status'),  # amd
        (N_('Completed'), '~completed'),#amd
        (N_('Unsaved'), 'unsavedtracks'),#amd
        (N_('Length'), '~length'),
        (N_('Artist'), 'artist'),
        (N_('Cat No.'), 'catalognumber'),#amd
        (N_('Media'), 'media'),#amd
        (N_('Size'), '~filesize'),#amd
        (N_('Album Artist'), 'albumartist'),
        (N_('Composer'), 'composer'),
        (N_('Album'), 'album'),
        (N_('Disc Subtitle'), 'discsubtitle'),
        (N_('Track No.'), 'tracknumber'),
        (N_('Disc No.'), 'discnumber'),
        (N_('Barcode'), 'barcode'),
        (N_('Genre'), 'genre'),
        (N_('Bitrate'), '~bitrate'),#amd
        (N_('Ext.'), '~extension'),#amd
        (N_('Format'), '~format'),#amd
        (N_('Path'), '~dirname'),#amd
        (N_('File'), '~filename'),#amd
    ]

Iā€™m still working out how the column setup really works. Originally when they were added here they were going to show up on both sides by design. I discussed making a separate list so that some of them would not be visible on the Left. Short of dragging the position over to the far right making that column width as small as it can be.

When the configurable columns methodology was implemented that made having two lists a moot point. So I reverted all my changes back to having the single list.

So, to have a column be present at all- itā€™s defined in itemviews. Then it will display the variable 'album', '~length', thatā€™s been assigned to the column (N_('Album') in itā€™s raw form.

Since things like artwork quantity, unsaved/changed tracks, etc. are derived from within, are dynamic, and that data is specifically shaped/formatted for display, that is done in the code segment for the level of detail that is being made visible. If at the track level, an elif column in track, otherwise elif column in album or cluster.

        elif column == '~length':
            length = self.metadata.length
            if length:
                return format_time(length)
            else:
                return ''

In the Column Length, the value we want is ~length. Weā€™ll call that length and it comes from self.metadata.length. Thereā€™s a value there, then format it format_time(length) otherwise give me nothing ''.

But if we wanted to see ~length as it is stored natively the whole elif column == wouldnā€™t be necessary.

I need to look at QTreeWidget and see what/how parameters are passed to it and what they do and some of this should be a clearer.

Thanks for putting up with me and my seemingly boneheaded approach to figuring all this outā€¦

text = 'hello world'
return text
Just doesnā€™t do it for me as a starting point.

Bah humbug! :wink:

D: 15:07:18,116 file.move:544: Moving <MP3File '03. The Village[4m37s][V3 44100KHz VBR 2ch].mp3'> from <Cluster d4532f26-1b63-44ea-9d12-7b358e62cd38 'Power, Corruption & Lies/Unmatched Files'> to <Track a5aab782-bfb9-4621-a1d9-327952e9d692 'The Village'>
Traceback (most recent call last):
  File "picard/webservice/__init__.py", line 441, in _process_reply
  File "picard/webservice/__init__.py", line 428, in _handle_reply
  File "/Users/tdiaz/Library/Preferences/MusicBrainz/Picard/plugins/wikidata.zip/wikidata/__init__.py", line 279, in parse_wikidata_response
  File "picard/album.py", line 364, in _finalize_loading
  File "picard/album.py", line 539, in match_files
  File "picard/file.py", line 549, in move
  File "picard/cluster.py", line 126, in remove_file
  File "picard/cluster.py", line 97, in _update_related_album
  File "picard/album.py", line 469, in update
  File "picard/ui/itemviews.py", line 840, in update
  File "picard/ui/itemviews.py", line 920, in update
AttributeError: 'NoneType' object has no attribute 'obj'
Abort trap: 6
logout
Saving session.

I get that NoneType in TrackItem(TreeItem) while importing albums with that ability to sort enabled.

        if newnum > oldnum:  # add new items
            items = []
            for i in range(newnum - 1, oldnum - 1, -1):  # insertChildren is backwards
                item = TrackItem(album.tracks[i], True) #amd This one changed for sorting enabling.
                item.setHidden(False)  # Workaround to make sure the parent state gets updated
                items.append(item)
            self.insertChildren(oldnum, items)

Need to scrutinize cluster vs album in there a bit more I guess. Actually, I donā€™t need to sort by track especially. If using the sort options on other columns worked at the track level when there are duplicate tracks showingā€¦ e.g., MP3 always being second, smaller filesize being first, etcā€¦