feat: Adds menu option to convert all screenshots to 32-bit color depth

This commit is contained in:
mikael.lantz 2021-02-05 16:18:14 +01:00
parent e0b75056ca
commit 5ef84bf316
7 changed files with 303 additions and 38 deletions

View File

@ -3,30 +3,19 @@ package se.lantz.gui;
import java.awt.Desktop;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import javax.swing.JFileChooser;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.KeyStroke;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.stream.JsonReader;
import se.lantz.gui.convertscreens.ConvertProgressDialog;
import se.lantz.gui.convertscreens.ConvertWorker;
import se.lantz.gui.dbbackup.BackupProgressDialog;
import se.lantz.gui.dbbackup.BackupWorker;
import se.lantz.gui.dbrestore.RestoreDbDialog;
@ -44,7 +33,6 @@ import se.lantz.manager.ImportManager;
import se.lantz.manager.RestoreManager;
import se.lantz.model.MainViewModel;
import se.lantz.model.data.GameListData;
import se.lantz.util.ExceptionHandler;
import se.lantz.util.FileManager;
import se.lantz.util.VersionChecker;
@ -63,7 +51,7 @@ public class MenuManager
private JMenuItem runGameItem;
private JMenuItem importItem;
private JMenuItem exportItem;
private JMenuItem toggleFavoriteItem;
private JMenuItem clearFavoritesItem;
@ -71,6 +59,8 @@ public class MenuManager
private JMenuItem restoreDbItem;
private JMenuItem createEmptyDbItem;
private JMenuItem convertScreensItem;
private JMenuItem helpItem;
private JMenuItem aboutItem;
private JMenuItem newVersionItem;
@ -114,10 +104,12 @@ public class MenuManager
editMenu = new JMenu("Edit");
editMenu.add(getToggleFavoriteItem());
editMenu.add(getClearFavoritesItem());
dbMenu = new JMenu("Database");
dbMenu = new JMenu("Tools");
dbMenu.add(getBackupDbItem());
dbMenu.add(getRestoreDbItem());
dbMenu.add(getCreateEmptyDbItem());
dbMenu.addSeparator();
dbMenu.add(getConvertScreensItem());
helpMenu = new JMenu("Help");
helpMenu.add(getHelpItem());
helpMenu.add(getCheckVersionItem());
@ -167,7 +159,7 @@ public class MenuManager
deleteGameItem.addActionListener(e -> mainWindow.getMainPanel().deleteCurrentGame());
return deleteGameItem;
}
JMenuItem getRunGameMenuItem()
{
runGameItem = new JMenuItem("Run Current Game");
@ -204,7 +196,7 @@ public class MenuManager
exitItem = new JMenuItem("Exit");
KeyStroke keyStrokeExit = KeyStroke.getKeyStroke(KeyEvent.VK_F4, InputEvent.ALT_DOWN_MASK);
exitItem.setAccelerator(keyStrokeExit);
exitItem.setMnemonic('x');
exitItem.addActionListener(e -> {
if (uiModel.isDataChanged())
@ -227,7 +219,7 @@ public class MenuManager
});
return exitItem;
}
private JMenuItem getToggleFavoriteItem()
{
toggleFavoriteItem = new JMenuItem("Add/remove from favorites");
@ -239,7 +231,7 @@ public class MenuManager
});
return toggleFavoriteItem;
}
private JMenuItem getClearFavoritesItem()
{
clearFavoritesItem = new JMenuItem("Clear all favorites");
@ -271,6 +263,13 @@ public class MenuManager
return createEmptyDbItem;
}
private JMenuItem getConvertScreensItem()
{
convertScreensItem = new JMenuItem("Convert screenshots...");
convertScreensItem.addActionListener(e -> convertScreens());
return convertScreensItem;
}
private JMenuItem getHelpItem()
{
helpItem = new JMenuItem("Help");
@ -283,7 +282,10 @@ public class MenuManager
}
catch (IOException | URISyntaxException ex)
{
JOptionPane.showMessageDialog(MainWindow.getInstance(), "Could not open help", "Help missing", JOptionPane.ERROR_MESSAGE);
JOptionPane.showMessageDialog(MainWindow.getInstance(),
"Could not open help",
"Help missing",
JOptionPane.ERROR_MESSAGE);
}
});
return helpItem;
@ -341,7 +343,9 @@ public class MenuManager
if (!gamesList.isEmpty())
{
exportManager.setGamesToExport(gamesList);
exportManager.setTargetDirectory(exportSelectionDialog.getTargetDirectory(), exportSelectionDialog.deleteBeforeExport(), exportSelectionDialog.addGamesSubDirectory());
exportManager.setTargetDirectory(exportSelectionDialog.getTargetDirectory(),
exportSelectionDialog.deleteBeforeExport(),
exportSelectionDialog.addGamesSubDirectory());
ExportProgressDialog dialog = new ExportProgressDialog(this.mainWindow);
ExportWorker worker = new ExportWorker(exportManager, dialog);
worker.execute();
@ -393,11 +397,25 @@ public class MenuManager
MainWindow.getInstance().selectViewAfterRestore();
}
}
private void clearFavorites()
private void convertScreens()
{
String message =
"Are you sure you want to clear all games marked as favorites?";
"Do you want to check all screenshots in the database and convert them to use 32-bit color depths?\nThe PCU list selector screen requires 32-bit depths for the screenshots to be rendered properly.";
int option = JOptionPane.showConfirmDialog(MainWindow.getInstance()
.getMainPanel(), message, "Convert screenshots", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if (option == JOptionPane.YES_OPTION)
{
ConvertProgressDialog dialog = new ConvertProgressDialog(this.mainWindow);
ConvertWorker worker = new ConvertWorker(dialog);
worker.execute();
dialog.setVisible(true);
}
}
private void clearFavorites()
{
String message = "Are you sure you want to clear all games marked as favorites?";
int option = JOptionPane.showConfirmDialog(MainWindow.getInstance()
.getMainPanel(), message, "Clear all favorites", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if (option == JOptionPane.YES_OPTION)

View File

@ -0,0 +1,44 @@
package se.lantz.gui.convertscreens;
import java.awt.Frame;
import javax.swing.JDialog;
import javax.swing.WindowConstants;
public class ConvertProgressDialog extends JDialog
{
private static final long serialVersionUID = 1L;
private ConvertProgressPanel panel;
public ConvertProgressDialog(Frame frame)
{
super(frame, "Convert screenshots", true);
this.add(getConvertProgressPanel());
setSize(900, 600);
setAlwaysOnTop(true);
setLocationRelativeTo(frame);
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
}
public void updateProgress(String infoText)
{
getConvertProgressPanel().updateProgress(infoText);
this.repaint();
}
public void finish(int count, Exception e)
{
getConvertProgressPanel().finish(count, e);
}
public ConvertProgressPanel getConvertProgressPanel()
{
if (panel == null)
{
panel = new ConvertProgressPanel();
panel.getCloseButton().addActionListener(e -> setVisible(false));
}
return panel;
}
}

View File

@ -0,0 +1,114 @@
package se.lantz.gui.convertscreens;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ConvertProgressPanel extends JPanel
{
private static final Logger logger = LoggerFactory.getLogger(ConvertProgressPanel.class);
private JProgressBar progressBar;
private JTextArea textArea;
private JScrollPane textScrollPane;
private JButton closeButton;
public ConvertProgressPanel()
{
GridBagLayout gridBagLayout = new GridBagLayout();
setLayout(gridBagLayout);
GridBagConstraints gbc_progressBar = new GridBagConstraints();
gbc_progressBar.weightx = 1.0;
gbc_progressBar.fill = GridBagConstraints.HORIZONTAL;
gbc_progressBar.insets = new Insets(10, 5, 5, 5);
gbc_progressBar.gridx = 0;
gbc_progressBar.gridy = 0;
add(getProgressBar(), gbc_progressBar);
GridBagConstraints gbc_textScrollPane = new GridBagConstraints();
gbc_textScrollPane.insets = new Insets(0, 5, 5, 5);
gbc_textScrollPane.weighty = 1.0;
gbc_textScrollPane.weightx = 1.0;
gbc_textScrollPane.fill = GridBagConstraints.BOTH;
gbc_textScrollPane.gridx = 0;
gbc_textScrollPane.gridy = 1;
add(getTextScrollPane(), gbc_textScrollPane);
GridBagConstraints gbc_closeButton = new GridBagConstraints();
gbc_closeButton.insets = new Insets(0, 5, 5, 5);
gbc_closeButton.gridx = 0;
gbc_closeButton.gridy = 2;
add(getCloseButton(), gbc_closeButton);
}
private JProgressBar getProgressBar()
{
if (progressBar == null)
{
progressBar = new JProgressBar();
progressBar.setIndeterminate(true);
}
return progressBar;
}
private JTextArea getTextArea()
{
if (textArea == null)
{
textArea = new JTextArea();
textArea.setEditable(false);
}
return textArea;
}
private JScrollPane getTextScrollPane()
{
if (textScrollPane == null)
{
textScrollPane = new JScrollPane();
textScrollPane.setViewportView(getTextArea());
}
return textScrollPane;
}
JButton getCloseButton()
{
if (closeButton == null)
{
closeButton = new JButton("Close");
closeButton.setEnabled(false);
}
return closeButton;
}
void updateProgress(String infoText)
{
getTextArea().append(infoText);
}
public void finish(int count, Exception e)
{
getCloseButton().setEnabled(true);
getProgressBar().setIndeterminate(false);
getProgressBar().setValue(getProgressBar().getMaximum());
if (e != null)
{
logger.error("Screen convertion failed", e);
getTextArea().append("\nConvertion failed: " + e.getMessage());
}
else if (count == 0)
{
getTextArea().append("\nNothing to convert, all up to date.");
}
else
{
getTextArea().append("\nConverted " + count + " screens successfully.");
}
}
}

View File

@ -0,0 +1,52 @@
package se.lantz.gui.convertscreens;
import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.swing.SwingWorker;
import se.lantz.util.FileManager;
public class ConvertWorker extends SwingWorker<Integer, String>
{
private ConvertProgressDialog dialog;
public ConvertWorker(ConvertProgressDialog dialog)
{
this.dialog = dialog;
}
@Override
protected Integer doInBackground() throws Exception
{
publish("Reading screnshots...");
List<String> convertionList = FileManager.convertAllScreenshotsTo32Bit();
for (String screenshot : convertionList)
{
publish(screenshot);
}
return convertionList.size();
}
@Override
protected void process(List<String> chunks)
{
for (String value : chunks)
{
dialog.updateProgress(value + "\n");
}
}
@Override
protected void done()
{
try
{
dialog.finish(this.get(), null);
}
catch (InterruptedException | ExecutionException e)
{
dialog.finish(0, e);
}
}
}

View File

@ -3,6 +3,7 @@ package se.lantz.gui.exports;
import java.awt.Frame;
import javax.swing.JDialog;
import javax.swing.WindowConstants;
public class ExportProgressDialog extends JDialog
{
@ -17,6 +18,7 @@ public class ExportProgressDialog extends JDialog
setSize(900, 600);
setAlwaysOnTop(true);
setLocationRelativeTo(frame);
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
}
public void updateProgress(String infoText)

View File

@ -3,6 +3,7 @@ package se.lantz.gui.imports;
import java.awt.Frame;
import javax.swing.JDialog;
import javax.swing.WindowConstants;
public class ImportProgressDialog extends JDialog
{
@ -17,6 +18,7 @@ public class ImportProgressDialog extends JDialog
setSize(900, 600);
setAlwaysOnTop(true);
setLocationRelativeTo(frame);
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
}
public void updateProgress(String infoText)

View File

@ -241,14 +241,14 @@ public class FileManager
//Screen 2
String screens2File = infoModel.getScreens2File();
String oldScreens2File = infoModel.getOldScreens2File();
//Special case if the same screen has been used for both screens: Copy first to second in this case
if (!oldScreens1File.isEmpty() && !oldScreens2File.isEmpty() && oldScreens1File.equals(oldScreens2File))
{
try
{
Files.copy(new File(SCREENS + screens1File).toPath(), new File(SCREENS + screens2File).toPath());
logger.debug("Copied {} to {}", screens1File, screens2File);
logger.debug("Copied {} to {}", screens1File, screens2File);
}
catch (IOException e)
{
@ -259,22 +259,22 @@ public class FileManager
{
if (!screens2File.isEmpty() && !oldScreens2File.isEmpty() && !screens2File.equals(oldScreens2File))
{
File oldScreen2 = new File(SCREENS + oldScreens2File);
File newScreen2 = new File(SCREENS + screens2File);
if (oldScreen2.renameTo(newScreen2))
{
logger.debug("Renamed screen2 {} to {}", oldScreen2.getName(), newScreen2.getName());
}
else
{
logger.debug("Could NOT rename screen2 {} to {}", oldScreen2.getName(), newScreen2.getName());
}
File oldScreen2 = new File(SCREENS + oldScreens2File);
File newScreen2 = new File(SCREENS + screens2File);
if (oldScreen2.renameTo(newScreen2))
{
logger.debug("Renamed screen2 {} to {}", oldScreen2.getName(), newScreen2.getName());
}
else
{
logger.debug("Could NOT rename screen2 {} to {}", oldScreen2.getName(), newScreen2.getName());
}
}
}
//Gamefile
String gamesFile = infoModel.getGamesFile();
String oldGamesFile = infoModel.getOldGamesFile();
if (!gamesFile.isEmpty() && !oldGamesFile.isEmpty() && !gamesFile.equals(oldGamesFile))
if (!gamesFile.isEmpty() && !oldGamesFile.isEmpty() && !gamesFile.equals(oldGamesFile))
{
File oldGame = new File(GAMES + oldGamesFile);
File newGame = new File(GAMES + gamesFile);
@ -922,4 +922,37 @@ public class FileManager
return ze;
}
public static List<String> convertAllScreenshotsTo32Bit() throws IOException
{
List<String> convertedScreensList = new ArrayList<>();
Files.walk(Paths.get(SCREENS), 1).filter(Files::isRegularFile).forEach(source -> {
BufferedImage image = null;
File currentFile = (source.toFile());
try
{
image = ImageIO.read(currentFile);
if (image != null && image.getType() != BufferedImage.TYPE_INT_ARGB &&
image.getType() != BufferedImage.TYPE_4BYTE_ABGR)
{
//Convert to 32 bit
BufferedImage convertedImage =
new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics g = convertedImage.createGraphics();
g.drawImage(image, 0, 0, null);
//Write new file
ImageIO.write(convertedImage, "png", currentFile);
convertedScreensList.add(source.getFileName().toString());
}
}
catch (Exception e)
{
logger.error("can't read file: " + source.toString(), e);
}
});
return convertedScreensList;
}
}