diff --git a/src/main/java/se/lantz/gui/MenuManager.java b/src/main/java/se/lantz/gui/MenuManager.java index 8d2857e..2ddb62e 100644 --- a/src/main/java/se/lantz/gui/MenuManager.java +++ b/src/main/java/se/lantz/gui/MenuManager.java @@ -24,6 +24,7 @@ import se.lantz.gui.dbbackup.BackupWorker; import se.lantz.gui.dbrestore.RestoreDbDialog; import se.lantz.gui.dbrestore.RestoreProgressDialog; import se.lantz.gui.dbrestore.RestoreWorker; +import se.lantz.gui.exports.ExportFileLoaderWorker; import se.lantz.gui.exports.ExportGamesDialog; import se.lantz.gui.exports.ExportProgressDialog; import se.lantz.gui.exports.ExportWorker; @@ -46,6 +47,7 @@ public class MenuManager { private JMenu fileMenu; private JMenu importMenu; + private JMenu exportMenu; private JMenu editMenu; private JMenu toolsMenu; private JMenu helpMenu; @@ -57,6 +59,7 @@ public class MenuManager private JMenuItem importCarouselItem; private JMenuItem importGamebaseItem; private JMenuItem exportItem; + private JMenuItem exportFLItem; private JMenuItem refreshItem; private JMenuItem toggleFavorite1Item; @@ -131,7 +134,11 @@ public class MenuManager fileMenu.add(importMenu); importMenu.add(getImportCarouselItem()); importMenu.add(getImportGamebaseItem()); - fileMenu.add(getExportItem()); + exportMenu = new JMenu("Export"); + exportMenu.setMnemonic('X'); + exportMenu.add(getExportItem()); + exportMenu.add(getExportFileLoaderItem()); + fileMenu.add(exportMenu); fileMenu.addSeparator(); fileMenu.add(getRefreshItem()); fileMenu.addSeparator(); @@ -262,13 +269,23 @@ public class MenuManager private JMenuItem getExportItem() { - exportItem = new JMenuItem("Export games..."); + exportItem = new JMenuItem("Export to Carousel..."); KeyStroke keyStrokeToExportGames = KeyStroke.getKeyStroke(KeyEvent.VK_E, InputEvent.CTRL_DOWN_MASK); exportItem.setAccelerator(keyStrokeToExportGames); exportItem.setMnemonic('E'); exportItem.addActionListener(e -> exportGames()); return exportItem; } + + private JMenuItem getExportFileLoaderItem() + { + exportFLItem = new JMenuItem("Export to File Loader..."); + KeyStroke keyStrokeToExportGames = KeyStroke.getKeyStroke(KeyEvent.VK_L, InputEvent.CTRL_DOWN_MASK); + exportFLItem.setAccelerator(keyStrokeToExportGames); + exportFLItem.setMnemonic('L'); + exportFLItem.addActionListener(e -> exportGamesToFileLoader()); + return exportFLItem; + } private JMenuItem getRefreshItem() { @@ -720,6 +737,28 @@ public class MenuManager } } } + + private void exportGamesToFileLoader() + { + final ExportGamesDialog exportSelectionDialog = new ExportGamesDialog(MainWindow.getInstance()); + exportSelectionDialog.pack(); + exportSelectionDialog.setLocationRelativeTo(this.mainWindow); + if (exportSelectionDialog.showDialog()) + { + List gamesList = exportSelectionDialog.getSelectedGames(); + if (!gamesList.isEmpty()) + { + exportManager.setGamesToExport(gamesList); + exportManager.setTargetDirectory(exportSelectionDialog.getTargetDirectory(), + exportSelectionDialog.deleteBeforeExport(), + exportSelectionDialog.addGamesSubDirectory()); + ExportProgressDialog dialog = new ExportProgressDialog(this.mainWindow); + ExportFileLoaderWorker worker = new ExportFileLoaderWorker(exportManager, dialog); + worker.execute(); + dialog.setVisible(true); + } + } + } private void reloadView() { diff --git a/src/main/java/se/lantz/gui/exports/ExportFileLoaderWorker.java b/src/main/java/se/lantz/gui/exports/ExportFileLoaderWorker.java new file mode 100644 index 0000000..af98300 --- /dev/null +++ b/src/main/java/se/lantz/gui/exports/ExportFileLoaderWorker.java @@ -0,0 +1,68 @@ +package se.lantz.gui.exports; + +import java.util.List; + +import javax.swing.SwingWorker; + +import se.lantz.manager.ExportManager; +import se.lantz.util.ExceptionHandler; + +public class ExportFileLoaderWorker extends SwingWorker +{ + + private ExportManager exportManager; + private ExportProgressDialog dialog; + + public ExportFileLoaderWorker(ExportManager importManager, ExportProgressDialog dialog) + { + this.exportManager = importManager; + this.dialog = dialog; + } + + @Override + protected Void doInBackground() throws Exception + { + if (exportManager.isDeleteBeforeExport()) + { + publish("Deleting existing games before exporting.\n"); + } + publish("Exporting from db..."); + StringBuilder infoBuilder = new StringBuilder(); + exportManager.readFromDb(infoBuilder); + publish(infoBuilder.toString()); + publish("Creating cjm files..."); + infoBuilder = new StringBuilder(); + exportManager.createGameInfoFiles(infoBuilder, true); + publish(infoBuilder.toString()); + publish("Copy game files..."); + infoBuilder = new StringBuilder(); + exportManager.copyGamesForFileLoader(infoBuilder); + publish(infoBuilder.toString()); + exportManager.clearAfterImport(); + 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 export"); + } + dialog.finish(); + } +} diff --git a/src/main/java/se/lantz/gui/exports/ExportWorker.java b/src/main/java/se/lantz/gui/exports/ExportWorker.java index ca81e1f..5fa41fb 100644 --- a/src/main/java/se/lantz/gui/exports/ExportWorker.java +++ b/src/main/java/se/lantz/gui/exports/ExportWorker.java @@ -32,7 +32,7 @@ public class ExportWorker extends SwingWorker publish(infoBuilder.toString()); publish("Creating game info files..."); infoBuilder = new StringBuilder(); - exportManager.createGameInfoFiles(infoBuilder); + exportManager.createGameInfoFiles(infoBuilder, false); publish(infoBuilder.toString()); publish("Copy screenshots, covers and game files..."); infoBuilder = new StringBuilder(); diff --git a/src/main/java/se/lantz/manager/ExportManager.java b/src/main/java/se/lantz/manager/ExportManager.java index 9da382b..3890340 100644 --- a/src/main/java/se/lantz/manager/ExportManager.java +++ b/src/main/java/se/lantz/manager/ExportManager.java @@ -105,11 +105,11 @@ public class ExportManager gameDetailsList = uiModel.readGameDetailsForExport(infoBuilder, gamesList); } - public void createGameInfoFiles(StringBuilder infoBuilder) + public void createGameInfoFiles(StringBuilder infoBuilder, boolean fileLoader) { for (GameDetails gameDetails : gameDetailsList) { - uiModel.exportGameInfoFile(gameDetails, targetDir, infoBuilder); + uiModel.exportGameInfoFile(gameDetails, targetDir, infoBuilder, fileLoader); } } @@ -118,39 +118,33 @@ public class ExportManager return deleteBeforeExport; } - - public void copyFiles(StringBuilder infoBuilder) { - - try - { - Path targetCoverPath = targetDir.toPath().resolve("covers"); - Files.createDirectories(targetCoverPath); - Path targetScreenPath = targetDir.toPath().resolve("screens"); - Files.createDirectories(targetScreenPath); - Path targetGamePath = targetDir.toPath().resolve("games"); - Files.createDirectories(targetGamePath); - } - catch (IOException e) - { - infoBuilder - .append("ERROR: Could not create directories for covers, screens and games, " + e.getMessage() + "\n"); - ExceptionHandler.handleException(e, " Could not create directories for covers, screens and games"); - return; - } - - + try + { + Path targetCoverPath = targetDir.toPath().resolve("covers"); + Files.createDirectories(targetCoverPath); + Path targetScreenPath = targetDir.toPath().resolve("screens"); + Files.createDirectories(targetScreenPath); + Path targetGamePath = targetDir.toPath().resolve("games"); + Files.createDirectories(targetGamePath); + } + catch (IOException e) + { + infoBuilder.append("ERROR: Could not create directories for covers, screens and games, " + e.getMessage() + "\n"); + ExceptionHandler.handleException(e, " Could not create directories for covers, screens and games"); + return; + } for (GameDetails gameDetails : gameDetailsList) { Path coverPath = Paths.get("./covers/" + gameDetails.getCover()); Path targetCoverPath = targetDir.toPath().resolve("covers/" + gameDetails.getCover()); - + Path screens1Path = Paths.get("./screens/" + gameDetails.getScreen1()); Path targetScreen1Path = targetDir.toPath().resolve("screens/" + gameDetails.getScreen1()); Path screens2Path = Paths.get("./screens/" + gameDetails.getScreen2()); Path targetScreen2Path = targetDir.toPath().resolve("screens/" + gameDetails.getScreen2()); - + Path gamePath = Paths.get("./games/" + gameDetails.getGame()); Path targetGamePath = targetDir.toPath().resolve("games/" + gameDetails.getGame()); @@ -192,6 +186,45 @@ public class ExportManager } } } + + public void copyGamesForFileLoader(StringBuilder infoBuilder) + { + try + { + Path targetGamePath = targetDir.toPath(); + Files.createDirectories(targetGamePath); + } + catch (IOException e) + { + infoBuilder.append("ERROR: Could not create directory for games, " + e.getMessage() + "\n"); + ExceptionHandler.handleException(e, " Could not create directory for games"); + return; + } + for (GameDetails gameDetails : gameDetailsList) + { + Path gamePath = Paths.get("./games/" + gameDetails.getGame()); + + //TODO: Unzip if needed, rename vsf files to prg according to Spannernick + + Path targetGamePath = targetDir.toPath().resolve(gameDetails.getGame()); + + try + { + if (!gameDetails.getGame().isEmpty()) + { + infoBuilder.append("Copying game file from "); + infoBuilder.append(gamePath.toString()); + infoBuilder.append("\n"); + Files.copy(gamePath, targetGamePath, StandardCopyOption.REPLACE_EXISTING); + } + } + catch (IOException e) + { + infoBuilder.append("ERROR: Could not copy files for " + gameDetails.getTitle() + ", " + e.getMessage() + "\n"); + ExceptionHandler.handleException(e, "Could NOT copy files for: " + gameDetails.getTitle()); + } + } + } public void clearAfterImport() { diff --git a/src/main/java/se/lantz/model/MainViewModel.java b/src/main/java/se/lantz/model/MainViewModel.java index 32975c5..377dadd 100644 --- a/src/main/java/se/lantz/model/MainViewModel.java +++ b/src/main/java/se/lantz/model/MainViewModel.java @@ -274,9 +274,9 @@ public class MainViewModel extends AbstractModel return returnList; } - public void exportGameInfoFile(GameDetails gameDetails, File targetDir, StringBuilder infoBuilder) + public void exportGameInfoFile(GameDetails gameDetails, File targetDir, StringBuilder infoBuilder, boolean fileLoader) { - fileManager.exportGameInfoFile(gameDetails, targetDir, infoBuilder); + fileManager.exportGameInfoFile(gameDetails, targetDir, infoBuilder, fileLoader); } public InfoModel getInfoModel() diff --git a/src/main/java/se/lantz/util/FileManager.java b/src/main/java/se/lantz/util/FileManager.java index 1552882..c45e0c4 100644 --- a/src/main/java/se/lantz/util/FileManager.java +++ b/src/main/java/se/lantz/util/FileManager.java @@ -366,16 +366,45 @@ public class FileManager logger.debug("Game title: \"{}\" ---- New fileName: \"{}\"", title, newNameString); return newNameString; } + + public static String generateFileNameFromTitleForFileLoader(String title, int duplicateIndex) + { + List forbiddenCharsList = + ":,'’!+*<>()/[]?|".chars().mapToObj(item -> (char) item).collect(Collectors.toList()); - public void exportGameInfoFile(GameDetails gameDetails, File targetDir, StringBuilder infoBuilder) + List newName = + title.chars().mapToObj(item -> (char) item).filter(character -> !forbiddenCharsList.contains(character)) + .collect(Collectors.toList()); + String newNameString = newName.stream().map(String::valueOf).collect(Collectors.joining()); + if (duplicateIndex > 0) + { + //Just add the duplicate index if there are several games with the same name + newNameString = newNameString + "0" + duplicateIndex; + } + + logger.debug("Game title: \"{}\" ---- New fileName: \"{}\"", title, newNameString); + return newNameString; + } + + public void exportGameInfoFile(GameDetails gameDetails, File targetDir, StringBuilder infoBuilder, boolean fileLoader) { try { - String filename = generateFileNameFromTitle(gameDetails.getTitle(), gameDetails.getDuplicateIndex()); - infoBuilder.append("Creating game info file for " + gameDetails.getTitle() + "\n"); - //Add -ms to comply with the maxi game tool. - filename = filename + "-ms.tsg"; - writeGameInfoFile(filename, targetDir, gameDetails); + String filename = ""; + + if (fileLoader) + { + infoBuilder.append("Creating cjm file for " + gameDetails.getTitle() + "\n"); + filename = generateFileNameFromTitleForFileLoader(gameDetails.getTitle(), gameDetails.getDuplicateIndex()) + ".cjm"; + } + else + { + infoBuilder.append("Creating game info file for " + gameDetails.getTitle() + "\n"); + //Add -ms to comply with the maxi game tool. + filename = generateFileNameFromTitle(gameDetails.getTitle(), gameDetails.getDuplicateIndex()) + "-ms.tsg"; + } + + writeGameInfoFile(filename, targetDir, gameDetails, fileLoader); } catch (Exception e) { @@ -385,47 +414,49 @@ public class FileManager } } - public void writeGameInfoFile(String fileName, File targetDir, GameDetails gameDetails) throws IOException + public void writeGameInfoFile(String fileName, File targetDir, GameDetails gameDetails, boolean fileLoader) throws IOException { Path outDirPath = targetDir.toPath(); Path filePath = outDirPath.resolve(fileName); filePath.toFile().createNewFile(); FileWriter fw = new FileWriter(filePath.toFile()); - - fw.write("T:" + gameDetails.getTitle() + "\n"); + + if (!fileLoader) + { + fw.write("T:" + gameDetails.getTitle() + "\n"); + String description = replaceMinus(gameDetails.getDescription()); + fw.write("D:en:" + description + "\n"); + fw.write("D:de:" + + (gameDetails.getDescriptionDe().isEmpty() ? description : replaceMinus(gameDetails.getDescriptionDe())) + "\n"); + fw.write("D:fr:" + + (gameDetails.getDescriptionFr().isEmpty() ? description : replaceMinus(gameDetails.getDescriptionFr())) + "\n"); + fw.write("D:es:" + + (gameDetails.getDescriptionEs().isEmpty() ? description : replaceMinus(gameDetails.getDescriptionEs())) + "\n"); + fw.write("D:it:" + + (gameDetails.getDescriptionIt().isEmpty() ? description : replaceMinus(gameDetails.getDescriptionIt())) + "\n"); + if (!gameDetails.getAuthor().isEmpty()) + { + fw.write("A:" + gameDetails.getAuthor() + "\n"); + } + if (!gameDetails.getComposer().isEmpty()) + { + fw.write("M:" + gameDetails.getComposer() + "\n"); + } + fw.write("E:" + gameDetails.getGenre() + "\n"); + fw.write("Y:" + gameDetails.getYear() + "\n"); + + fw.write("F:" + "games/" + gameDetails.getGame() + "\n"); + fw.write("C:" + "covers/" + gameDetails.getCover() + "\n"); + if (!gameDetails.getScreen1().isEmpty()) + { + fw.write("G:" + "screens/" + gameDetails.getScreen1() + "\n"); + } + if (!gameDetails.getScreen2().isEmpty()) + { + fw.write("G:" + "screens/" + gameDetails.getScreen2() + "\n"); + } + } fw.write("X:" + gameDetails.getSystem() + "\n"); - String description = replaceMinus(gameDetails.getDescription()); - fw.write("D:en:" + description + "\n"); - fw.write("D:de:" + - (gameDetails.getDescriptionDe().isEmpty() ? description : replaceMinus(gameDetails.getDescriptionDe())) + "\n"); - fw.write("D:fr:" + - (gameDetails.getDescriptionFr().isEmpty() ? description : replaceMinus(gameDetails.getDescriptionFr())) + "\n"); - fw.write("D:es:" + - (gameDetails.getDescriptionEs().isEmpty() ? description : replaceMinus(gameDetails.getDescriptionEs())) + "\n"); - fw.write("D:it:" + - (gameDetails.getDescriptionIt().isEmpty() ? description : replaceMinus(gameDetails.getDescriptionIt())) + "\n"); - if (!gameDetails.getAuthor().isEmpty()) - { - fw.write("A:" + gameDetails.getAuthor() + "\n"); - } - if (!gameDetails.getComposer().isEmpty()) - { - fw.write("M:" + gameDetails.getComposer() + "\n"); - } - fw.write("E:" + gameDetails.getGenre() + "\n"); - fw.write("Y:" + gameDetails.getYear() + "\n"); - - fw.write("F:" + "games/" + gameDetails.getGame() + "\n"); - fw.write("C:" + "covers/" + gameDetails.getCover() + "\n"); - if (!gameDetails.getScreen1().isEmpty()) - { - fw.write("G:" + "screens/" + gameDetails.getScreen1() + "\n"); - } - if (!gameDetails.getScreen2().isEmpty()) - { - fw.write("G:" + "screens/" + gameDetails.getScreen2() + "\n"); - } - if (!gameDetails.getJoy1().isEmpty()) { fw.write(gameDetails.getJoy1() + "\n");