Skip to content

Commit

Permalink
Fix being able to delete folder from Playlists-Directories panel
Browse files Browse the repository at this point in the history
  • Loading branch information
Borewit committed Feb 26, 2023
1 parent 1c325d6 commit 688464e
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 128 deletions.
2 changes: 1 addition & 1 deletion src/main/java/listfix/io/FileTreeNodeGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public static PlaylistTreeNode addNodes(PlaylistTreeNode curTop, Stream<Path> fi
}


public static Path TreePathToFileSystemPath(TreePath node)
public static Path treePathToFileSystemPath(TreePath node)
{
return ((PlaylistTreeNode) node.getLastPathComponent()).getUserObject();
}
Expand Down
37 changes: 10 additions & 27 deletions src/main/java/listfix/io/FileUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Stream;

public class FileUtils
{
Expand Down Expand Up @@ -97,37 +98,19 @@ public static String replaceInvalidWindowsFileSystemCharsWithChar(String input,
return result.toString();
}

public static void deleteDirectory(Path dirOrFile)
/**
* Delete recursive
* @param directory Folder to delete
*/
public static void deleteDirectory(Path directory) throws IOException
{
if (Files.isDirectory(dirOrFile))
{
try
{
Files.list(dirOrFile).forEach(FileUtils :: deleteDirectory);
}
catch (IOException e)
{
throw new RuntimeException(e);
}
}
else
{
try
{
Files.deleteIfExists(dirOrFile);
}
catch (IOException e)
{
throw new RuntimeException(e);
}
try (Stream<Path> walk = Files.walk(directory)) {
walk
.map(Path::toFile)
.forEach(File::delete);
}
}

public static void deleteDirectory(File dir)
{
FileUtils.deleteDirectory(dir.toPath());
}

/**
* Extract the extension from the provided filename
*
Expand Down
204 changes: 104 additions & 100 deletions src/main/java/listfix/view/GUIScreen.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.plaf.FontUIResource;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreePath;
import javax.xml.bind.JAXBException;
import java.awt.*;
Expand Down Expand Up @@ -180,30 +179,6 @@ private void postInitComponents()
// addAt popup menu to playlist tree on right-click
_playlistDirectoryTree.addMouseListener(createPlaylistTreeMouseListener());

addPlaylistPanelModelListener();

// _documentPane.setGroupsAllowed(false);
// _documentPane.setFloatingAllowed(false);
// _documentPane.setTabbedPaneCustomizer(createTabCustomizer());
// _documentPane.setTabColorProvider(createTabColorProvider());

// Load the position the window was in when it was last closed.
WindowSaver.getInstance().loadSettings(this);

// Set the position of the divider in the left split pane.
_leftSplitPane.setDividerLocation(.7);

updateMenuItemStatuses();

// JCaron - 2012.05.03 - Global listener for Ctrl-Tab and Ctrl-Shift-Tab
configureGlobalKeyboardListener();

// Stop showing the loading screen
splashScreen.setVisible(false);
}

private void addPlaylistPanelModelListener()
{
_playlistDirectoryTree.getModel().addTreeModelListener(new TreeModelListener()
{
@Override
Expand All @@ -230,6 +205,20 @@ public void treeStructureChanged(TreeModelEvent e)
recheckStatusOfOpenPlaylists();
}
});

// Load the position the window was in when it was last closed.
WindowSaver.getInstance().loadSettings(this);

// Set the position of the divider in the left split pane.
_leftSplitPane.setDividerLocation(.7);

updateMenuItemStatuses();

// JCaron - 2012.05.03 - Global listener for Ctrl-Tab and Ctrl-Shift-Tab
configureGlobalKeyboardListener();

// Stop showing the loading screen
splashScreen.setVisible(false);
}

private void recheckStatusOfOpenPlaylists()
Expand Down Expand Up @@ -322,18 +311,19 @@ private void handleMouseEvent(MouseEvent e)
_miExactMatchesSearch.setEnabled(true);
_miClosestMatchesSearch.setEnabled(true);
_miOpenSelectedPlaylists.setEnabled(true);
_miDeletePlaylist.setEnabled(true);
_miRenameSelectedItem.setEnabled(_playlistDirectoryTree.getSelectionCount() == 1
&& !allTopLevel
&& Files.isRegularFile(GUIScreen.this.getSelectedPlaylistTreeNodes().get(0).getUserObject())
);
boolean singleFileSelected = _playlistDirectoryTree.getSelectionCount() == 1;
_miRenameSelectedItem.setEnabled(singleFileSelected
&& !allTopLevel
&& Files.isRegularFile(GUIScreen.this.getSelectedPlaylistTreeNodes().get(0).getUserObject())
);
_miDeleteFile.setEnabled(true);
}
else
{
_miExactMatchesSearch.setEnabled(false);
_miClosestMatchesSearch.setEnabled(false);
_miOpenSelectedPlaylists.setEnabled(false);
_miDeletePlaylist.setEnabled(false);
_miDeleteFile.setEnabled(false);
_miRenameSelectedItem.setEnabled(false);
}

Expand Down Expand Up @@ -392,7 +382,7 @@ protected Transferable createTransferable(JComponent c)
for (int selRow : _playlistDirectoryTree.getSelectionRows())
{
TreePath selPath = _playlistDirectoryTree.getPathForRow(selRow);
paths.add(FileTreeNodeGenerator.TreePathToFileSystemPath(selPath).toString());
paths.add(FileTreeNodeGenerator.treePathToFileSystemPath(selPath).toString());
}

String serializedPaths = StringArrayListSerializer.serialize(paths);
Expand Down Expand Up @@ -607,7 +597,7 @@ private void initComponents()
_miOpenSelectedPlaylistLocation = new javax.swing.JMenuItem();
_miExactMatchesSearch = new javax.swing.JMenuItem();
_miClosestMatchesSearch = new javax.swing.JMenuItem();
_miDeletePlaylist = new javax.swing.JMenuItem();
_miDeleteFile = new javax.swing.JMenuItem();
_miRenameSelectedItem = new javax.swing.JMenuItem();
_statusPanel = new javax.swing.JPanel();
statusLabel = new javax.swing.JLabel();
Expand Down Expand Up @@ -671,7 +661,7 @@ private void initComponents()

_miRemovePlaylistDirectory.setText("Remove Playlist Directory");
_miRemovePlaylistDirectory.setToolTipText("Remove playlist directory from configuration");
_miRemovePlaylistDirectory.addActionListener(evt -> this.removePlaylistDirectory());
_miRemovePlaylistDirectory.addActionListener(evt -> this.removePlaylistDirectory(this._playlistDirectoryTree.getSelectionPaths()));
_playlistTreeRightClickMenu.add(_miRemovePlaylistDirectory);

_miRefreshDirectoryTree.setText("Refresh");
Expand All @@ -694,11 +684,11 @@ private void initComponents()
_miClosestMatchesSearch.addActionListener(evt -> _miClosestMatchesSearchActionPerformed(evt));
_playlistTreeRightClickMenu.add(_miClosestMatchesSearch);

_miDeletePlaylist.setMnemonic('D');
_miDeletePlaylist.setText("Delete file");
_miDeletePlaylist.setToolTipText("Delete selected playlist file");
_miDeletePlaylist.addActionListener(evt -> _miDeletePlaylistActionPerformed(evt));
_playlistTreeRightClickMenu.add(_miDeletePlaylist);
_miDeleteFile.setMnemonic('D');
_miDeleteFile.setText("Delete file(s)");
_miDeleteFile.setToolTipText("Delete selected file(s)");
_miDeleteFile.addActionListener(evt -> _miDeletePlaylistActionPerformed(evt));
_playlistTreeRightClickMenu.add(_miDeleteFile);

_miRenameSelectedItem.setMnemonic('R');
_miRenameSelectedItem.setAccelerator(KeyStroke.getKeyStroke(keyEventRenameFile, 0));
Expand Down Expand Up @@ -1277,71 +1267,86 @@ private List<Path> getSelectedFilesFromTreePlaylists()
{
return Collections.emptyList();
}
return Arrays.stream(paths).map(FileTreeNodeGenerator :: TreePathToFileSystemPath).collect(Collectors.toList());
return Arrays.stream(paths).map(FileTreeNodeGenerator :: treePathToFileSystemPath).collect(Collectors.toList());
}

private void deleteTreeSelectedPlaylists()
{
int[] selRows = _playlistDirectoryTree.getSelectionRows();
if (selRows != null && selRows.length > 0)
if (selRows == null ||
selRows.length == 0 ||
JOptionPane.showConfirmDialog(this, new JTransparentTextArea("Are you sure you want to delete the selected file?"), "Delete Selected File?", JOptionPane.YES_NO_OPTION) == JOptionPane.NO_OPTION)
{
if (JOptionPane.showConfirmDialog(this, new JTransparentTextArea("Are you sure you want to delete the selected file?"), "Delete Selected File?", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION)
return;
}
final List<Path> playlistsDirectoriesToRemove = new LinkedList<>();
for (TreePath selPath : this.getSelectedPlaylistTreePaths())
{
PlaylistTreeNode treeNode = (PlaylistTreeNode) selPath.getLastPathComponent();
Path toDelete = ((PlaylistTreeNode)selPath.getLastPathComponent()).getUserObject();
if (Files.isDirectory(toDelete))
{
List<TreePath> selPaths = new ArrayList<>();
for (int i : selRows)
try {
FileUtils.deleteDirectory(toDelete);
Files.delete(toDelete);
} catch(IOException ioe) {
final String message = String.format("Failed to delete folder: %s: %s", toDelete, ioe.getMessage());
_logger.error(message, ioe);
JOptionPane.showMessageDialog(this, message, "Deleting Playlist Failed", JOptionPane.WARNING_MESSAGE);
}
if (treeNode.getParent() == null)
{
selPaths.add(_playlistDirectoryTree.getPathForRow(i));
// Node is a configured playlist directory
playlistsDirectoriesToRemove.add(treeNode.getUserObject());
}
for (TreePath selPath : selPaths)
}
else
{
if (Files.isWritable(toDelete))
{
Path toOpen = FileTreeNodeGenerator.TreePathToFileSystemPath(selPath);
if (Files.isDirectory(toOpen))
try
{
FileUtils.deleteDirectory(toOpen);
DefaultTreeModel treeModel = (DefaultTreeModel) _playlistDirectoryTree.getModel();
treeModel.removeNodeFromParent((MutableTreeNode) selPath.getLastPathComponent());
Files.delete(toDelete);
}
else
catch (IOException e)
{
if (Files.isWritable(toOpen))
{
try
{
Files.delete(toOpen);
}
catch (IOException e)
{
throw new RuntimeException(e);
}
_playlistDirectoryTree.makeVisible(selPath);
DefaultTreeModel treeModel = (DefaultTreeModel) _playlistDirectoryTree.getModel();
treeModel.removeNodeFromParent((MutableTreeNode) selPath.getLastPathComponent());
this._playlistTabbedPane.remove(toOpen);
}
else
{
final String fileShortname = toOpen.getFileName().toString();
JOptionPane.showMessageDialog(this, String.format("Failed to delete playlist: %s", fileShortname), "Deleting Playlist Failed", JOptionPane.WARNING_MESSAGE);
}
throw new RuntimeException(e);
}
this._playlistDirectoryTree.makeVisible(selPath);
DefaultTreeModel treeModel = (DefaultTreeModel) this._playlistDirectoryTree.getModel();
treeModel.removeNodeFromParent(treeNode);
this._playlistTabbedPane.remove(toDelete);
}
else
{
final String fileShortname = toDelete.getFileName().toString();
JOptionPane.showMessageDialog(this, String.format("Failed to delete playlist: %s", fileShortname), "Deleting Playlist Failed", JOptionPane.WARNING_MESSAGE);
}
}
}
this.removePlaylistDirectory(playlistsDirectoriesToRemove);
}

public List<PlaylistTreeNode> getSelectedPlaylistTreeNodes()
public List<TreePath> getSelectedPlaylistTreePaths()
{
int[] selRows = _playlistDirectoryTree.getSelectionRows();
if (selRows != null) {
return Arrays.stream(selRows).mapToObj(i -> (PlaylistTreeNode) _playlistDirectoryTree.getPathForRow(i).getLastPathComponent()).collect(Collectors.toList());
if (selRows != null)
{
return Arrays.stream(selRows).mapToObj(i -> _playlistDirectoryTree.getPathForRow(i)).collect(Collectors.toList());
}
return Collections.emptyList();
}

public List<PlaylistTreeNode> getSelectedPlaylistTreeNodes()
{
return this.getSelectedPlaylistTreePaths().stream().map(path -> (PlaylistTreeNode)path.getLastPathComponent()).collect(Collectors.toList());
}

private void renameTreeSelectedNode()
{
List<PlaylistTreeNode> selectedTreeNodes = getSelectedPlaylistTreeNodes();
if (selectedTreeNodes.size() != 1) {
if (selectedTreeNodes.size() != 1)
{
_logger.debug(String.format("Will only rename when exactly 1 file is selected, got %s.", selectedTreeNodes.size()));
return;
}
Expand Down Expand Up @@ -1380,7 +1385,7 @@ private void renameTreeSelectedNode()

private void playlistDirectoryTreeNodeDoubleClicked(TreePath selPath)
{
Path toOpen = FileTreeNodeGenerator.TreePathToFileSystemPath(selPath);
Path toOpen = FileTreeNodeGenerator.treePathToFileSystemPath(selPath);
if (Files.isRegularFile(toOpen))
{
this.openPlaylist(toOpen);
Expand Down Expand Up @@ -2644,7 +2649,6 @@ private void updatePlaylistDirectoryPanel()
{
DefaultTreeModel treeModel = (DefaultTreeModel) this._playlistDirectoryTree.getModel();
treeModel.setRoot(playlistTreeNode);
addPlaylistPanelModelListener();
loadExpansionState(this._playlistDirectoryTree, treeStateEnum);
}
finally
Expand All @@ -2658,30 +2662,30 @@ private void updatePlaylistDirectoryPanel()
}
}

private void removePlaylistDirectory()
private void removePlaylistDirectory(TreePath[] selectedPath)
{
TreePath[] selectedPath = this._playlistDirectoryTree.getSelectionPaths();
if (selectedPath != null)
{
for (TreePath treePath : selectedPath)
{
FileTreeNodeGenerator.TreePathToFileSystemPath(treePath);
}
Arrays.stream(selectedPath)
.map(FileTreeNodeGenerator :: TreePathToFileSystemPath)
.forEach(playlistDirectory -> {
_logger.info(String.format("Removing playlist directory from configuration: %s", playlistDirectory));
this.getApplicationConfig().getPlaylistDirectories().remove(playlistDirectory.toString());
});
this.updatePlaylistDirectoryPanel();
try
{
this._listFixController.getApplicationConfiguration().write();
}
catch (IOException e)
{
throw new RuntimeException("Failed to write updated application configuration", e);
}
removePlaylistDirectory(Arrays.stream(selectedPath)
.map(FileTreeNodeGenerator :: treePathToFileSystemPath)
.collect(Collectors.toList()));
}
}

private void removePlaylistDirectory(Collection<Path> selectedPath)
{
selectedPath.forEach(playlistDirectory -> {
_logger.info(String.format("Removing playlist directory from configuration: %s", playlistDirectory));
this.getApplicationConfig().getPlaylistDirectories().remove(playlistDirectory.toString());
});
this.updatePlaylistDirectoryPanel();
try
{
this._listFixController.getApplicationConfiguration().write();
}
catch (IOException e)
{
throw new RuntimeException("Failed to write updated application configuration", e);
}
}

Expand Down Expand Up @@ -2836,7 +2840,7 @@ public static void main(String[] args) throws IOException, InterruptedException,
private javax.swing.JMenuItem _miBatchRepair;
private javax.swing.JMenuItem _miClosestMatchRepairOpenPlaylists;
private javax.swing.JMenuItem _miClosestMatchesSearch;
private javax.swing.JMenuItem _miDeletePlaylist;
private javax.swing.JMenuItem _miDeleteFile;
private javax.swing.JMenuItem _miExactMatchRepairOpenPlaylists;
private javax.swing.JMenuItem _miExactMatchesSearch;
private javax.swing.JMenuItem _miOpenSelectedPlaylists;
Expand Down

0 comments on commit 688464e

Please sign in to comment.