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)
{
@@ -425,56 +467,13 @@ public class SelectDirPanel extends JPanel
}
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)
diff --git a/src/main/java/se/lantz/gui/exports/ImportExportProgressDialog.java b/src/main/java/se/lantz/gui/exports/ImportExportProgressDialog.java
index 6a5ac76..dccad10 100644
--- a/src/main/java/se/lantz/gui/exports/ImportExportProgressDialog.java
+++ b/src/main/java/se/lantz/gui/exports/ImportExportProgressDialog.java
@@ -7,16 +7,20 @@ import javax.swing.WindowConstants;
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);
@@ -31,7 +35,7 @@ public class ImportExportProgressDialog extends JDialog
public void finish()
{
- getExportProgressPanel().finish(isImport);
+ getExportProgressPanel().finish(type);
}
public ImportExportProgressPanel getExportProgressPanel()
diff --git a/src/main/java/se/lantz/gui/exports/ImportExportProgressPanel.java b/src/main/java/se/lantz/gui/exports/ImportExportProgressPanel.java
index e835881..b46aa40 100644
--- a/src/main/java/se/lantz/gui/exports/ImportExportProgressPanel.java
+++ b/src/main/java/se/lantz/gui/exports/ImportExportProgressPanel.java
@@ -10,6 +10,8 @@ import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
+import se.lantz.gui.exports.ImportExportProgressDialog.DIALOGTYPE;
+
public class ImportExportProgressPanel extends JPanel
{
private JProgressBar progressBar;
@@ -88,7 +90,7 @@ public class ImportExportProgressPanel extends JPanel
getTextArea().append(infoText);
}
- public void finish(boolean isImport)
+ public void finish(DIALOGTYPE type)
{
getCloseButton().setEnabled(true);
getProgressBar().setIndeterminate(false);
@@ -96,14 +98,27 @@ public class ImportExportProgressPanel extends JPanel
//Check for errors
String text = getTextArea().getText();
int count = text.length() - text.replace("ERROR:", "").length();
- if (isImport)
+ switch (type)
+ {
+ case IMPORT:
{
getTextArea().append("\nImport ");
+ break;
}
- else
+ case EXPORT:
{
getTextArea().append("\nExport ");
+ break;
}
+ case FIX:
+ {
+ getTextArea().append("\nFix ");
+ break;
+ }
+ default:
+ //Do nothing
+ }
+
if (count > 0)
{
getTextArea().append("ended with " + count/6 + " errors. See pcusb.log for details.");
diff --git a/src/main/java/se/lantz/gui/savedstates/FixCorruptSavedStatesDialog.java b/src/main/java/se/lantz/gui/savedstates/FixCorruptSavedStatesDialog.java
new file mode 100644
index 0000000..2f1a608
--- /dev/null
+++ b/src/main/java/se/lantz/gui/savedstates/FixCorruptSavedStatesDialog.java
@@ -0,0 +1,41 @@
+package se.lantz.gui.savedstates;
+
+import java.awt.Dimension;
+import java.io.File;
+
+import se.lantz.gui.BaseDialog;
+import se.lantz.gui.MainWindow;
+
+public class FixCorruptSavedStatesDialog extends BaseDialog
+{
+ FixCorruptSavedStatesPanel panel;
+
+ public FixCorruptSavedStatesDialog()
+ {
+ super(MainWindow.getInstance());
+ addContent(getImportSavedStatesPanel());
+ setTitle("Fix corrupt saved states");
+ this.setPreferredSize(new Dimension(435, 310));
+ // getOkButton().setText("");
+ this.setResizable(false);
+ }
+
+ private FixCorruptSavedStatesPanel getImportSavedStatesPanel()
+ {
+ if (panel == null)
+ {
+ panel = new FixCorruptSavedStatesPanel();
+ }
+ return panel;
+ }
+
+ public File getTargetDirectory()
+ {
+ return getImportSavedStatesPanel().getTargetDirectory();
+ }
+
+ // public boolean isImportOverwrite()
+ // {
+ // return getImportSavedStatesPanel().isImportOverwrite();
+ // }
+}
diff --git a/src/main/java/se/lantz/gui/savedstates/FixCorruptSavedStatesPanel.java b/src/main/java/se/lantz/gui/savedstates/FixCorruptSavedStatesPanel.java
new file mode 100644
index 0000000..1ee1e89
--- /dev/null
+++ b/src/main/java/se/lantz/gui/savedstates/FixCorruptSavedStatesPanel.java
@@ -0,0 +1,64 @@
+package se.lantz.gui.savedstates;
+
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.io.File;
+
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+import se.lantz.gui.SelectDirPanel;
+import se.lantz.gui.SelectDirPanel.Mode;
+
+public class FixCorruptSavedStatesPanel extends JPanel
+{
+ private JLabel infoLabel;
+ private SelectDirPanel selectDirPanel;
+
+ public FixCorruptSavedStatesPanel()
+ {
+ GridBagLayout gridBagLayout = new GridBagLayout();
+ setLayout(gridBagLayout);
+ GridBagConstraints gbc_infoLabel = new GridBagConstraints();
+ gbc_infoLabel.fill = GridBagConstraints.HORIZONTAL;
+ gbc_infoLabel.anchor = GridBagConstraints.WEST;
+ gbc_infoLabel.insets = new Insets(10, 10, 0, 10);
+ gbc_infoLabel.gridx = 0;
+ gbc_infoLabel.gridy = 0;
+ add(getInfoLabel(), gbc_infoLabel);
+ GridBagConstraints gbc_selectDirPanel = new GridBagConstraints();
+ gbc_selectDirPanel.anchor = GridBagConstraints.NORTHWEST;
+ gbc_selectDirPanel.weighty = 1.0;
+ gbc_selectDirPanel.weightx = 1.0;
+ gbc_selectDirPanel.insets = new Insets(0, 5, 5, 0);
+ gbc_selectDirPanel.fill = GridBagConstraints.HORIZONTAL;
+ gbc_selectDirPanel.gridx = 0;
+ gbc_selectDirPanel.gridy = 1;
+ add(getSelectDirPanel(), gbc_selectDirPanel);
+ }
+
+ private JLabel getInfoLabel()
+ {
+ if (infoLabel == null)
+ {
+ infoLabel =
+ new JLabel("Sometimes the saved states on a USB stick can become corrupt and cannot be loaded (a yellow triangle is shown over the screenshot in the saved states UI). This can be fixed by recreating the .mta file.Select a folder containing saved states to fix any corrupt files:");
+ }
+ return infoLabel;
+ }
+
+ private SelectDirPanel getSelectDirPanel()
+ {
+ if (selectDirPanel == null)
+ {
+ selectDirPanel = new SelectDirPanel(Mode.FIX_CORRUPT_SAVEDSTATES);
+ }
+ return selectDirPanel;
+ }
+
+ File getTargetDirectory()
+ {
+ return getSelectDirPanel().getTargetDirectory();
+ }
+}
diff --git a/src/main/java/se/lantz/gui/savedstates/FixCorruptSavedStatesWorker.java b/src/main/java/se/lantz/gui/savedstates/FixCorruptSavedStatesWorker.java
new file mode 100644
index 0000000..7244b8f
--- /dev/null
+++ b/src/main/java/se/lantz/gui/savedstates/FixCorruptSavedStatesWorker.java
@@ -0,0 +1,62 @@
+package se.lantz.gui.savedstates;
+
+import java.util.List;
+
+import javax.swing.SwingWorker;
+
+import se.lantz.gui.exports.ImportExportProgressDialog;
+import se.lantz.gui.exports.PublishWorker;
+import se.lantz.manager.SavedStatesManager;
+import se.lantz.util.ExceptionHandler;
+
+public class FixCorruptSavedStatesWorker extends SwingWorker implements PublishWorker
+{
+
+ private SavedStatesManager savedStatesManager;
+ private ImportExportProgressDialog dialog;
+
+ public FixCorruptSavedStatesWorker(SavedStatesManager savedStatesManager, ImportExportProgressDialog dialog)
+ {
+ this.savedStatesManager = savedStatesManager;
+ this.dialog = dialog;
+ }
+
+ @Override
+ protected Void doInBackground() throws Exception
+ {
+ publish("Processing saved states...\n");
+ savedStatesManager.fixCorruptSavedStates(this);
+ publish("Processed " + savedStatesManager.getNumberOfFixedSavedStates() + " saved states.");
+ publish("Done!");
+ return null;
+ }
+
+ @Override
+ protected void process(List chunks)
+ {
+ for (String value : chunks)
+ {
+ dialog.updateProgress(value + "\n");
+ }
+ }
+
+ @Override
+ protected void done()
+ {
+ try
+ {
+ get();
+ }
+ catch (Exception e)
+ {
+ ExceptionHandler.handleException(e, "Error during fixing corrupt saved states");
+ }
+ dialog.finish();
+ }
+
+ @Override
+ public void publishMessage(String message)
+ {
+ publish(message);
+ }
+}
diff --git a/src/main/java/se/lantz/manager/SavedStatesManager.java b/src/main/java/se/lantz/manager/SavedStatesManager.java
index c357b91..d6f2171 100644
--- a/src/main/java/se/lantz/manager/SavedStatesManager.java
+++ b/src/main/java/se/lantz/manager/SavedStatesManager.java
@@ -64,11 +64,13 @@ public class SavedStatesManager
private File exportDir;
private File importDir;
+ private File fixDir;
private boolean exportOverwrite;
private boolean importOverwrite;
private int noFilesCopied = 0;
+ private int noSavedStatesFixed = 0;
/**
* Map holding available saved states with fileName (subfolder) as key and number of saved states available as value
@@ -328,6 +330,11 @@ public class SavedStatesManager
{
this.importDir = importDir;
}
+
+ public void setFixDirectory(File fixDir)
+ {
+ this.fixDir = fixDir;
+ }
public void setImportOverwrite(boolean importOverwrite)
{
@@ -498,17 +505,64 @@ public class SavedStatesManager
//Update model list after import
model.getGameListModel().notifyChange();
}
+
+ public void fixCorruptSavedStates(PublishWorker worker)
+ {
+ noSavedStatesFixed = 0;
+
+ try (Stream stream = Files.walk(fixDir.toPath().toAbsolutePath()))
+ {
+ stream.forEachOrdered(sourcePath -> {
+ try
+ {
+ if (!isValidSaveStateMtaFilePath(sourcePath))
+ {
+ return;
+ }
+
+ worker.publishMessage("Fixing " + sourcePath);
+ //Read the mta file and keep track of the time
+ String playTime = readPlayTime(sourcePath);
+ //Copy the template file
+ FileUtils.copyInputStreamToFile(getClass().getResourceAsStream("/se/lantz/template.mta"), sourcePath.toFile());
+ //Write the time from the old file
+ storePlayTime(sourcePath, playTime);
+ noSavedStatesFixed++;
+ }
+ catch (Exception e)
+ {
+ worker.publishMessage("Could not fix " + sourcePath.toString());
+ ExceptionHandler.logException(e, "Could not fix " + sourcePath.toString());
+ }
+ });
+ }
+ catch (IOException e1)
+ {
+ ExceptionHandler.handleException(e1, "Could not fix saved states files.");
+ }
+ }
private boolean isValidSaveStatePath(Path path)
{
PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:**.{mta,png,vsz}");
return matcher.matches(path) || path.toFile().isDirectory();
}
+
+ private boolean isValidSaveStateMtaFilePath(Path path)
+ {
+ PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:**.{mta}");
+ return matcher.matches(path);
+ }
public int getNumberOfFilesCopied()
{
return noFilesCopied;
}
+
+ public int getNumberOfFixedSavedStates()
+ {
+ return noSavedStatesFixed;
+ }
public void readSavedStatesAndUpdateMap()
{