Skip to content

Commit

Permalink
feat: add menu option to fix corrupt saved states
Browse files Browse the repository at this point in the history
  • Loading branch information
lantzelot-swe committed Apr 6, 2024
1 parent 963ae7e commit 5025e76
Show file tree
Hide file tree
Showing 9 changed files with 346 additions and 68 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>se.lantz</groupId>
<artifactId>PCUAEManager</artifactId>
<version>2.16.3</version>
<version>2.17.0</version>
<name>PCUAEManager</name>
<properties>
<project.build.sourceEncoding>Cp1252</project.build.sourceEncoding>
Expand Down
57 changes: 48 additions & 9 deletions src/main/java/se/lantz/gui/MenuManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import se.lantz.gui.exports.ExportSavedStatesWorker;
import se.lantz.gui.exports.ExportWorker;
import se.lantz.gui.exports.ImportExportProgressDialog;
import se.lantz.gui.exports.ImportExportProgressDialog.DIALOGTYPE;
import se.lantz.gui.imports.CarouselImportWorker;
import se.lantz.gui.imports.GamebaseImportWorker;
import se.lantz.gui.imports.ImportOptionsDialog;
Expand All @@ -45,6 +46,8 @@
import se.lantz.gui.imports.ImportSavedStatesWorker;
import se.lantz.gui.install.ManagerDownloadDialog;
import se.lantz.gui.preferences.PreferencesDialog;
import se.lantz.gui.savedstates.FixCorruptSavedStatesDialog;
import se.lantz.gui.savedstates.FixCorruptSavedStatesWorker;
import se.lantz.manager.BackupManager;
import se.lantz.manager.ExportManager;
import se.lantz.manager.ImportManager;
Expand Down Expand Up @@ -130,6 +133,7 @@ public class MenuManager
private JMenuItem palNtscFixItem;
private JMenuItem convertSavedStatesItem;
private JMenuItem copySavedStatesItem;
private JMenuItem fixCorruptSavedStatesItem;
private JMenuItem resetJoystickConfigItem;
private JMenuItem enableAccurateDiskItem;
private JMenuItem disableAccurateDiskItem;
Expand Down Expand Up @@ -256,6 +260,8 @@ private void setupMenues()
toolsMenu.addSeparator();
toolsMenu.add(getConvertSavedStatesItem());
toolsMenu.add(getCopySavedStatesToFileLoaderItem());
toolsMenu.add(getFixCorruptSavedStatesItem());
toolsMenu.addSeparator();
toolsMenu.add(getResetJoystickConfigItem());
toolsMenu.add(getEnableAccurateDiskItem());
toolsMenu.add(getDisableAccurateDiskItem());
Expand Down Expand Up @@ -503,7 +509,8 @@ JMenuItem getCarouselPreviewMenuItem()
KeyStroke keyStrokeCarouselPreview = KeyStroke.getKeyStroke(KeyEvent.VK_W, InputEvent.CTRL_DOWN_MASK);
carouselPreviewItem.setAccelerator(keyStrokeCarouselPreview);
carouselPreviewItem.setMnemonic('W');
carouselPreviewItem.addActionListener(e -> MainWindow.getInstance().getMainPanel().getListPanel().showCarouselPreview());
carouselPreviewItem
.addActionListener(e -> MainWindow.getInstance().getMainPanel().getListPanel().showCarouselPreview());
return carouselPreviewItem;
}

Expand Down Expand Up @@ -995,8 +1002,8 @@ private JMenuItem getPrimaryJoystickItem()
if (dialog.showDialog())
{
MainWindow.getInstance().setWaitCursor(true);
List<String> selectedGameIds = MainWindow.getInstance().getMainPanel().getListPanel().getSelectedGameListData().stream()
.map(data -> data.getGameId()).collect(Collectors.toList());
List<String> selectedGameIds = MainWindow.getInstance().getMainPanel().getListPanel()
.getSelectedGameListData().stream().map(data -> data.getGameId()).collect(Collectors.toList());

uiModel.updatePrimaryJoystickPort(selectedGameIds, dialog.isPort1Primary());

Expand Down Expand Up @@ -1093,6 +1100,17 @@ private JMenuItem getCopySavedStatesToFileLoaderItem()
return copySavedStatesItem;
}

private JMenuItem getFixCorruptSavedStatesItem()
{
if (fixCorruptSavedStatesItem == null)
{
fixCorruptSavedStatesItem = new JMenuItem("Fix corrupt Saved states...");
fixCorruptSavedStatesItem.setMnemonic('o');
fixCorruptSavedStatesItem.addActionListener(e -> fixCorruptSavedStates());
}
return fixCorruptSavedStatesItem;
}

private JMenuItem getResetJoystickConfigItem()
{
if (resetJoystickConfigItem == null)
Expand Down Expand Up @@ -1360,7 +1378,8 @@ private void importSavedStates()
{
savedStatesManager.setImportDirectory(importSavedStatesDialog.getTargetDirectory());
savedStatesManager.setImportOverwrite(importSavedStatesDialog.isImportOverwrite());
ImportExportProgressDialog dialog = new ImportExportProgressDialog(MainWindow.getInstance(), "Import saved states", true);
ImportExportProgressDialog dialog =
new ImportExportProgressDialog(MainWindow.getInstance(), "Import saved states", DIALOGTYPE.IMPORT);
ImportSavedStatesWorker worker = new ImportSavedStatesWorker(savedStatesManager, dialog);
worker.execute();
dialog.setVisible(true);
Expand All @@ -1376,7 +1395,8 @@ private void exportSavedStates()
{
savedStatesManager.setExportDirectory(exportSavedStatesDialog.getTargetDirectory());
savedStatesManager.setExportOverwrite(exportSavedStatesDialog.isExportOverwrite());
ImportExportProgressDialog dialog = new ImportExportProgressDialog(MainWindow.getInstance(), "Export saved states", false);
ImportExportProgressDialog dialog =
new ImportExportProgressDialog(MainWindow.getInstance(), "Export saved states", DIALOGTYPE.EXPORT);
ExportSavedStatesWorker worker = new ExportSavedStatesWorker(savedStatesManager, dialog);
worker.execute();
dialog.setVisible(true);
Expand All @@ -1398,7 +1418,8 @@ private void exportGames()
exportManager.setGameViewsToExport(viewList);
exportManager.setDeleteBeforeExport(exportSelectionDialog.deleteBeforeExport());
exportManager.setTargetDirectory(exportSelectionDialog.getTargetDirectory());
ImportExportProgressDialog dialog = new ImportExportProgressDialog(MainWindow.getInstance(), "Export games", false);
ImportExportProgressDialog dialog =
new ImportExportProgressDialog(MainWindow.getInstance(), "Export games", DIALOGTYPE.EXPORT);
ExportWorker worker = new ExportWorker(exportManager, dialog);
worker.execute();
dialog.setVisible(true);
Expand All @@ -1412,7 +1433,8 @@ private void exportGames()
exportManager.setGamesToExport(gamesList);
exportManager.setDeleteBeforeExport(exportSelectionDialog.deleteBeforeExport());
exportManager.setTargetDirectory(exportSelectionDialog.getTargetDirectory());
ImportExportProgressDialog dialog = new ImportExportProgressDialog(MainWindow.getInstance(), "Export games", false);
ImportExportProgressDialog dialog =
new ImportExportProgressDialog(MainWindow.getInstance(), "Export games", DIALOGTYPE.EXPORT);
ExportWorker worker = new ExportWorker(exportManager, dialog);
worker.execute();
dialog.setVisible(true);
Expand All @@ -1436,7 +1458,8 @@ private void exportGamesToFileLoader()
exportManager.setGameViewsToExport(viewList);
exportManager.setDeleteBeforeExport(exportSelectionDialog.deleteBeforeExport());
exportManager.setTargetDirectory(exportSelectionDialog.getTargetDirectory());
ImportExportProgressDialog dialog = new ImportExportProgressDialog(MainWindow.getInstance(), "Export games", false);
ImportExportProgressDialog dialog =
new ImportExportProgressDialog(MainWindow.getInstance(), "Export games", DIALOGTYPE.EXPORT);
ExportFileLoaderWorker worker = new ExportFileLoaderWorker(exportManager, dialog);
worker.execute();
dialog.setVisible(true);
Expand All @@ -1450,7 +1473,8 @@ private void exportGamesToFileLoader()
exportManager.setGamesToExport(gamesList);
exportManager.setDeleteBeforeExport(exportSelectionDialog.deleteBeforeExport());
exportManager.setTargetDirectory(exportSelectionDialog.getTargetDirectory());
ImportExportProgressDialog dialog = new ImportExportProgressDialog(MainWindow.getInstance(), "Export games", false);
ImportExportProgressDialog dialog =
new ImportExportProgressDialog(MainWindow.getInstance(), "Export games", DIALOGTYPE.EXPORT);
ExportFileLoaderWorker worker = new ExportFileLoaderWorker(exportManager, dialog);
worker.execute();
dialog.setVisible(true);
Expand Down Expand Up @@ -1690,7 +1714,22 @@ private void copySavedStatesFromCarouselToFileLoader()
uiModel.setSelectedGameView(null);
}
}
}

private void fixCorruptSavedStates()
{
FixCorruptSavedStatesDialog corruptedDialog = new FixCorruptSavedStatesDialog();
corruptedDialog.pack();
corruptedDialog.setLocationRelativeTo(MainWindow.getInstance());
if (corruptedDialog.showDialog())
{
savedStatesManager.setFixDirectory(corruptedDialog.getTargetDirectory());
ImportExportProgressDialog dialog =
new ImportExportProgressDialog(MainWindow.getInstance(), "Fix corrupt saved states", DIALOGTYPE.FIX);
FixCorruptSavedStatesWorker worker = new FixCorruptSavedStatesWorker(savedStatesManager, dialog);
worker.execute();
dialog.setVisible(true);
}
}

private void resetControllerConfigs()
Expand Down
101 changes: 50 additions & 51 deletions src/main/java/se/lantz/gui/SelectDirPanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
Expand All @@ -34,15 +35,15 @@

import se.lantz.util.ExceptionHandler;
import se.lantz.util.FileManager;
import javax.swing.JLabel;

public class SelectDirPanel extends JPanel
{
private static final String THEC64SAVE = ".THEC64SAVE";

public enum Mode
{
CAROUSEL_IMPORT, GB_IMPORT, CAROUSEL_EXPORT, FILELOADER_EXPORT, SAVEDSTATES_IMPORT, SAVEDSTATES_EXPORT
CAROUSEL_IMPORT, GB_IMPORT, CAROUSEL_EXPORT, FILELOADER_EXPORT, SAVEDSTATES_IMPORT, SAVEDSTATES_EXPORT,
FIX_CORRUPT_SAVEDSTATES
}

private static final Logger logger = LoggerFactory.getLogger(SelectDirPanel.class);
Expand All @@ -52,6 +53,7 @@ public enum Mode
private static final String FILELOADER_EXPORT_DIR_PROPERTY = "flexportDir";
private static final String SAVEDSTATES_IMPORT_DIR_PROPERTY = "savedStatesImportDir";
private static final String SAVEDSTATES_EXPORT_DIR_PROPERTY = "savedStatesExportDir";
private static final String FIX_SAVEDSTATES_DIR_PROPERTY = "fixSavedStatesDir";
private JTextField dirTextField;
private JButton selectDirButton;

Expand Down Expand Up @@ -148,6 +150,17 @@ public SelectDirPanel(Mode mode)
configuredDir = new File(".").getAbsolutePath();
}
break;
case FIX_CORRUPT_SAVEDSTATES:
configuredDir = getUsbFilePath(true, false);
if (configuredDir.isEmpty())
{
configuredDir = FileManager.getConfiguredProperties().getProperty(FIX_SAVEDSTATES_DIR_PROPERTY);
}
if (configuredDir == null)
{
configuredDir = new File(".").getAbsolutePath();
}
break;
default:
break;
}
Expand All @@ -161,7 +174,7 @@ public SelectDirPanel(Mode mode)
gbc_usbInfoLabel.gridy = 1;
add(getUsbInfoLabel(), gbc_usbInfoLabel);
}

private String getUsbFilePath(boolean saveState, boolean fileLoader)
{
String usbDir = FileManager.getPCUAEUSBPath(saveState, fileLoader);
Expand Down Expand Up @@ -217,6 +230,9 @@ public void actionPerformed(ActionEvent e)
case SAVEDSTATES_EXPORT:
selectSavedStatesExportDirectory();
break;
case FIX_CORRUPT_SAVEDSTATES:
selectFixSavedStatesDirectory();
break;
default:
break;
}
Expand Down Expand Up @@ -394,6 +410,31 @@ protected JDialog createDialog(Component parent) throws HeadlessException
}
}

private void selectFixSavedStatesDirectory()
{
final JFileChooser fileChooser = new JFileChooser()
{
@Override
protected JDialog createDialog(Component parent) throws HeadlessException
{
//Set parent to the export dialog
JDialog dlg = super.createDialog(SwingUtilities.getAncestorOfClass(JDialog.class, SelectDirPanel.this));
return dlg;
}
};
fileChooser.setDialogTitle("Select a directory containing saved states");
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
fileChooser.setCurrentDirectory(new File(configuredDir));
int value = fileChooser.showDialog(this, "OK");
if (value == JFileChooser.APPROVE_OPTION)
{
targetDirectory = fileChooser.getSelectedFile();
configuredDir = targetDirectory.toPath().toString();
FileManager.getConfiguredProperties().put(FIX_SAVEDSTATES_DIR_PROPERTY, configuredDir);
getDirTextField().setText(configuredDir);
}
}

public File getTargetDirectory()
{
return targetDirectory;
Expand All @@ -417,64 +458,22 @@ private boolean checkSelectedFolder(Path folder)
List<Path> foundCarousels = Collections.EMPTY_LIST;
try (Stream<Path> filePathStream = Files.walk(folder, 1))
{
foundCarousels = filePathStream.filter(Files::isDirectory).filter(dir -> isCarouselFolder(dir)).collect(Collectors.toList());
foundCarousels =
filePathStream.filter(Files::isDirectory).filter(dir -> isCarouselFolder(dir)).collect(Collectors.toList());
}
catch (IOException e)
{
ExceptionHandler.handleException(e, "Could not read gameInfo files");
}
return foundCarousels.size() > 0;
}

// //Assume a games subfolder is available
// Path srcParentFolder = folder.resolve("games");
// Path srcCoversFolder = srcParentFolder.resolve("covers");
// Path srcGamesFolder = srcParentFolder.resolve("games");
// Path srcScreensFolder = srcParentFolder.resolve("screens");
//
// logger.debug("parent folder: {}", srcParentFolder);
// logger.debug("covers folder: {}", srcCoversFolder);
// logger.debug("games folder: {}", srcGamesFolder);
// logger.debug("screens folder: {}", srcScreensFolder);
//
// // Verify that subfolders are available
// if (Files.exists(srcParentFolder, LinkOption.NOFOLLOW_LINKS) &&
// Files.exists(srcCoversFolder, LinkOption.NOFOLLOW_LINKS) &&
// Files.exists(srcGamesFolder, LinkOption.NOFOLLOW_LINKS) &&
// Files.exists(srcScreensFolder, LinkOption.NOFOLLOW_LINKS))
// {
// logger.debug("A valid directory!");
//
// return true;
// }
// else
// {
// //Check if there is no games subfolder, but valid structure
// srcCoversFolder = folder.resolve("covers");
// srcGamesFolder = folder.resolve("games");
// srcScreensFolder = folder.resolve("screens");
// if (Files.exists(srcCoversFolder, LinkOption.NOFOLLOW_LINKS) &&
// Files.exists(srcGamesFolder, LinkOption.NOFOLLOW_LINKS) &&
// Files.exists(srcScreensFolder, LinkOption.NOFOLLOW_LINKS))
// {
// logger.debug("A valid directory!");
//
// return true;
// }
// else
// {
// logger.debug("An ivalid directory!");
// return false;
// }
// }
}



private boolean isCarouselFolder(Path folder)
{
return Files.exists(folder.resolve("covers"), LinkOption.NOFOLLOW_LINKS) &&
Files.exists(folder.resolve("screens"), LinkOption.NOFOLLOW_LINKS) &&
Files.exists(folder.resolve("games"), LinkOption.NOFOLLOW_LINKS);
return Files.exists(folder.resolve("covers"), LinkOption.NOFOLLOW_LINKS) &&
Files.exists(folder.resolve("screens"), LinkOption.NOFOLLOW_LINKS) &&
Files.exists(folder.resolve("games"), LinkOption.NOFOLLOW_LINKS);
}

public void registerGBFileSelectedActionListener(ActionListener listener)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,20 @@

public class ImportExportProgressDialog extends JDialog
{
public enum DIALOGTYPE
{
IMPORT, EXPORT, FIX
}
private static final long serialVersionUID = 1L;

private ImportExportProgressPanel panel;

private final boolean isImport;
private final DIALOGTYPE type;

public ImportExportProgressDialog(Frame frame, String title, boolean isImport)
public ImportExportProgressDialog(Frame frame, String title, DIALOGTYPE type)
{
super(frame, title, true);
this.isImport = isImport;
this.type = type;
this.add(getExportProgressPanel());
setSize(900, 600);
setLocationRelativeTo(frame);
Expand All @@ -31,7 +35,7 @@ public void updateProgress(String infoText)

public void finish()
{
getExportProgressPanel().finish(isImport);
getExportProgressPanel().finish(type);
}

public ImportExportProgressPanel getExportProgressPanel()
Expand Down
Loading

0 comments on commit 5025e76

Please sign in to comment.