fix: add, backup and restore db works

This commit is contained in:
lantzelot-swe 2024-05-23 16:30:03 +02:00
parent 812a3b16f2
commit 00d739401a
6 changed files with 256 additions and 94 deletions

View File

@ -33,6 +33,7 @@ import se.lantz.util.GameListDataComparator;
public class DbConnector
{
public static String DB_FILE_NAME = "pcusb.db";
public static String DB_FILE = "";
private static final String COMMA = "\",\"";
// @J-
@ -105,27 +106,32 @@ public class DbConnector
columnList.add(DbConstants.DISK_4);
columnList.add(DbConstants.DISK_5);
columnList.add(DbConstants.DISK_6);
for (String dbFolder : dbFolders)
{
setCurrentDbFolder(dbFolder);
//Check if databases file exists, if not create an empty db.
File dbFile = new File("./" + DB_FILE);
if (!dbFile.exists())
{
createNewDb();
logger.debug("Database {} missing, new db created.", dbFolder);
}
//To be backwards compatible with 1.0 db, update if missing
addLanguageAndDuplicateColumnsIfMissing();
//To be backwards compatible with 2.8.2 db, update if missing
addDiskColumnsIfMissing();
createDbIfMissing(dbFolder);
}
}
public void createDbIfMissing(String folderName)
{
//Check if databases file exists, if not create an empty db.
File dbFile = new File("./" + DB_FILE);
if (!dbFile.exists())
{
createNewDb();
logger.debug("Database {} missing, new db created.", folderName);
}
//To be backwards compatible with 1.0 db, update if missing
addLanguageAndDuplicateColumnsIfMissing();
//To be backwards compatible with 2.8.2 db, update if missing
addDiskColumnsIfMissing();
}
public static void setCurrentDbFolder(String dbFolder)
{
DB_FILE = "./databases/" + dbFolder + "/pcusb.db";
DB_FILE = "./databases/" + dbFolder + "/" + DB_FILE_NAME;
}
private void createNewDb()

View File

@ -14,10 +14,7 @@ import java.awt.image.BufferedImage;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
public class DraggableTabbedPane extends JTabbedPane
{
@ -32,14 +29,13 @@ public class DraggableTabbedPane extends JTabbedPane
private ActionListener draggedTabListener = null;
private ActionListener tabStructureChangedListener = null;
private boolean removingTab = false;
public DraggableTabbedPane()
{
super();
addMouseMotionListener(new MouseMotionAdapter()
{
public void mouseDragged(MouseEvent e)
{
@ -165,34 +161,31 @@ public class DraggableTabbedPane extends JTabbedPane
// Need to repaint
repaint();
}
@Override
public void mouseClicked(MouseEvent e)
{
if (SwingUtilities.isRightMouseButton(e))
{
int tabNumber = getUI().tabForCoordinate(DraggableTabbedPane.this, e.getX(), 10);
if (tabNumber > -1 && (tabNumber < getTabCount() - 1))
{
JPopupMenu menu = new JPopupMenu();
JMenuItem renameTabItem = new JMenuItem("Rename database");
JMenuItem deleteTabItem = new JMenuItem("Delete database");
menu.add(renameTabItem);
menu.add(deleteTabItem);
menu.show(DraggableTabbedPane.this, e.getX(), e.getY());
}
}
}
});
}
@Override
public void removeTabAt(int index)
{
//Select a proper tab after removing
if (getSelectedIndex() == getTabCount() - 2)
{
this.removingTab = true;
super.removeTabAt(index);
this.removingTab = false;
setSelectedIndex(getTabCount() - 2);
}
else
{
super.removeTabAt(index);
}
}
public void addTabDraggedListener(ActionListener listener)
{
draggedTabListener = listener;
}
public void addTabStructureChangedListener(ActionListener listener)
{
tabStructureChangedListener = listener;
@ -205,7 +198,7 @@ public class DraggableTabbedPane extends JTabbedPane
draggedTabListener.actionPerformed(new ActionEvent(this, tabNumber, "inserted"));
}
}
private void notifyTabStructureChangedListener()
{
if (tabStructureChangedListener != null)
@ -219,6 +212,11 @@ public class DraggableTabbedPane extends JTabbedPane
return dragging;
}
public boolean isRemovingTab()
{
return removingTab;
}
public int getPreviouslySelectedIndex()
{
return previouslySelectedIndex;

View File

@ -1,16 +1,24 @@
package se.lantz.gui;
import java.awt.BorderLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import javax.swing.JComponent;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JSplitPane;
import javax.swing.SwingUtilities;
import se.lantz.model.MainViewModel;
import se.lantz.model.data.GameListData;
import se.lantz.util.ExceptionHandler;
public class MainPanel extends JPanel
{
@ -58,11 +66,11 @@ public class MainPanel extends JPanel
//Update previous selected index once a tab is dragged to a new position
tabbedPane.addTabDraggedListener(e -> previouslySelectedIndex = e.getID());
//Update preferences when the tab structure changes (renamed, deleted, re-arranged)
//Update preferences when the tab positions changes
tabbedPane.addTabStructureChangedListener(e -> updateTabOrderPreferences());
tabbedPane.addChangeListener(e -> {
if (!tabbedPane.isDragging())
if (!tabbedPane.isRemovingTab() && !tabbedPane.isDragging())
{
if (tabbedPane.getSelectedIndex() == uiModel.getAvailableDatabases().size())
{
@ -70,6 +78,7 @@ public class MainPanel extends JPanel
tabbedPane.setSelectedIndex(previouslySelectedIndex);
ignoreTabChange = false;
String name = JOptionPane.showInputDialog(this, "Write a new name!");
createNewTab(name);
//Create a new empty one!
return;
}
@ -92,10 +101,114 @@ public class MainPanel extends JPanel
repaint();
}
});
tabbedPane.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
if (SwingUtilities.isRightMouseButton(e))
{
int tabNumber = tabbedPane.getUI().tabForCoordinate(tabbedPane, e.getX(), 10);
if (tabNumber > -1 && (tabNumber < tabbedPane.getTabCount() - 1))
{
JPopupMenu menu = new JPopupMenu();
JMenuItem renameTabItem = new JMenuItem("Rename database");
renameTabItem.addActionListener(ev -> renameTab(tabNumber));
JMenuItem deleteTabItem = new JMenuItem("Delete database");
deleteTabItem.addActionListener(ev -> deleteTab(tabNumber));
menu.add(renameTabItem);
menu.add(deleteTabItem);
menu.show(tabbedPane, e.getX(), e.getY());
}
}
}
});
}
return tabbedPane;
}
private void renameTab(int tabIndex)
{
String oldName = tabbedPane.getTitleAt(tabIndex);
String newName = (String) JOptionPane.showInputDialog(this,
"Enter new name for \"" + oldName + "\"",
"Rename database",
JOptionPane.QUESTION_MESSAGE,
null,
null,
oldName);
if (newName != null)
{
try
{
uiModel.renameTab(oldName, newName);
tabbedPane.setTitleAt(tabIndex, newName);
updateTabOrderPreferences();
}
catch (IOException e)
{
ExceptionHandler.handleException(e, "Could not rename database");
}
}
}
private void deleteTab(int tabIndex)
{
String selectedTab = tabbedPane.getTitleAt(tabIndex);
int answer = JOptionPane.showConfirmDialog(this,
"Are you sure you want to delete the " + selectedTab +
" database?\nIt will be removed completely from the databases folder.",
"Delete database",
JOptionPane.YES_NO_OPTION);
if (answer == JOptionPane.YES_OPTION)
{
try
{
uiModel.deleteTab(selectedTab);
tabbedPane.removeTabAt(tabIndex);
updateTabOrderPreferences();
}
catch (IOException e)
{
ExceptionHandler.handleException(e, "Could not delete database");
}
}
}
private void createNewTab(String name)
{
//TODO: Check name here, do not add one with same name as existing, or null, or empty
if (name == null || name.isEmpty() || name.isBlank())
{
//Do nothing
return;
}
List<String> lowerCaseNames =
uiModel.getAvailableDatabases().stream().map(x -> x.toLowerCase()).collect(Collectors.toList());
if (lowerCaseNames.contains(name.toLowerCase().trim()))
{
JOptionPane.showMessageDialog(this,
"A database with name " + name.trim() + " already exists",
"Duplicate db name",
JOptionPane.INFORMATION_MESSAGE);
return;
}
try
{
uiModel.addTab(name);
tabbedPane.insertTab(name, null, getNewContentPanel(null), null, tabbedPane.getTabCount() - 1);
tabbedPane.setSelectedIndex(tabbedPane.getTabCount() - 2);
updateTabOrderPreferences();
}
catch (IOException e)
{
ExceptionHandler.handleException(e, "Could not create database");
}
}
private void updateTabOrderPreferences()
{
List<String> tabTitles = new ArrayList<>();

View File

@ -13,48 +13,50 @@ public class BackupManager
{
private static final Logger logger = LoggerFactory.getLogger(BackupManager.class);
private MainViewModel uiModel;
private String currentFolderName = "";
public BackupManager(MainViewModel uiModel)
{
this.uiModel = uiModel;
}
public String setupTargetFolderName()
{
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss");
LocalDateTime now = LocalDateTime.now();
//String for current date and time
currentFolderName = dtf.format(now);
currentFolderName = FileManager.getCurrentDbName() + "-" + currentFolderName;
return currentFolderName;
}
public void backupDb()
{
FileManager.backupDb(currentFolderName);
}
public void backupCovers()
{
FileManager.backupCovers(currentFolderName);
}
public void backupScreens()
{
FileManager.backupScreens(currentFolderName);
}
public void backupGames()
{
FileManager.backupGames(currentFolderName);
}
public void backupExtraDisks()
{
FileManager.backupExtraDisks(currentFolderName);
}
public void backupSaves()
{
FileManager.backupSaves(currentFolderName);

View File

@ -43,7 +43,7 @@ import se.lantz.util.TextComponentSupport;
public class MainViewModel extends AbstractModel
{
public static final String DB_TAB_ORDER = "dbTabOrder";
private static final Logger logger = LoggerFactory.getLogger(MainViewModel.class);
DbConnector dbConnector;
@ -111,7 +111,7 @@ public class MainViewModel extends AbstractModel
{
ExceptionHandler.handleException(ex, "Could not read databases");
}
if (availableDatabases.size() > 0)
{
//Read preferences for tab order
@ -120,23 +120,46 @@ public class MainViewModel extends AbstractModel
if (tabOrder != null)
{
List<String> preferencesOrder = Arrays.asList(tabOrder.split("\\s*,\\s*"));
Collections.sort(availableDatabases,
Comparator.comparing(item -> preferencesOrder.indexOf(item)));
Collections.sort(availableDatabases, Comparator.comparing(item -> preferencesOrder.indexOf(item)));
}
selectedDatabase = availableDatabases.get(0);
FileManager.setCurrentDbFolder(selectedDatabase);
DbConnector.setCurrentDbFolder(selectedDatabase);
}
}
}
public void updateDbTabPreferences(String prefValue)
{
Properties configuredProperties = FileManager.getConfiguredProperties();
configuredProperties.put(DB_TAB_ORDER, prefValue);
}
public void renameTab(String oldName, String newName) throws IOException
{
Path source = Paths.get("./databases" + "/" + oldName);
Files.move(source, source.resolveSibling(newName));
selectedDatabase = newName;
FileManager.setCurrentDbFolder(selectedDatabase);
DbConnector.setCurrentDbFolder(selectedDatabase);
}
public void deleteTab(String dbName) throws IOException
{
availableDatabases.remove(dbName);
Path source = Paths.get("./databases" + "/" + dbName);
Files.walk(source).sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete);
}
public void addTab(String name) throws IOException
{
FileManager.createNewDb(name);
availableDatabases.add(name);
}
public void setSavedStatesManager(SavedStatesManager savedStatesManager)
{
this.stateManager = savedStatesManager;
@ -1329,12 +1352,12 @@ public class MainViewModel extends AbstractModel
{
return this.currentGameDetails;
}
public List<String> getAvailableDatabases()
{
return availableDatabases;
}
public void setCurrentDatabase(String database)
{
selectedDatabase = database;

View File

@ -70,11 +70,12 @@ public class FileManager
public static BufferedImage infoSlotVic20Cover;
private static String currentDbPath = "./";
private static String currentDbName = "";
public static String GAMES = "./games/";
public static String SCREENS = "./screens/";
public static String COVERS = "./covers/";
public static String SAVES = "./saves/";
private static String BACKUP = "./backup/";
private static final String BACKUP = "./backup/";
public static String DISKS = "./extradisks/";
private static final Path TEMP_PATH = Paths.get("./temp");
@ -131,18 +132,35 @@ public class FileManager
{
dbconnector = ref;
}
public static void setCurrentDbFolder(String dbFolder)
{
currentDbName = dbFolder;
currentDbPath = "./databases/" + dbFolder + "/";
GAMES = currentDbPath + "games/";
SCREENS = currentDbPath + "screens/";
COVERS = currentDbPath + "covers/";
SAVES = currentDbPath + "saves/";
BACKUP = currentDbPath + "backup/";
DISKS = currentDbPath + "extradisks/";
}
public static void createNewDb(String name) throws IOException
{
setCurrentDbFolder(name);
Files.createDirectories(Paths.get(GAMES));
Files.createDirectories(Paths.get(SCREENS));
Files.createDirectories(Paths.get(COVERS));
Files.createDirectories(Paths.get(SAVES));
Files.createDirectories(Paths.get(DISKS));
dbconnector.setCurrentDbFolder(name);
dbconnector.createDbIfMissing(name);
}
public static String getCurrentDbName()
{
return currentDbName;
}
public static InputStream getMissingC64GameFile() throws URISyntaxException
{
return FileManager.class.getResourceAsStream("/se/lantz/MissingGame-C64.vsf.gz");
@ -727,7 +745,7 @@ public class FileManager
}
else if (duplicateIndex > 9)
{
newNameString = newNameString + "-" + duplicateIndex;
newNameString = newNameString + "-" + duplicateIndex;
}
logger.debug("Game title: \"{}\" ---- New fileName: \"{}\"", title, newNameString);
@ -970,9 +988,8 @@ public class FileManager
}
else
{
gamePathString = SAVES +
SavedStatesManager.getGameFolderName(infoModel.getGamesFile(), infoModel.getTitle()) + "/" +
savedStatesModel.getState1File();
gamePathString = SAVES + SavedStatesManager.getGameFolderName(infoModel.getGamesFile(), infoModel.getTitle()) +
"/" + savedStatesModel.getState1File();
}
}
break;
@ -985,9 +1002,8 @@ public class FileManager
}
else
{
gamePathString = SAVES +
SavedStatesManager.getGameFolderName(infoModel.getGamesFile(), infoModel.getTitle()) + "/" +
savedStatesModel.getState2File();
gamePathString = SAVES + SavedStatesManager.getGameFolderName(infoModel.getGamesFile(), infoModel.getTitle()) +
"/" + savedStatesModel.getState2File();
}
break;
case Save2:
@ -999,9 +1015,8 @@ public class FileManager
}
else
{
gamePathString = SAVES +
SavedStatesManager.getGameFolderName(infoModel.getGamesFile(), infoModel.getTitle()) + "/" +
savedStatesModel.getState3File();
gamePathString = SAVES + SavedStatesManager.getGameFolderName(infoModel.getGamesFile(), infoModel.getTitle()) +
"/" + savedStatesModel.getState3File();
}
break;
case Save3:
@ -1013,9 +1028,8 @@ public class FileManager
}
else
{
gamePathString = SAVES +
SavedStatesManager.getGameFolderName(infoModel.getGamesFile(), infoModel.getTitle()) + "/" +
savedStatesModel.getState4File();
gamePathString = SAVES + SavedStatesManager.getGameFolderName(infoModel.getGamesFile(), infoModel.getTitle()) +
"/" + savedStatesModel.getState4File();
}
break;
default:
@ -1381,24 +1395,30 @@ public class FileManager
}
return Boolean.parseBoolean(cropScreenshots);
}
public static boolean isShowCropDialogForCover()
{
if (showCropDialogForCover.isEmpty())
{
showCropDialogForCover = FileManager.getConfiguredProperties().getProperty(PreferencesModel.SHOW_CROP_DIALOG_FOR_COVER, "true");
showCropDialogForCover =
FileManager.getConfiguredProperties().getProperty(PreferencesModel.SHOW_CROP_DIALOG_FOR_COVER, "true");
}
return Boolean.parseBoolean(showCropDialogForCover);
}
private static String getBackupFolderName(String targetFolderName)
{
return BACKUP + "/" + targetFolderName + "/";
}
public static void backupDb(String targetFolderName)
{
File outputFolder = new File(BACKUP + "/" + targetFolderName + "/");
File outputFolder = new File(getBackupFolderName(targetFolderName));
try
{
File dbFile = new File("./" + DbConnector.DB_FILE);
File dbFile = new File(DbConnector.DB_FILE);
Files.createDirectories(outputFolder.toPath());
Path targetFile = outputFolder.toPath().resolve(DbConnector.DB_FILE);
Path targetFile = outputFolder.toPath().resolve(DbConnector.DB_FILE_NAME);
Files.copy(dbFile.toPath(), targetFile);
}
catch (IOException e)
@ -1409,7 +1429,7 @@ public class FileManager
public static void backupScreens(String targetFolderName)
{
File outputFolder = new File(BACKUP + "/" + targetFolderName + "/");
File outputFolder = new File(getBackupFolderName(targetFolderName));
try
{
Files.createDirectories(outputFolder.toPath());
@ -1424,7 +1444,7 @@ public class FileManager
public static void backupCovers(String targetFolderName)
{
File outputFolder = new File(BACKUP + "/" + targetFolderName + "/");
File outputFolder = new File(getBackupFolderName(targetFolderName));
try
{
Files.createDirectories(outputFolder.toPath());
@ -1439,7 +1459,7 @@ public class FileManager
public static void backupGames(String targetFolderName)
{
File outputFolder = new File(BACKUP + "/" + targetFolderName + "/");
File outputFolder = new File(getBackupFolderName(targetFolderName));
try
{
Files.createDirectories(outputFolder.toPath());
@ -1454,7 +1474,7 @@ public class FileManager
public static void backupExtraDisks(String targetFolderName)
{
File outputFolder = new File(BACKUP + "/" + targetFolderName + "/");
File outputFolder = new File(getBackupFolderName(targetFolderName));
try
{
Files.createDirectories(outputFolder.toPath());
@ -1469,7 +1489,7 @@ public class FileManager
public static void backupSaves(String targetFolderName)
{
File outputFolder = new File(BACKUP + "/" + targetFolderName + "/");
File outputFolder = new File(getBackupFolderName(targetFolderName));
try
{
Files.createDirectories(outputFolder.toPath());
@ -1583,10 +1603,10 @@ public class FileManager
public static void restoreDb(String backupFolderName)
{
File backupFolder = new File(BACKUP + "/" + backupFolderName + "/");
File backupFolder = new File(getBackupFolderName(backupFolderName));
try
{
Path backupFile = backupFolder.toPath().resolve(DbConnector.DB_FILE);
Path backupFile = backupFolder.toPath().resolve(DbConnector.DB_FILE_NAME);
Path dbFile = new File("./" + DbConnector.DB_FILE).toPath();
Files.copy(backupFile, dbFile, StandardCopyOption.REPLACE_EXISTING);
}
@ -1598,7 +1618,7 @@ public class FileManager
public static void restoreCovers(String backupFolderName)
{
File backupFolder = new File(BACKUP + "/" + backupFolderName + "/");
File backupFolder = new File(getBackupFolderName(backupFolderName));
try
{
File coversDir = new File(COVERS);
@ -1613,7 +1633,7 @@ public class FileManager
public static void restoreScreens(String backupFolderName)
{
File backupFolder = new File(BACKUP + "/" + backupFolderName + "/");
File backupFolder = new File(getBackupFolderName(backupFolderName));
try
{
File screensDir = new File(SCREENS);
@ -1628,7 +1648,7 @@ public class FileManager
public static void restoreGames(String backupFolderName)
{
File backupFolder = new File(BACKUP + "/" + backupFolderName + "/");
File backupFolder = new File(getBackupFolderName(backupFolderName));
try
{
File gamesDir = new File(GAMES);
@ -1643,7 +1663,7 @@ public class FileManager
public static void restoreExtraDisks(String backupFolderName)
{
File backupFolder = new File(BACKUP + "/" + backupFolderName + "/");
File backupFolder = new File(getBackupFolderName(backupFolderName));
try
{
File extradisksDir = new File(DISKS);
@ -1662,7 +1682,7 @@ public class FileManager
public static void restoreSaves(String backupFolderName)
{
File backupFolder = new File(BACKUP + "/" + backupFolderName + "/");
File backupFolder = new File(getBackupFolderName(backupFolderName));
try
{
File savesDir = new File(SAVES);