Skip to content

Commit d0c102c

Browse files
authored
Support for multiple playlist folders (#93)
- Add support for multiple playlist folders - Removed are you sure dialog before showing renaming dialog - Keep playlist-editor-tabs in sync with playlists-directories - Disabling renaming multiple files - Disabling renaming playlists - Fixing issues with tab headers of playlist-editors
1 parent 9a57f94 commit d0c102c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1410
-1907
lines changed

src/main/java/listfix/io/TreeNodeFile.java renamed to src/main/java/listfix/comparators/DirectoryThenFileThenAlphabeticalPathComparator.java

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,30 +18,32 @@
1818
* along with this program; if not, please see http://www.gnu.org/licenses/
1919
*/
2020

21-
package listfix.io;
21+
package listfix.comparators;
22+
23+
import java.nio.file.Files;
24+
import java.nio.file.Path;
2225

2326
/**
24-
*
25-
* @author jcaron
27+
* Sorts directories ahead of files, and then sorts files alphabetically (ignoring case).
2628
*/
27-
public class TreeNodeFile extends java.io.File
29+
public class DirectoryThenFileThenAlphabeticalPathComparator implements java.util.Comparator<Path>
2830
{
29-
/**
30-
*
31-
* @param filename
32-
*/
33-
public TreeNodeFile(String filename)
34-
{
35-
super(filename);
36-
}
3731

38-
/**
39-
*
40-
* @return
41-
*/
4232
@Override
43-
public String toString()
33+
public int compare(Path a, Path b)
4434
{
45-
return this.getName();
35+
if (!Files.isDirectory(a) && Files.isDirectory(b))
36+
{
37+
return 1;
38+
}
39+
else if (Files.isDirectory(a) && !Files.isDirectory(b))
40+
{
41+
return -1;
42+
}
43+
else
44+
{
45+
// both Files are files or both are directories
46+
return a.compareTo(b);
47+
}
4648
}
4749
}

src/main/java/listfix/config/IAppOptions.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public interface IAppOptions extends IPlaylistOptions
1717
String getPlaylistsDirectory();
1818

1919
/**
20-
* @return the appFont
20+
* @return configured application font
2121
*/
2222
Font getAppFont();
2323
}

src/main/java/listfix/config/IMediaLibrary.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,19 @@
44

55
public interface IMediaLibrary
66
{
7-
Set<String> getDirectories();
7+
/**
8+
* User configured top level media directories.
9+
* Used to search media files in
10+
*/
11+
Set<String> getMediaDirectories();
812

13+
/**
14+
* Cached nested directories, derived from media-directories
15+
*/
916
Set<String> getNestedDirectories();
1017

18+
/**
19+
* Cached nested files, derived from media-directories
20+
*/
1121
Set<String> getNestedMediaFiles();
1222
}

src/main/java/listfix/config/JsonConfigFile.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
public abstract class JsonConfigFile<T>
1515
{
16-
public static final Logger _logger = LogManager.getLogger(JsonConfigFile.class);
16+
public final Logger logger = LogManager.getLogger(JsonConfigFile.class);
1717

1818
protected final File jsonFile;
1919
protected T jsonPojo = null;

src/main/java/listfix/config/MediaLibraryConfiguration.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,9 @@ private void clearMediaLibraryDirectoryList()
4646
this.jsonPojo.getNestedDirectories().clear();
4747
}
4848

49-
/**
50-
* @param dir
51-
* @return
52-
* @throws MediaDirNotFoundException
53-
*/
5449
public void removeMediaDir(String dir) throws MediaDirNotFoundException
5550
{
56-
final Set<String> mediaDir = this.jsonPojo.getDirectories();
51+
final Set<String> mediaDir = this.jsonPojo.getMediaDirectories();
5752
final boolean found = mediaDir.remove(dir);
5853

5954
if (found)
@@ -80,7 +75,7 @@ public void removeMediaDir(String dir) throws MediaDirNotFoundException
8075

8176
public void cleanNonExistingMediaDirectories() throws MediaDirNotFoundException
8277
{
83-
for (String dir : new ArrayList<>(this.jsonPojo.getDirectories()))
78+
for (String dir : new ArrayList<>(this.jsonPojo.getMediaDirectories()))
8479
{
8580
if (!new File(dir).exists())
8681
{
@@ -116,6 +111,7 @@ public void switchMediaLibraryToUNCPaths()
116111
*/
117112
public void writeOnBackground()
118113
{
114+
this.logger.info("Writing media-library-configuration in background");
119115
WriteMediaLibraryIniTask thisTask = new WriteMediaLibraryIniTask(this);
120116
thisTask.start();
121117
}

src/main/java/listfix/controller/ListFixController.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@ private ListFixController()
4141
this.mediaLibraryConfiguration = MediaLibraryConfiguration.load();
4242
this.applicationOptionsConfiguration = ApplicationOptionsConfiguration.load();
4343

44+
String oldPlaylistDirectory = this.applicationOptionsConfiguration.getConfig().getPlaylistsDirectory();
45+
if (this.applicationOptionsConfiguration.getConfig().getPlaylistDirectories().isEmpty() && oldPlaylistDirectory != null && !oldPlaylistDirectory.isEmpty()) {
46+
_logger.error(String.format("Migrating playlists directory: %s", oldPlaylistDirectory));
47+
this.applicationOptionsConfiguration.getConfig().getPlaylistDirectories().add(oldPlaylistDirectory);
48+
this.mediaLibraryConfiguration.writeOnBackground();
49+
}
50+
4451
this.history = new PlaylistHistory(this.applicationOptionsConfiguration.getConfig().getMaxPlaylistHistoryEntries());
4552
this.history.load();
4653

src/main/java/listfix/controller/MediaLibraryOperator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public MediaLibraryOperator(ProgressWorker observer)
4747

4848
public void addDirectory(String dir)
4949
{
50-
final Set<String> mediaDir = this.mediaLibraryConfiguration.getConfig().getDirectories();
50+
final Set<String> mediaDir = this.mediaLibraryConfiguration.getConfig().getMediaDirectories();
5151
mediaDir.add(dir);
5252
DirectoryScanner ds = new DirectoryScanner();
5353
ds.createMediaLibraryDirectoryAndFileList(mediaDir, _observer);
@@ -79,7 +79,7 @@ private static void replaceSetValues(Set<String> set, Collection<String> newValu
7979
public void refresh()
8080
{
8181
DirectoryScanner ds = new DirectoryScanner();
82-
ds.createMediaLibraryDirectoryAndFileList(this.mediaLibraryConfiguration.getConfig().getDirectories(), _observer);
82+
ds.createMediaLibraryDirectoryAndFileList(this.mediaLibraryConfiguration.getConfig().getMediaDirectories(), _observer);
8383
if (!_observer.getCancelled())
8484
{
8585
_observer.setMessage("Finishing...");

src/main/java/listfix/io/Constants.java

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,3 @@
1-
/*
2-
* listFix() - Fix Broken Playlists!
3-
* Copyright (C) 2001-2014 Jeremy Caron
4-
*
5-
* This file is part of listFix().
6-
*
7-
* This program is free software; you can redistribute it and/or
8-
* modify it under the terms of the GNU General Public License
9-
* as published by the Free Software Foundation; either version 2
10-
* of the License, or (at your option) any later version.
11-
*
12-
* This program is distributed in the hope that it will be useful,
13-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15-
* GNU General Public License for more details.
16-
*
17-
* You should have received a copy of the GNU General Public License
18-
* along with this program; if not, please see http://www.gnu.org/licenses/
19-
*/
20-
211
package listfix.io;
222

233
import java.io.File;
@@ -60,4 +40,5 @@ public class Constants
6040
* Boolean specifying if the current OS's file system is case-sensitive.
6141
*/
6242
public static final boolean FILE_SYSTEM_IS_CASE_SENSITIVE = File.separatorChar == '/';
43+
6344
}
Lines changed: 44 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,114 +1,65 @@
1-
/*
2-
* listFix() - Fix Broken Playlists!
3-
* Copyright (C) 2001-2014 Jeremy Caron
4-
*
5-
* This file is part of listFix().
6-
*
7-
* This program is free software; you can redistribute it and/or
8-
* modify it under the terms of the GNU General Public License
9-
* as published by the Free Software Foundation; either version 2
10-
* of the License, or (at your option) any later version.
11-
*
12-
* This program is distributed in the hope that it will be useful,
13-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15-
* GNU General Public License for more details.
16-
*
17-
* You should have received a copy of the GNU General Public License
18-
* along with this program; if not, please see http://www.gnu.org/licenses/
19-
*/
20-
211
package listfix.io;
222

23-
import listfix.comparators.DirectoryThenFileThenAlphabeticalFileComparator;
24-
import listfix.io.filters.PlaylistFileFilter;
3+
import listfix.comparators.DirectoryThenFileThenAlphabeticalPathComparator;
4+
import listfix.model.playlists.Playlist;
255
import listfix.view.support.PlaylistTreeNode;
6+
import org.apache.logging.log4j.LogManager;
7+
import org.apache.logging.log4j.Logger;
268

279
import javax.swing.tree.TreePath;
28-
import java.io.File;
29-
import java.util.ArrayList;
30-
import java.util.Arrays;
31-
import java.util.Collections;
32-
import java.util.List;
10+
import java.io.IOException;
11+
import java.nio.file.Files;
12+
import java.nio.file.Path;
13+
14+
import java.util.Collection;
15+
import java.util.stream.Stream;
16+
3317

34-
/**
35-
*
36-
* @author jcaron
37-
*/
3818
public class FileTreeNodeGenerator
3919
{
40-
/** Add nodes from under "dir" into curTop. Highly recursive.
41-
* @param curTop
42-
* @param dir
43-
* @return
44-
*/
45-
public static PlaylistTreeNode addNodes(PlaylistTreeNode curTop, File dir)
46-
{
47-
if (dir.exists())
48-
{
49-
String curPath = dir.getPath();
50-
TreeNodeFile file = new TreeNodeFile(curPath);
51-
PlaylistTreeNode curDir = new PlaylistTreeNode(file);
52-
// curDir.setUserObject(file);
53-
54-
// if we're creating the root node here, use a regular file to get the full path to show.
55-
if (curTop == null)
56-
{
57-
curDir.setUserObject(new File(curPath));
58-
}
20+
private static final Logger logger = LogManager.getLogger(FileTreeNodeGenerator.class);
5921

60-
List<File> ol = new ArrayList<>();
61-
File[] inodes = dir.listFiles(new PlaylistFileFilter());
22+
public static PlaylistTreeNode addNodes(PlaylistTreeNode curTop, Collection<Path> playlistDirectories)
23+
{
24+
return FileTreeNodeGenerator.addNodes(curTop, playlistDirectories.stream());
25+
}
6226

63-
if (inodes != null && inodes.length > 0)
64-
{
65-
ol.addAll(Arrays.asList(inodes));
66-
Collections.sort(ol, new DirectoryThenFileThenAlphabeticalFileComparator());
67-
File f;
68-
List<File> files = new ArrayList<>();
69-
// Make two passes, one for Dirs and one for Files. This is #1.
70-
for (File ol1 : ol)
27+
/**
28+
* Add nodes from under "playlistDirectories" into curTop. Highly recursive.
29+
*
30+
* @param curTop Tree node, to which the provided files will be added as children. Maybe Null.
31+
* @param files Playlist directories or playlist files to add
32+
* @return Playlist tree
33+
*/
34+
public static PlaylistTreeNode addNodes(PlaylistTreeNode curTop, Stream<Path> files)
35+
{
36+
PlaylistTreeNode currentNode = curTop == null ? new PlaylistTreeNode(Path.of("#___root___")) : curTop;
37+
files
38+
.filter(file -> Files.isDirectory(file) || Playlist.isPlaylist(file))
39+
.sorted(new DirectoryThenFileThenAlphabeticalPathComparator())
40+
.map(PlaylistTreeNode :: new)
41+
.forEach(node -> {
42+
Path path = node.getUserObject();
43+
if (Files.isDirectory(path))
7144
{
72-
f = ol1;
73-
if (f.isDirectory())
45+
try
7446
{
75-
File[] tmp = f.listFiles(new PlaylistFileFilter());
76-
if (tmp != null && tmp.length > 0)
77-
{
78-
addNodes(curDir, f);
79-
}
47+
addNodes(node, Files.list(path)); // recursion
8048
}
81-
else
49+
catch (IOException e)
8250
{
83-
files.add(f);
51+
logger.error(String.format("Failed to list files in directory: %s", path), e);
52+
throw new RuntimeException(e);
8453
}
8554
}
86-
// Pass two: for files.
87-
for (File file1 : files)
88-
{
89-
curDir.add(new PlaylistTreeNode(new TreeNodeFile(file1.getPath())));
90-
}
91-
if (curDir.children().hasMoreElements() || !((File) curDir.getUserObject()).isDirectory())
92-
{
93-
if (curTop != null)
94-
{
95-
curTop.add(curDir);
96-
}
97-
}
98-
return curDir;
99-
}
100-
return null;
101-
}
102-
return null;
55+
currentNode.add(node);
56+
});
57+
return currentNode;
10358
}
10459

105-
/**
106-
*
107-
* @param node
108-
* @return
109-
*/
110-
public static String TreePathToFileSystemPath(TreePath node)
60+
61+
public static Path TreePathToFileSystemPath(TreePath node)
11162
{
112-
return ((File) ((PlaylistTreeNode) node.getLastPathComponent()).getUserObject()).getPath();
63+
return ((PlaylistTreeNode) node.getLastPathComponent()).getUserObject();
11364
}
11465
}

0 commit comments

Comments
 (0)