Skip to content

Preserve playlist sequence & persist active playlist editor #148

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/main/java/listfix/config/IApplicationState.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@

import listfix.json.JsonFrameSettings;

import java.util.List;
import java.util.TreeMap;
import java.util.TreeSet;

public interface IApplicationState
{
TreeSet<String> getPlaylistsOpened();
List<String> getPlaylistsOpened();

TreeMap<String, JsonFrameSettings> getFramePositions();

Integer getActivePlaylistIndex();

void setActivePlaylistIndex(Integer activePlaylistIndex);
}
21 changes: 18 additions & 3 deletions src/main/java/listfix/json/JsonApplicationState.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,20 @@

import listfix.config.IApplicationState;

import java.util.ArrayList;
import java.util.TreeMap;
import java.util.TreeSet;

public class JsonApplicationState implements IApplicationState
{
/**
* Keep track of playlist opened
*/
private final TreeSet<String> playlistsOpened = new TreeSet<>();
private final ArrayList<String> playlistsOpened = new ArrayList<>();

/**
* Index of active playlist
*/
private Integer activePlaylistIndex = null;

/**
* Keep track of frame positions
Expand All @@ -19,7 +24,7 @@ public class JsonApplicationState implements IApplicationState
private final TreeMap<String, JsonFrameSettings> framePositions = new TreeMap<>();

@Override
public TreeSet<String> getPlaylistsOpened()
public ArrayList<String> getPlaylistsOpened()
{
return playlistsOpened;
}
Expand All @@ -29,4 +34,14 @@ public TreeMap<String, JsonFrameSettings> getFramePositions()
{
return this.framePositions;
}

public Integer getActivePlaylistIndex()
{
return activePlaylistIndex;
}

public void setActivePlaylistIndex(Integer activePlaylistIndex)
{
this.activePlaylistIndex = activePlaylistIndex;
}
}
148 changes: 78 additions & 70 deletions src/main/java/listfix/view/GUIScreen.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import listfix.model.BatchRepair;
import listfix.model.BatchRepairItem;
import listfix.model.PlaylistHistory;

import listfix.model.playlists.Playlist;
import listfix.model.playlists.PlaylistFactory;
import listfix.swing.IDocumentChangeListener;
Expand Down Expand Up @@ -132,10 +131,10 @@ private void postInitComponents()
if (this._listFixController.getShowMediaDirWindow())
{
JOptionPane.showMessageDialog(
this,
new JTransparentTextArea("You need to add a media directory before you can find the new locations of your files. See help for more information."),
"Reminder",
JOptionPane.INFORMATION_MESSAGE);
this,
new JTransparentTextArea("You need to add a media directory before you can find the new locations of your files. See help for more information."),
"Reminder",
JOptionPane.INFORMATION_MESSAGE);
}
else
{
Expand Down Expand Up @@ -211,12 +210,19 @@ public void treeStructureChanged(TreeModelEvent e)

_logger.info("post init");

EventQueue.invokeLater(() ->
// Restore previous opened playlists
_listFixController.getApplicationConfiguration().getConfig().getApplicationState().getPlaylistsOpened().stream()
.map(Path::of)
.filter(Files::exists)
.forEach(GUIScreen.this::openPlaylist));
EventQueue.invokeLater(() -> {
IApplicationState appState = _listFixController.getApplicationConfiguration().getConfig().getApplicationState();
// Restore previous opened playlists
appState.getPlaylistsOpened().stream()
.map(Path::of)
.filter(Files::exists)
.forEach(GUIScreen.this::openPlaylist);

if (appState.getActivePlaylistIndex() != null)
{
_playlistTabbedPane.setSelectedIndex(appState.getActivePlaylistIndex());
}
});
}

private void recheckStatusOfOpenPlaylists()
Expand Down Expand Up @@ -300,7 +306,7 @@ private void handleMouseEvent(MouseEvent e)

final TreePath[] selectPath = _playlistDirectoryTree.getSelectionPaths();
final boolean allTopLevel = selectPath != null && Arrays.stream(selectPath)
.allMatch(path -> path.getParentPath() != null && path.getParentPath().getParentPath() == null);
.allMatch(path -> path.getParentPath() != null && path.getParentPath().getParentPath() == null);

_miRemovePlaylistDirectory.setEnabled(allTopLevel);

Expand All @@ -311,8 +317,8 @@ private void handleMouseEvent(MouseEvent e)
_miOpenSelectedPlaylists.setEnabled(true);
boolean singleFileSelected = _playlistDirectoryTree.getSelectionCount() == 1;
_miRenameSelectedItem.setEnabled(singleFileSelected
&& !allTopLevel
&& Files.isRegularFile(GUIScreen.this.getSelectedPlaylistTreeNodes().get(0).getUserObject())
&& !allTopLevel
&& Files.isRegularFile(GUIScreen.this.getSelectedPlaylistTreeNodes().get(0).getUserObject())
);
_miDeleteFile.setEnabled(true);
}
Expand Down Expand Up @@ -379,7 +385,7 @@ private void configureFileAndFolderChoosers()
{
String curName = selectedFile.getName();
String nameWithoutExtension = FileUtils.getExtension(selectedFile.getName()).map(
ext -> curName.substring(0, curName.lastIndexOf("."))).orElse(curName);
ext -> curName.substring(0, curName.lastIndexOf("."))).orElse(curName);
String newName = nameWithoutExtension + fileFilter.getContentType().getExtensions()[0];
_savePlaylistAsFileChooser.setSelectedFile(new File(newName));
}
Expand Down Expand Up @@ -967,19 +973,19 @@ public void documentActivated(JDocumentComponent<PlaylistEditCtrl> doc)
setJMenuBar(_mainMenuBar);

this.componentsRequireActivePlaylist = new Component[]{
_openPlaylistLocationMenuItem,
_saveAllMenuItem,
_saveAsMenuItem,
_saveMenuItem,
_openPlaylistLocationMenuItem,
_saveAllMenuItem,
_saveAsMenuItem,
_saveMenuItem,

_closeAllMenuItem,
_closeMenuItem,
_closeAllMenuItem,
_closeMenuItem,

_miReload,
_miReloadAll,
_miReload,
_miReloadAll,

_miExactMatchRepairOpenPlaylists,
_miClosestMatchRepairOpenPlaylists,
_miExactMatchRepairOpenPlaylists,
_miClosestMatchRepairOpenPlaylists,
};

splashScreen.setIconImage(applicationIcon);
Expand Down Expand Up @@ -1100,8 +1106,8 @@ private void deleteTreeSelectedPlaylists()
{
int[] selRows = _playlistDirectoryTree.getSelectionRows();
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)
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)
{
return;
}
Expand Down Expand Up @@ -1264,10 +1270,10 @@ private void openIconButtonActionPerformed()//GEN-FIRST:event_openIconButtonActi
private void openPlaylistFoldersFromPlaylistTree()
{
this.getSelectedFilesFromTreePlaylists().stream()
.map(file -> Files.isDirectory(file) ? file : file.getParent())
.filter(Objects::nonNull)
.distinct()
.forEach(this::openFolderInExplorerPerformed);
.map(file -> Files.isDirectory(file) ? file : file.getParent())
.filter(Objects::nonNull)
.distinct()
.forEach(this::openFolderInExplorerPerformed);
}

private void openPlaylistLocation(Playlist playList)
Expand Down Expand Up @@ -1328,7 +1334,7 @@ else if (Files.isDirectory(filePath))
{
_logger.warn("Failed to open playlist", ioe);
JOptionPane.showMessageDialog(this, new JTransparentTextArea(ExStack.textFormatErrorForUser("There was a problem opening the file you selected.", ioe.getCause())),
"Open Playlist Error", JOptionPane.ERROR_MESSAGE);
"Open Playlist Error", JOptionPane.ERROR_MESSAGE);
}
}

Expand Down Expand Up @@ -1357,7 +1363,7 @@ public void openPlaylist(final Path playlistPath)
{
_logger.error("Open playlist error", ex);
JOptionPane.showMessageDialog(this, new JTransparentTextArea(ExStack.textFormatErrorForUser("There was a problem opening the file you selected.", ex.getCause())),
"Open Playlist Error", JOptionPane.ERROR_MESSAGE);
"Open Playlist Error", JOptionPane.ERROR_MESSAGE);
return;
}

Expand Down Expand Up @@ -1395,7 +1401,7 @@ protected void done()
_logger.error("Open playlist error", ex);

JOptionPane.showMessageDialog(GUIScreen.this, new JTransparentTextArea(ExStack.textFormatErrorForUser("There was a problem opening the file you selected, are you sure it was a playlist?", ex.getCause())),
"Open Playlist Error", JOptionPane.ERROR_MESSAGE);
"Open Playlist Error", JOptionPane.ERROR_MESSAGE);
return;
}

Expand Down Expand Up @@ -1444,11 +1450,11 @@ public void openNewTabForPlaylist(Playlist playlist)

// Tie the DocumentComponent and the Playlist in the editor together via listeners, so the former can update when the latter is modified
playlist.addModifiedListener(
list1 -> {
updateTabTitleForPlaylist(list1, tempComp);
tempComp.setIcon(getIconForPlaylist(list1));
tempComp.setPath(list1.getPath());
}
list1 -> {
updateTabTitleForPlaylist(list1, tempComp);
tempComp.setIcon(getIconForPlaylist(list1));
tempComp.setPath(list1.getPath());
}
);

// Update the list of open playlists
Expand Down Expand Up @@ -1568,10 +1574,10 @@ public boolean showPlaylistSaveAsDialog(Playlist playlist)
_savePlaylistAsFileChooser.setSelectedFile(playlist.getFile());
// Select the file-filter to the current playlist
Arrays.stream(_savePlaylistAsFileChooser.getChoosableFileFilters())
.map(filter -> (SpecificPlaylistFileFilter) filter)
.filter(filter -> filter.getPlaylistProvider().getId().equals(playlist.getType().name()))
.findFirst()
.ifPresent(_savePlaylistAsFileChooser::setFileFilter);
.map(filter -> (SpecificPlaylistFileFilter) filter)
.filter(filter -> filter.getPlaylistProvider().getId().equals(playlist.getType().name()))
.findFirst()
.ifPresent(_savePlaylistAsFileChooser::setFileFilter);

int rc = _savePlaylistAsFileChooser.showSaveDialog(this);
if (rc == JFileChooser.APPROVE_OPTION)
Expand Down Expand Up @@ -1761,11 +1767,11 @@ public boolean tryCloseTab(JDocumentComponent<PlaylistEditCtrl> ctrl)
if (playlist.isModified())
{
Object[] options =
{
"Save", "Save As", "Don't Save", "Cancel"
};
{
"Save", "Save As", "Don't Save", "Cancel"
};
int rc = JOptionPane.showOptionDialog(this, new JTransparentTextArea("The playlist \"" + playlist.getFilename() + "\" has been modified. Do you want to save the changes?"), "Confirm Close",
JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[2]);
JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[2]);

if (rc == 0)
{
Expand Down Expand Up @@ -1827,11 +1833,11 @@ private void confirmCloseApp()
if (list.isModified())
{
Object[] options =
{
"Discard Changes and Exit", "Cancel"
};
{
"Discard Changes and Exit", "Cancel"
};
int rc = JOptionPane.showOptionDialog(this, new JTransparentTextArea("You have unsaved changes. Do you really want to discard these changes and exit?"), "Confirm Close",
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[1]);
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[1]);
if (rc == JOptionPane.NO_OPTION)
{
return;
Expand All @@ -1845,12 +1851,14 @@ private void confirmCloseApp()

// Store open playlists
List<String> openPlaylists = this._playlistTabbedPane.getAllEmbeddedMainComponent().stream()
.map(playlistEditCtrl -> playlistEditCtrl.getPlaylist().getPath().toString())
.collect(Collectors.toList());
.map(playlistEditCtrl -> playlistEditCtrl.getPlaylist().getPath().toString())
.collect(Collectors.toList());

Set<String> playlistPaths = this._listFixController.getApplicationConfiguration().getConfig().getApplicationState().getPlaylistsOpened();
IApplicationState appState = this._listFixController.getApplicationConfiguration().getConfig().getApplicationState();
List<String> playlistPaths = appState.getPlaylistsOpened();
playlistPaths.clear();
playlistPaths.addAll(openPlaylists);
appState.setActivePlaylistIndex(_playlistTabbedPane.getSelectedIndex());

try
{
Expand Down Expand Up @@ -1885,7 +1893,7 @@ private void _addMediaDirButtonActionPerformed()
if (ArrayFunctions.containsStringPrefixingAnotherString(_listFixController.getMediaLibrary().getMediaDirectories(), dir, !ListFixController.FILE_SYSTEM_IS_CASE_SENSITIVE))
{
JOptionPane.showMessageDialog(this, new JTransparentTextArea("The directory you attempted to add is a subdirectory of one already in your media library, no change was made."),
"Reminder", JOptionPane.INFORMATION_MESSAGE);
"Reminder", JOptionPane.INFORMATION_MESSAGE);
return;
}
else
Expand All @@ -1900,8 +1908,8 @@ private void _addMediaDirButtonActionPerformed()
if (matchCount == 0)
{
JOptionPane.showMessageDialog(this,
new JTransparentTextArea("One or more of your existing media directories is a subdirectory of the directory you just added. These directories will be removed from your list automatically."),
"Reminder", JOptionPane.INFORMATION_MESSAGE);
new JTransparentTextArea("One or more of your existing media directories is a subdirectory of the directory you just added. These directories will be removed from your list automatically."),
"Reminder", JOptionPane.INFORMATION_MESSAGE);
}
removeMediaDir(dirToCheck);
matchCount++;
Expand Down Expand Up @@ -1995,12 +2003,12 @@ private void removeMediaDir(String mediaDirectory)
private void _aboutMenuItemActionPerformed()
{
JOptionPane.showMessageDialog(this, "listFix( ) v" + applicationVersion + "\n\nBrought To You By: " +
"\n Borewit" +
"\n Jeremy Caron (firewyre) " +
"\n Kennedy Akala (kennedyakala)" +
"\n John Peterson (johnpeterson)" +
"\n\nProject home: https://github.com/Borewit/listFix",
"About", JOptionPane.INFORMATION_MESSAGE);
"\n Borewit" +
"\n Jeremy Caron (firewyre) " +
"\n Kennedy Akala (kennedyakala)" +
"\n John Peterson (johnpeterson)" +
"\n\nProject home: https://github.com/Borewit/listFix",
"About", JOptionPane.INFORMATION_MESSAGE);
}

private void refreshMediaDirs()
Expand Down Expand Up @@ -2179,9 +2187,9 @@ private void _newIconButtonActionPerformed()
{
_logger.error("Error creating a new playlist", ex);
JOptionPane.showMessageDialog(this,
new JTransparentTextArea(ExStack.textFormatErrorForUser("Sorry, there was an error creating a new playlist. Please try again, or file a bug report.", ex.getCause())),
"New Playlist Error",
JOptionPane.ERROR_MESSAGE);
new JTransparentTextArea(ExStack.textFormatErrorForUser("Sorry, there was an error creating a new playlist. Please try again, or file a bug report.", ex.getCause())),
"New Playlist Error",
JOptionPane.ERROR_MESSAGE);
}

}
Expand Down Expand Up @@ -2301,8 +2309,8 @@ private void updatePlaylistDirectoryPanel()
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

List<Path> playListDirFiles = this.getApplicationConfig().getPlaylistDirectories().stream()
.map(Path::of)
.collect(Collectors.toList());
.map(Path::of)
.collect(Collectors.toList());

PlaylistTreeNode playlistTreeNode = FileTreeNodeGenerator.addNodes(null, playListDirFiles);

Expand All @@ -2329,8 +2337,8 @@ private void removePlaylistDirectory(TreePath[] selectedPath)
if (selectedPath != null)
{
removePlaylistDirectory(Arrays.stream(selectedPath)
.map(FileTreeNodeGenerator::treePathToFileSystemPath)
.collect(Collectors.toList()));
.map(FileTreeNodeGenerator::treePathToFileSystemPath)
.collect(Collectors.toList()));
}
}

Expand Down