diff --git a/picard/tagger.py b/picard/tagger.py index 169543221..71bfa2d1e 100644 --- a/picard/tagger.py +++ b/picard/tagger.py @@ -29,15 +29,17 @@ import sys import picard.resources from picard.album import Album -from picard.cluster import Cluster from picard.api import IFileOpener, ITaggerScript -from picard.browser.filelookup import FileLookup from picard.browser.browser import BrowserIntegration +from picard.browser.filelookup import FileLookup +from picard.cluster import Cluster from picard.component import ComponentManager, Interface, ExtensionPoint, Component from picard.config import Config +from picard.file import File +from picard.metadata import Metadata +from picard.track import Track from picard.ui.mainwindow import MainWindow from picard.worker import WorkerThread -from picard.metadata import Metadata from musicbrainz2.webservice import Query, TrackFilter @@ -180,11 +182,49 @@ class Tagger(QtGui.QApplication, ComponentManager, Component): str(metadata.get("~#length", 0)), metadata["~filename"], metadata["musicip_puid"]) - - def save_files(self, files): - for file in files: + + def get_files_from_objects(self, objects): + """Return list of files from list of albums, clusters, tracks or files.""" + files = [] + for obj in objects: + if isinstance(obj, Album): + for track in obj.tracks: + if track.linked_file and track.linked_file not in files: + files.append(track.linked_file) + elif isinstance(obj, Track): + if obj.linked_file and obj.linked_file not in files: + files.append(obj.linked_file) + elif isinstance(obj, Cluster): + for file in obj.files: + if file not in files: + files.append(file) + elif isinstance(obj, File): + if obj not in files: + files.append(obj) + return files + + def save(self, objects): + """Save the specified objects.""" + for file in self.get_files_from_objects(objects): self.worker.save_file(file) + def remove(self, objects): + """Remove the specified objects.""" + files = [] + albums = [] + for obj in objects: + if isinstance(obj, File): + files.append(obj) + elif isinstance(obj, Track): + if obj.isLinked(): + files.append(obj.getLinkedFile()) + elif isinstance(obj, Album): + albums.append(obj) + if files: + self.remove_files(files) + for album in albums: + self.remove_album(album) + # Albums def load_album(self, albumId): @@ -200,7 +240,7 @@ class Tagger(QtGui.QApplication, ComponentManager, Component): return album return None - def removeAlbum(self, album): + def remove_album(self, album): # Move all linked files to "Unmatched Files" for track in album.tracks: if track.isLinked(): diff --git a/picard/ui/itemviews.py b/picard/ui/itemviews.py index e16027096..00bef85ab 100644 --- a/picard/ui/itemviews.py +++ b/picard/ui/itemviews.py @@ -45,9 +45,9 @@ class BaseTreeView(QtGui.QTreeWidget): TextOption("persist", "album_view_sizes", "250 40 100"), ] - def __init__(self, mainWindow, parent): + def __init__(self, main_window, parent): QtGui.QTreeWidget.__init__(self, parent) - self.mainWindow = mainWindow + self.main_window = main_window self.numHeaderSections = 3 self.setHeaderLabels([_(u"Title"), _(u"Time"), _(u"Artist")]) @@ -215,8 +215,8 @@ class BaseTreeView(QtGui.QTreeWidget): class FileTreeView(BaseTreeView): - def __init__(self, mainWindow, parent): - BaseTreeView.__init__(self, mainWindow, parent) + def __init__(self, main_window, parent): + BaseTreeView.__init__(self, main_window, parent) # Create the context menu @@ -232,7 +232,8 @@ class FileTreeView(BaseTreeView): self.contextMenu.addSeparator() self.contextMenu.addAction(self.lookupAct) self.contextMenu.addAction(self.analyzeAct) - self.contextMenu.addAction(self.mainWindow.remove_action) + self.contextMenu.addAction(self.main_window.save_action) + self.contextMenu.addAction(self.main_window.remove_action) # Prepare some common icons @@ -342,8 +343,8 @@ class FileTreeView(BaseTreeView): class AlbumTreeView(BaseTreeView): - def __init__(self, mainWindow, parent): - BaseTreeView.__init__(self, mainWindow, parent) + def __init__(self, main_window, parent): + BaseTreeView.__init__(self, main_window, parent) self.cdIcon = QtGui.QIcon(":/images/cd.png") self.noteIcon = QtGui.QIcon(":/images/note.png") @@ -357,7 +358,7 @@ class AlbumTreeView(BaseTreeView): ] self.connect(self.tagger, QtCore.SIGNAL("albumAdded"), self.addAlbum) - self.connect(self.tagger, QtCore.SIGNAL("albumRemoved"), self.removeAlbum) + self.connect(self.tagger, QtCore.SIGNAL("albumRemoved"), self.remove_album) self.connect(self.tagger, QtCore.SIGNAL("trackUpdated"), self.updateTrack) self.connect(self.tagger.worker, QtCore.SIGNAL("albumLoaded(QString)"), self.updateAlbum) @@ -408,7 +409,7 @@ class AlbumTreeView(BaseTreeView): albumItem.addChild(item) i += 1 - def removeAlbum(self, album, index): + def remove_album(self, album, index): self.unregisterObject(album) self.takeTopLevelItem(index) diff --git a/picard/ui/mainwindow.py b/picard/ui/mainwindow.py index 56363df69..a9d4a8716 100644 --- a/picard/ui/mainwindow.py +++ b/picard/ui/mainwindow.py @@ -165,8 +165,9 @@ class MainWindow(QtGui.QMainWindow): self.addDirectoryAct.setShortcut(QtGui.QKeySequence(_("Ctrl+D"))) self.connect(self.addDirectoryAct, QtCore.SIGNAL("triggered()"), self.addDirectory) - self.save_action = QtGui.QAction(QtGui.QIcon(":/images/ToolbarSave.png"), _("&Save Selected Files"), self) - # TR: Keyboard shortcut for "Save files" + self.save_action = QtGui.QAction(QtGui.QIcon(":/images/ToolbarSave.png"), _("&Save"), self) + self.addDirectoryAct.setStatusTip(_("Save selected files")) + # TR: Keyboard shortcut for "Save" self.save_action.setShortcut(QtGui.QKeySequence(_("Ctrl+S"))) self.save_action.setEnabled(False) self.connect(self.save_action, QtCore.SIGNAL("triggered()"), self.save) @@ -327,19 +328,15 @@ class MainWindow(QtGui.QMainWindow): def showOptions(self): dlg = OptionsDialogProvider(self.tagger).get_options_dialog(self) dlg.exec_() - + def save(self): - files = [] - for obj in self.selected_objects: - if isinstance(obj, File): - files.append(obj) - elif isinstance(obj, Track): - if obj.linked_file: - files.append(obj.linked_file) - - if files: - self.tagger.save_files(files) - + """Tell the tagger to save the selected objects.""" + self.tagger.save(self.selected_objects) + + def remove(self): + """Tell the tagger to remove the selected objects.""" + self.tagger.remove(self.selected_objects) + def listen(self): pass @@ -378,7 +375,7 @@ class MainWindow(QtGui.QMainWindow): self.save_action.setEnabled(can_save) def updateSelection(self, objects=None): - if objects: + if objects is not None: self.selected_objects = objects else: objects = self.selected_objects @@ -415,25 +412,6 @@ class MainWindow(QtGui.QMainWindow): self.serverMetadataBox.setMetadata(serverMetadata, isAlbum, file_id=file_id) self.setStatusBarMessage(statusBar) - def remove(self): - files = [] - albums = [] - for obj in self.selected_objects: - if isinstance(obj, File): - files.append(obj) - elif isinstance(obj, Track): - if obj.isLinked(): - files.append(obj.getLinkedFile()) - elif isinstance(obj, Album): - albums.append(obj) - - if files: - self.tagger.remove_files(files) - - for album in albums: - self.tagger.removeAlbum(album) - - def showCoverArt(self): """Show/hide the cover art box.""" if self.showCoverArtAct.isChecked():