diff --git a/picard/album.py b/picard/album.py index 3dc685ed9..dc821a3b9 100644 --- a/picard/album.py +++ b/picard/album.py @@ -168,7 +168,7 @@ class Album(DataObject, Item): if track_discids: track.metadata['musicbrainz_discid'] = track_discids track.update() - for file in track.linked_files: + for file in track.files: file.metadata['musicbrainz_discid'] = track_discids file.update() @@ -399,7 +399,7 @@ class Album(DataObject, Item): self._new_metadata.strip_whitespace() for track in self.tracks: - for file in list(track.linked_files): + for file in list(track.files): file.move(self.unmatched_files) self.metadata = self._new_metadata self.orig_metadata.copy(self.metadata) @@ -632,7 +632,7 @@ class Album(DataObject, Item): def is_modified(self): if self.tracks: for track in self.tracks: - for file in track.linked_files: + for file in track.files: if not file.is_saved(): return True return False @@ -640,7 +640,7 @@ class Album(DataObject, Item): def get_num_unsaved_files(self): count = 0 for track in self.tracks: - for file in track.linked_files: + for file in track.files: if not file.is_saved(): count += 1 return count @@ -746,7 +746,7 @@ class NatAlbum(Album): for track in self.tracks: if old_album_title == track.metadata["album"]: track.metadata["album"] = self.metadata["album"] - for file in track.linked_files: + for file in track.files: track.update_file_metadata(file) self.enable_update_metadata_images(True) super().update(update_tracks) diff --git a/picard/tagger.py b/picard/tagger.py index c1ee1e330..77fad8626 100644 --- a/picard/tagger.py +++ b/picard/tagger.py @@ -750,7 +750,7 @@ class Tagger(QtWidgets.QApplication): elif isinstance(obj, NonAlbumTrack): self.remove_nat(obj) elif isinstance(obj, Track): - files.extend(obj.linked_files) + files.extend(obj.files) elif isinstance(obj, Album): self.window.set_statusbar_message( N_("Removing album %(id)s: %(artist)s - %(album)s"), diff --git a/picard/track.py b/picard/track.py index 6f17e22ae..db0d62cdd 100644 --- a/picard/track.py +++ b/picard/track.py @@ -48,6 +48,7 @@ from picard import ( config, log, ) +from picard.cluster import FileList from picard.const import ( DATA_TRACK_TITLE, SILENCE_TRACK_TITLE, @@ -73,12 +74,9 @@ from picard.util.imagelist import ( ImageList, add_metadata_images, remove_metadata_images, - update_metadata_images, ) from picard.util.textencoding import asciipunct -from picard.ui.item import Item - _TRANSLATE_TAGS = { "hip hop": "Hip-Hop", @@ -137,39 +135,42 @@ class TrackArtist(DataObject): super().__init__(ta_id) -class Track(DataObject, Item): +class Track(DataObject, FileList): metadata_images_changed = QtCore.pyqtSignal() def __init__(self, track_id, album=None): DataObject.__init__(self, track_id) + FileList.__init__(self) self.album = album - self.linked_files = [] self.num_linked_files = 0 - self.metadata = Metadata() - self.orig_metadata = Metadata() self.scripted_metadata = Metadata() self._track_artists = [] def __repr__(self): return '' % (self.id, self.metadata["title"]) + @property + def linked_files(self): + """For backward compatibility with old code in plugins""" + return self.files + def add_file(self, file): - if file not in self.linked_files: + if file not in self.files: track_will_expand = self.num_linked_files == 1 - self.linked_files.append(file) + self.files.append(file) self.num_linked_files += 1 self.update_file_metadata(file) add_metadata_images(self, [file]) self.album._add_file(self, file) - file.metadata_images_changed.connect(self.update_orig_metadata_images) + file.metadata_images_changed.connect(self.update_metadata_images) run_file_post_addition_to_track_processors(self, file) if track_will_expand: # Files get expanded, ensure the existing item renders correctly - self.linked_files[0].update_item() + self.files[0].update_item() def update_file_metadata(self, file): - if file not in self.linked_files: + if file not in self.files: return # Run the scripts for the file to allow usage of # file specific metadata and variables @@ -191,12 +192,12 @@ class Track(DataObject, Item): self.update() def remove_file(self, file): - if file not in self.linked_files: + if file not in self.files: return - self.linked_files.remove(file) + self.files.remove(file) self.num_linked_files -= 1 file.copy_metadata(file.orig_metadata, preserve_deleted=False) - file.metadata_images_changed.disconnect(self.update_orig_metadata_images) + file.metadata_images_changed.disconnect(self.update_metadata_images) self.album._remove_file(self, file) remove_metadata_images(self, [file]) run_file_post_removal_from_track_processors(self, file) @@ -218,23 +219,19 @@ class Track(DataObject, Item): if self.item: self.item.update() - def iterfiles(self, save=False): - for file in self.linked_files: - yield file - def is_linked(self): return self.num_linked_files > 0 def can_save(self): """Return if this object can be saved.""" - for file in self.linked_files: + for file in self.files: if file.can_save(): return True return False def can_remove(self): """Return if this object can be removed.""" - for file in self.linked_files: + for file in self.files: if file.can_remove(): return True return False @@ -254,7 +251,7 @@ class Track(DataObject, Item): elif column in m: return m[column] elif self.num_linked_files == 1: - return self.linked_files[0].column(column) + return self.files[0].column(column) def is_video(self): return self.metadata['~video'] == '1' @@ -348,15 +345,9 @@ class Track(DataObject, Item): genre = [join_genres.join(genre)] self.metadata['genre'] = genre - def update_orig_metadata_images(self): - update_metadata_images(self) - self.metadata_images_changed.emit() - def keep_original_images(self): - for file in self.linked_files: - file.keep_original_images() - self.update_orig_metadata_images() - if self.linked_files: + super().keep_original_images() + if self.files: self.metadata.images = self.orig_metadata.images.copy() else: self.metadata.images = ImageList() @@ -411,7 +402,7 @@ class NonAlbumTrack(Track): return try: self._parse_recording(recording) - for file in self.linked_files: + for file in self.files: self.update_file_metadata(file) except Exception: self._set_error(traceback.format_exc()) diff --git a/picard/ui/coverartbox.py b/picard/ui/coverartbox.py index 279f42b58..b75149eb2 100644 --- a/picard/ui/coverartbox.py +++ b/picard/ui/coverartbox.py @@ -55,7 +55,6 @@ from picard.coverart.image import ( CoverArtImageError, ) from picard.file import File -from picard.track import Track from picard.util import imageinfo from picard.util.lrucache import LRUCache @@ -488,29 +487,16 @@ class CoverArtBox(QtWidgets.QGroupBox): album.update_metadata_images() album.update(False) elif isinstance(self.item, FileList): - cluster = self.item - cluster.enable_update_metadata_images(False) - set_image(cluster, coverartimage) - for file in cluster.iterfiles(): + filelist = self.item + filelist.enable_update_metadata_images(False) + set_image(filelist, coverartimage) + for file in filelist.iterfiles(): set_image(file, coverartimage) file.metadata_images_changed.emit() file.update(signal=False) - cluster.enable_update_metadata_images(True) - cluster.update_metadata_images() - cluster.update() - elif isinstance(self.item, Track): - track = self.item - track.album.enable_update_metadata_images(False) - set_image(track, coverartimage) - track.metadata_images_changed.emit() - for file in track.iterfiles(): - set_image(file, coverartimage) - file.metadata_images_changed.emit() - file.update(signal=False) - track.album.enable_update_metadata_images(True) - track.album.update_metadata_images() - track.album.update(False) - track.update() + filelist.enable_update_metadata_images(True) + filelist.update_metadata_images() + filelist.update() elif isinstance(self.item, File): file = self.item set_image(file, coverartimage) diff --git a/picard/ui/infodialog.py b/picard/ui/infodialog.py index 62a3290b0..d4e03d0b4 100644 --- a/picard/ui/infodialog.py +++ b/picard/ui/infodialog.py @@ -399,7 +399,7 @@ class TrackInfoDialog(InfoDialog): tabWidget.setTabText(tab_index, _("&Info")) text = ngettext("%i file in this track", "%i files in this track", track.num_linked_files) % track.num_linked_files - info_files = [format_file_info(file_) for file_ in track.linked_files] + info_files = [format_file_info(file_) for file_ in track.files] text += '
' + '
'.join(info_files) self.ui.info.setText(text) diff --git a/picard/ui/itemviews.py b/picard/ui/itemviews.py index 438705e80..466ff10bc 100644 --- a/picard/ui/itemviews.py +++ b/picard/ui/itemviews.py @@ -1018,7 +1018,7 @@ class TrackItem(TreeItem): def update(self, update_album=True, update_files=True): track = self.obj if track.num_linked_files == 1: - file = track.linked_files[0] + file = track.files[0] file.item = self color = TrackItem.track_colors[file.state] bgcolor = get_match_color(file.similarity, TreeItem.base_color) @@ -1053,14 +1053,14 @@ class TrackItem(TreeItem): oldnum = newnum for i in range(oldnum): # update existing items item = self.child(i) - file = track.linked_files[i] + file = track.files[i] item.obj = file file.item = item item.update(update_track=False) if newnum > oldnum: # add new items items = [] for i in range(newnum - 1, oldnum - 1, -1): - item = FileItem(track.linked_files[i], False) + item = FileItem(track.files[i], False) item.update(update_track=False) items.append(item) self.addChildren(items) diff --git a/picard/ui/mainwindow.py b/picard/ui/mainwindow.py index 09a365ae5..bb0c4c40c 100644 --- a/picard/ui/mainwindow.py +++ b/picard/ui/mainwindow.py @@ -1077,7 +1077,7 @@ class MainWindow(QtWidgets.QMainWindow, PreserveGeometry): def show_more_tracks(self): obj = self.selected_objects[0] if isinstance(obj, Track): - obj = obj.linked_files[0] + obj = obj.files[0] dialog = TrackSearchDialog(self) dialog.load_similar_tracks(obj) dialog.exec_() @@ -1193,7 +1193,7 @@ class MainWindow(QtWidgets.QMainWindow, PreserveGeometry): self.set_statusbar_message(msg, mparms, echo=None, history=None) elif isinstance(obj, Track): if obj.num_linked_files == 1: - file = obj.linked_files[0] + file = obj.files[0] if file.has_error(): msg = N_("%(filename)s (%(similarity)d%%) (error: %(error)s)") mparms = { diff --git a/picard/ui/metadatabox.py b/picard/ui/metadatabox.py index cff5137c0..222932154 100644 --- a/picard/ui/metadatabox.py +++ b/picard/ui/metadatabox.py @@ -395,7 +395,7 @@ class MetadataBox(QtWidgets.QTableWidget): track_albums = set() for file in self.files: objects = [file] - if file.parent in self.tracks and len(self.files & set(file.parent.linked_files)) == 1: + if file.parent in self.tracks and len(self.files & set(file.parent.files)) == 1: objects.append(file.parent) file_tracks.append(file.parent) track_albums.add(file.parent.album) @@ -503,7 +503,7 @@ class MetadataBox(QtWidgets.QTableWidget): files.add(obj) elif isinstance(obj, Track): tracks.add(obj) - files.update(obj.linked_files) + files.update(obj.files) elif isinstance(obj, Cluster) and obj.can_edit_tags(): objects.add(obj) files.update(obj.files) @@ -511,7 +511,7 @@ class MetadataBox(QtWidgets.QTableWidget): objects.add(obj) tracks.update(obj.tracks) for track in obj.tracks: - files.update(track.linked_files) + files.update(track.files) objects.update(files) objects.update(tracks) self.selection_dirty = False diff --git a/picard/ui/ratingwidget.py b/picard/ui/ratingwidget.py index 7fab90ab8..1a4f9fb39 100644 --- a/picard/ui/ratingwidget.py +++ b/picard/ui/ratingwidget.py @@ -95,7 +95,7 @@ class RatingWidget(QtWidgets.QWidget): track = self._track rating = str(self._rating) track.metadata["~rating"] = rating - for file in track.linked_files: + for file in track.files: file.metadata["~rating"] = rating if config.setting["submit_ratings"]: ratings = {("recording", track.id): self._rating} diff --git a/picard/ui/scriptsmenu.py b/picard/ui/scriptsmenu.py index 1020e594d..87786522a 100644 --- a/picard/ui/scriptsmenu.py +++ b/picard/ui/scriptsmenu.py @@ -82,4 +82,4 @@ class ScriptsMenu(QtWidgets.QMenu): yield from self._get_metadata_objects(obj.tracks) yield from self._get_metadata_objects(obj.unmatched_files.iterfiles()) if isinstance(obj, Track): - yield from self._get_metadata_objects(obj.linked_files) + yield from self._get_metadata_objects(obj.files) diff --git a/picard/util/imagelist.py b/picard/util/imagelist.py index 237b95e11..a485690e3 100644 --- a/picard/util/imagelist.py +++ b/picard/util/imagelist.py @@ -147,12 +147,12 @@ def _get_state(obj): if isinstance(obj, Album): for track in obj.tracks: state.sources.append(track) - state.sources += track.linked_files + state.sources += track.files state.sources += obj.unmatched_files.files state.update_new_metadata = True state.update_orig_metadata = True elif isinstance(obj, Track): - state.sources = obj.linked_files + state.sources = obj.files state.update_orig_metadata = True elif isinstance(obj, Cluster): state.sources = obj.files diff --git a/test/test_imagelist.py b/test/test_imagelist.py index 57aea56f1..4b0230184 100644 --- a/test/test_imagelist.py +++ b/test/test_imagelist.py @@ -88,22 +88,22 @@ class UpdateMetadataImagesTest(PicardTestCase): def test_update_track_images(self): track = Track('00000000-0000-0000-0000-000000000000') - track.linked_files = list(self.test_files) + track.files = list(self.test_files) update_metadata_images(track) self.assertEqual(set(self.test_images), set(track.orig_metadata.images)) self.assertFalse(track.orig_metadata.has_common_images) - track.linked_files.remove(self.test_files[2]) + track.files.remove(self.test_files[2]) update_metadata_images(track) self.assertEqual(set(self.test_images), set(track.orig_metadata.images)) self.assertFalse(track.orig_metadata.has_common_images) - track.linked_files.remove(self.test_files[0]) + track.files.remove(self.test_files[0]) update_metadata_images(track) self.assertEqual(set(self.test_images[1:]), set(track.orig_metadata.images)) self.assertTrue(track.orig_metadata.has_common_images) - track.linked_files.append(self.test_files[2]) + track.files.append(self.test_files[2]) update_metadata_images(track) self.assertEqual(set(self.test_images[1:]), set(track.orig_metadata.images)) self.assertTrue(track.orig_metadata.has_common_images) @@ -111,9 +111,9 @@ class UpdateMetadataImagesTest(PicardTestCase): def test_update_album_images(self): album = Album('00000000-0000-0000-0000-000000000000') track1 = Track('00000000-0000-0000-0000-000000000001') - track1.linked_files.append(self.test_files[0]) + track1.files.append(self.test_files[0]) track2 = Track('00000000-0000-0000-0000-000000000002') - track2.linked_files.append(self.test_files[1]) + track2.files.append(self.test_files[1]) album.tracks = [track1, track2] album.unmatched_files.files.append(self.test_files[2]) update_metadata_images(album) @@ -171,27 +171,27 @@ class RemoveMetadataImagesTest(PicardTestCase): def test_remove_from_track(self): track = Track('00000000-0000-0000-0000-000000000000') - track.linked_files = list(self.test_files) + track.files = list(self.test_files) update_metadata_images(track) - track.linked_files.remove(self.test_files[0]) + track.files.remove(self.test_files[0]) remove_metadata_images(track, [self.test_files[0]]) self.assertEqual(set(self.test_images[1:]), set(track.orig_metadata.images)) self.assertTrue(track.orig_metadata.has_common_images) def test_remove_from_track_with_common_images(self): track = Track('00000000-0000-0000-0000-000000000000') - track.linked_files = list(self.test_files[1:]) + track.files = list(self.test_files[1:]) update_metadata_images(track) - track.linked_files.remove(self.test_files[1]) + track.files.remove(self.test_files[1]) remove_metadata_images(track, [self.test_files[1]]) self.assertEqual(set(self.test_images[1:]), set(track.orig_metadata.images)) self.assertTrue(track.orig_metadata.has_common_images) def test_remove_from_empty_track(self): track = Track('00000000-0000-0000-0000-000000000000') - track.linked_files.append(File('test1.flac')) + track.files.append(File('test1.flac')) update_metadata_images(track) - remove_metadata_images(track, [track.linked_files[0]]) + remove_metadata_images(track, [track.files[0]]) self.assertEqual(set(), set(track.orig_metadata.images)) self.assertTrue(track.orig_metadata.has_common_images)