/* * Jajuk * Copyright (C) The Jajuk Team * http://jajuk.info * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ package org.jajuk.ui.actions; import java.awt.event.ActionEvent; import java.util.ArrayList; import java.util.List; import javax.swing.JOptionPane; import javax.swing.KeyStroke; import org.jajuk.base.Album; import org.jajuk.base.Artist; import org.jajuk.base.Directory; import org.jajuk.base.DirectoryManager; import org.jajuk.base.File; import org.jajuk.base.FileManager; import org.jajuk.base.Genre; import org.jajuk.base.Item; import org.jajuk.base.Playlist; import org.jajuk.base.PlaylistManager; import org.jajuk.base.Track; import org.jajuk.base.TrackManager; import org.jajuk.events.JajukEvent; import org.jajuk.events.JajukEvents; import org.jajuk.events.ObservationManager; import org.jajuk.services.players.QueueModel; import org.jajuk.services.webradio.WebRadio; import org.jajuk.services.webradio.WebRadioManager; import org.jajuk.ui.widgets.InformationJPanel; import org.jajuk.util.Conf; import org.jajuk.util.Const; import org.jajuk.util.IconLoader; import org.jajuk.util.JajukIcons; import org.jajuk.util.Messages; import org.jajuk.util.UtilGUI; import org.jajuk.util.UtilSystem; import org.jajuk.util.log.Log; /** * . */ public class DeleteSelectionAction extends SelectionAction { /** Generated serialVersionUID. */ private static final long serialVersionUID = 1L; private List<File> alFiles; private List<File> rejFiles; private List<Directory> alDirs; private List<Directory> rejDirs; private List<Directory> emptyDirs; /** * Instantiates a new delete selection action. */ DeleteSelectionAction() { super(Messages.getString("FilesTreeView.7"), IconLoader.getIcon(JajukIcons.DELETE), true); setAcceleratorKey(KeyStroke.getKeyStroke("DELETE")); setShortDescription(Messages.getString("FilesTreeView.7")); } /** * Called on files deletion (long task). */ class FilesDeletionThread extends Thread { /** * Instantiates a new files deletion thread. */ FilesDeletionThread() { super("Files Deletion Thread"); } /* (non-Javadoc) * @see java.lang.Thread#run() */ @Override public void run() { UtilGUI.waiting(); for (File f : alFiles) { try { Directory d = f.getDirectory(); UtilSystem.deleteFile(f.getFIO()); FileManager.getInstance().removeFile(f); if (d.getFiles().size() == 0) { emptyDirs.add(f.getDirectory()); } } catch (Exception ioe) { Log.error(131, ioe); rejFiles.add(f); } } UtilGUI.stopWaiting(); InformationJPanel.getInstance().setMessage(Messages.getString("ActionDelete.0"), InformationJPanel.MessageType.INFORMATIVE); if (rejFiles.size() > 0) { String rejString = ""; for (File f : rejFiles) { rejString += f.getName() + "\n"; } // Operation failed... display list of files in error Messages.showWarningMessage(Messages.getErrorMessage(136) + "\n" + rejString); } // requires device refresh ObservationManager.notify(new JajukEvent(JajukEvents.DEVICE_REFRESH)); } } /** * Called on directories deletion (long task). */ class DirectoriesDeletionThread extends Thread { /** * Instantiates a new directories deletion thread. */ DirectoriesDeletionThread() { super("Directories Deletion Thread"); } /* (non-Javadoc) * @see java.lang.Thread#run() */ @Override public void run() { UtilGUI.waiting(); for (Directory d : alDirs) { try { for (File f : d.getFiles()) { if (QueueModel.getPlayingFile() != null && f.equals(QueueModel.getPlayingFile())) { throw new Exception("File currently in use"); } } UtilSystem.deleteDir(new java.io.File(d.getAbsolutePath())); DirectoryManager.getInstance().removeDirectory(d.getID()); } catch (Exception ioe) { Log.error(131, ioe); rejDirs.add(d); } } UtilGUI.stopWaiting(); InformationJPanel.getInstance().setMessage(Messages.getString("ActionDelete.1"), InformationJPanel.MessageType.INFORMATIVE); if (rejDirs.size() > 0) { String rejString = ""; for (Directory d : rejDirs) { rejString += d.getName() + "\n"; } // Operation failed... display list of files in error Messages.showWarningMessage(Messages.getErrorMessage(136) + "\n\n" + rejString); } // requires device refresh ObservationManager.notify(new JajukEvent(JajukEvents.DEVICE_REFRESH)); } } /* * (non-Javadoc) * * @see org.jajuk.ui.actions.SelectionAction#perform(java.awt.event.ActionEvent) */ @Override public void perform(ActionEvent e) throws Exception { // Make sure to consider selection as a raw playlist, not its content expandPlaylists = false; super.perform(e); // Get required data from the tree (selected node and node type) alFiles = new ArrayList<File>(selection.size()); rejFiles = new ArrayList<File>(selection.size()); alDirs = new ArrayList<Directory>(selection.size()); rejDirs = new ArrayList<Directory>(selection.size()); emptyDirs = new ArrayList<Directory>(selection.size()); // Compute all files to move from various items list if (selection.size() == 0) { Log.debug("None item to move"); return; } Item first = selection.get(0); if (first instanceof Album || first instanceof Artist || first instanceof Genre) { List<Track> tracks = TrackManager.getInstance().getAssociatedTracks(selection, true); for (Track track : tracks) { alFiles.addAll(track.getFiles()); } } else { for (Item item : selection) { if (item instanceof WebRadio) { WebRadioManager.getInstance().removeItem(item); ObservationManager.notify(new JajukEvent(JajukEvents.DEVICE_REFRESH)); } else if (item instanceof File) { alFiles.add((File) item); } else if (item instanceof Track) { alFiles.addAll(((Track) item).getFiles()); } else if (item instanceof Directory) { alDirs.add((Directory) item); } else if ((item instanceof Playlist) && (Conf.getBoolean(Const.CONF_CONFIRMATIONS_DELETE_FILE))) { // file delete confirmation Playlist plf = (Playlist) item; String sFileToDelete = plf.getAbsolutePath(); String sMessage = Messages.getString("Confirmation_delete") + "\n" + sFileToDelete; int i = Messages.getChoice(sMessage, JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); if (i == JOptionPane.YES_OPTION) { try { PlaylistManager.getInstance().deletePlaylistFile(plf); // requires device refresh ObservationManager.notify(new JajukEvent(JajukEvents.DEVICE_REFRESH)); } catch (Exception e2) { Log.error(e2); Messages.showErrorMessage(131); } } } } } // Consider files (selection can contain both files and directories) if (alFiles.size() > 0) { handleFiles(); } // Now consider directories (selection can contain both files and directories) if (alDirs.size() > 0) { handleDirectories(); } } /** * Handle directories. */ private void handleDirectories() { // Ask if a confirmation is required if (Conf.getBoolean(Const.CONF_CONFIRMATIONS_DELETE_FILE)) { String sFiles = ""; int count = 0; for (Directory d : alDirs) { sFiles += d.getAbsolutePath() + "\n"; count += d.getFilesRecursively().size(); for (File f : d.getFilesRecursively()) { sFiles += " + " + f.getName() + "\n"; } } int iResu = Messages.getChoice(Messages.getString("Confirmation_delete_dirs") + " : \n" + sFiles + "\n" + count + " " + Messages.getString("Confirmation_file_number"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE); if (iResu != JOptionPane.YES_OPTION) { return; } // Check if selection doesn't contain playing file's directory for (Directory dir : alDirs) { if (QueueModel.getPlayingFile() != null && QueueModel.getPlayingFile().hasAncestor(dir)) { Messages .showWarningMessage(Messages.getErrorMessage(172) + " : " + dir.getAbsolutePath()); return; } } } //Actual deletion new DirectoriesDeletionThread().start(); } /** * Handle files. */ private void handleFiles() { // Ask if a confirmation is required if (Conf.getBoolean(Const.CONF_CONFIRMATIONS_DELETE_FILE)) { String sFiles = ""; for (File f : alFiles) { sFiles += f.getName() + "\n"; } int iResu = Messages.getChoice(Messages.getString("Confirmation_delete_files") + " : \n\n" + sFiles + "\n" + alFiles.size() + " " + Messages.getString("Confirmation_file_number"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE); if (iResu != JOptionPane.YES_OPTION) { return; } } // Check if selection doesn't contain playing file for (File f : alFiles) { if (QueueModel.getPlayingFile() != null && f.equals(QueueModel.getPlayingFile())) { Messages.showWarningMessage(Messages.getErrorMessage(172) + " : " + f.getAbsolutePath()); return; } } //Actual deletion new FilesDeletionThread().start(); // Cleanup empty directories if (emptyDirs.size() > 0) { String emptyDirsString = ""; for (Directory d : emptyDirs) { emptyDirsString += d.getName() + "\n"; } int iResu = Messages.getChoice(Messages.getString("Confirmation_delete_empty_dirs") + " : \n\n" + emptyDirsString, JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE); if (iResu != JOptionPane.YES_OPTION) { return; } else { for (Directory d : emptyDirs) { try { UtilSystem.deleteDir(new java.io.File(d.getAbsolutePath())); DirectoryManager.getInstance().removeDirectory(d.getID()); } catch (Exception ioe) { Log.error(131, ioe); rejDirs.add(d); } } if (rejDirs.size() > 0) { String rejString = ""; for (Directory d : rejDirs) { rejString += d.getName() + "\n"; } // Operation failed... display list of files in error Messages.showWarningMessage(Messages.getErrorMessage(136) + "\n" + rejString); } // requires device refresh ObservationManager.notify(new JajukEvent(JajukEvents.DEVICE_REFRESH)); } } } }