Skip to content

Commit

Permalink
Display tracklist in Info Dialog Infos tab for albums too
Browse files Browse the repository at this point in the history
On not-yet-matched clusters, context menu shows Infos item and user can see a copiable tracklist in the Info tab.
On loaded albums the context menu will be there only when album has cover art (and no errors).

This patch unifies things a bit without adding much code, Infos dialog is accessible as soon an album is loaded, and Infos tab displays a text tracklist for it, which can be convenient for the user as it is copiable.
  • Loading branch information
zas committed Sep 10, 2020
1 parent 8491e3f commit 7cd4312
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 54 deletions.
2 changes: 1 addition & 1 deletion picard/album.py
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@ def can_refresh(self):
return True

def can_view_info(self):
return (self.loaded and (self.metadata.images or self.orig_metadata.images)) or self.errors
return self.loaded or self.errors

def is_album_like(self):
return True
Expand Down
16 changes: 0 additions & 16 deletions picard/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -821,22 +821,6 @@ def update_item(self):
def iterfiles(self, save=False):
yield self

@property
def tracknumber(self):
"""The track number as an int."""
try:
return int(self.metadata["tracknumber"])
except BaseException:
return 0

@property
def discnumber(self):
"""The disc number as an int."""
try:
return int(self.metadata["discnumber"])
except BaseException:
return 0


_file_post_load_processors = PluginFunctions(label='file_post_load_processors')
_file_post_addition_to_track_processors = PluginFunctions(label='file_post_addition_to_track_processors')
Expand Down
81 changes: 44 additions & 37 deletions picard/ui/infodialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,48 @@ def format_file_info(file_):
htmlescape(i[1])), info))


def format_tracklist(cluster):
info = []
info.append("<b>%s</b> %s" % (_('Album:'),
htmlescape(cluster.metadata["album"])))
info.append("<b>%s</b> %s" % (_('Artist:'),
htmlescape(cluster.metadata["albumartist"])))
info.append("")
TrackListItem = namedtuple('TrackListItem', 'tracknumber, title, artist, length')
tracklists = defaultdict(list)
if isinstance(cluster, Album):
objlist = cluster.tracks
else:
objlist = cluster.iterfiles(False)
for obj_ in objlist:
m = obj_.metadata
artist = m["artist"] or m["albumartist"] or cluster.metadata["albumartist"]
track = TrackListItem(m["tracknumber"], m["title"], artist,
m["~length"])
tracklists[obj_.discnumber].append(track)

def sorttracknum(item):
try:
return int(item.tracknumber)
except ValueError:
try:
# This allows to parse values like '3' but also '3/10'
m = re.search(r'^\d+', item.tracknumber)
return int(m.group(0))
except AttributeError:
return 0

ndiscs = len(tracklists)
for discnumber in sorted(tracklists):
tracklist = tracklists[discnumber]
if ndiscs > 1:
info.append("<b>%s</b>" % (_('Disc %d') % discnumber))
lines = ["%s %s - %s (%s)" % item for item in sorted(tracklist, key=sorttracknum)]
info.append("<b>%s</b><br />%s<br />" % (_('Tracklist:'),
'<br />'.join([htmlescape(s).replace(' ', '&nbsp;') for s in lines])))
return '<br/>'.join(info)


class FileInfoDialog(InfoDialog):

def __init__(self, file_, parent=None):
Expand Down Expand Up @@ -325,7 +367,7 @@ def _display_info_tab(self):
self.ui.info.setText(text + '<hr />')
else:
tabWidget.setTabText(tab_index, _("&Info"))
self.tab_hide(tab)
self.ui.info.setText(format_tracklist(album))


class TrackInfoDialog(InfoDialog):
Expand Down Expand Up @@ -360,42 +402,7 @@ def __init__(self, cluster, parent=None):

def _display_info_tab(self):
tab = self.ui.info_tab
cluster = self.obj
tabWidget = self.ui.tabWidget
tab_index = tabWidget.indexOf(tab)
tabWidget.setTabText(tab_index, _("&Info"))
info = []
info.append("<b>%s</b> %s" % (_('Album:'),
htmlescape(cluster.metadata["album"])))
info.append("<b>%s</b> %s" % (_('Artist:'),
htmlescape(cluster.metadata["albumartist"])))
info.append("")
TrackListItem = namedtuple('TrackListItem', 'tracknumber, title, artist, length')
tracklists = defaultdict(list)
for file_ in cluster.iterfiles(False):
m = file_.metadata
artist = m["artist"] or m["albumartist"] or cluster.metadata["albumartist"]
track = TrackListItem(m["tracknumber"], m["title"], artist,
m["~length"])
tracklists[file_.discnumber].append(track)

def sorttracknum(item):
try:
return int(item.tracknumber)
except ValueError:
try:
# This allows to parse values like '3' but also '3/10'
m = re.search(r'^\d+', item.tracknumber)
return int(m.group(0))
except AttributeError:
return 0

ndiscs = len(tracklists)
for discnumber in sorted(tracklists):
tracklist = tracklists[discnumber]
if ndiscs > 1:
info.append("<b>%s</b>" % (_('Disc %d') % discnumber))
lines = ["%s %s - %s (%s)" % item for item in sorted(tracklist, key=sorttracknum)]
info.append("<b>%s</b><br />%s<br />" % (_('Tracklist:'),
'<br />'.join([htmlescape(s).replace(' ', '&nbsp;') for s in lines])))
self.ui.info.setText('<br/>'.join(info))
self.ui.info.setText(format_tracklist(self.obj))
16 changes: 16 additions & 0 deletions picard/ui/item.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,19 @@ def is_album_like(self):

def load(self, priority=False, refresh=False):
pass

@property
def tracknumber(self):
"""The track number as an int."""
try:
return int(self.metadata["tracknumber"])
except BaseException:
return 0

@property
def discnumber(self):
"""The disc number as an int."""
try:
return int(self.metadata["discnumber"])
except BaseException:
return 0

0 comments on commit 7cd4312

Please sign in to comment.