feat: wip of multiple db support

This commit is contained in:
lantzelot-swe 2024-05-16 22:42:57 +02:00
parent 1690fa3c55
commit 812a3b16f2
9 changed files with 487 additions and 65 deletions

View File

@ -69,8 +69,8 @@ public class PCUAEManager
int width = gd.getDisplayMode().getWidth(); int width = gd.getDisplayMode().getWidth();
int height = gd.getDisplayMode().getHeight(); int height = gd.getDisplayMode().getHeight();
mainWindow.setSize(Math.min(width, 1500), Math.min(height - 40, 825)); mainWindow.setSize(Math.min(width, 1500), Math.min(height - 40, 850));
mainWindow.setMinimumSize(new Dimension(Math.min(width, 1300), Math.min(height - 40, 700))); mainWindow.setMinimumSize(new Dimension(Math.min(width, 1300), Math.min(height - 40, 725)));
mainWindow.setLocationRelativeTo(null); mainWindow.setLocationRelativeTo(null);
mainWindow.initialize(); mainWindow.initialize();
mainWindow.setVisible(true); mainWindow.setVisible(true);

View File

@ -33,7 +33,7 @@ import se.lantz.util.GameListDataComparator;
public class DbConnector public class DbConnector
{ {
public static final String DB_NAME = "pcusb.db"; public static String DB_FILE = "";
private static final String COMMA = "\",\""; private static final String COMMA = "\",\"";
// @J- // @J-
private static final String GAMEINFO_SQL = private static final String GAMEINFO_SQL =
@ -78,7 +78,7 @@ public class DbConnector
Map<String, Integer> duplicateMap = new HashMap<>(); Map<String, Integer> duplicateMap = new HashMap<>();
List<String> addedRowsList = new ArrayList<>(); List<String> addedRowsList = new ArrayList<>();
public DbConnector() public DbConnector(List<String> dbFolders)
{ {
columnList.add(DbConstants.TITLE); columnList.add(DbConstants.TITLE);
columnList.add(DbConstants.YEAR); columnList.add(DbConstants.YEAR);
@ -105,18 +105,28 @@ public class DbConnector
columnList.add(DbConstants.DISK_4); columnList.add(DbConstants.DISK_4);
columnList.add(DbConstants.DISK_5); columnList.add(DbConstants.DISK_5);
columnList.add(DbConstants.DISK_6); columnList.add(DbConstants.DISK_6);
//Check if database file exists, if not create an empty db.
File dbFile = new File("./" + DB_NAME); 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()) if (!dbFile.exists())
{ {
createNewDb(); createNewDb();
logger.debug("Database missing, new db created."); logger.debug("Database {} missing, new db created.", dbFolder);
} }
//To be backwards compatible with 1.0 db, update if missing //To be backwards compatible with 1.0 db, update if missing
addLanguageAndDuplicateColumnsIfMissing(); addLanguageAndDuplicateColumnsIfMissing();
//To be backwards compatible with 2.8.2 db, update if missing //To be backwards compatible with 2.8.2 db, update if missing
addDiskColumnsIfMissing(); addDiskColumnsIfMissing();
} }
}
public static void setCurrentDbFolder(String dbFolder)
{
DB_FILE = "./databases/" + dbFolder + "/pcusb.db";
}
private void createNewDb() private void createNewDb()
{ {
@ -294,7 +304,7 @@ public class DbConnector
try try
{ {
// db parameters // db parameters
String url = "jdbc:sqlite:" + DB_NAME; String url = "jdbc:sqlite:" + DB_FILE;
// create a connection to the database // create a connection to the database
connection = DriverManager.getConnection(url); connection = DriverManager.getConnection(url);

View File

@ -0,0 +1,254 @@
package se.lantz.gui;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
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
{
private boolean dragging = false;
private Image tabImage = null;
private Point currentMouseLocation = null;
private int draggedTabIndex = 0;
private Rectangle draggedTabBounds = null;
private int previouslySelectedIndex;
private ActionListener draggedTabListener = null;
private ActionListener tabStructureChangedListener = null;
public DraggableTabbedPane()
{
super();
addMouseMotionListener(new MouseMotionAdapter()
{
public void mouseDragged(MouseEvent e)
{
if (!dragging)
{
// Gets the tab index based on the mouse position
int tabNumber = getUI().tabForCoordinate(DraggableTabbedPane.this, e.getX(), e.getY());
if (tabNumber >= 0 && tabNumber < (getTabCount() - 1))
{
draggedTabIndex = tabNumber;
Rectangle bounds = getUI().getTabBounds(DraggableTabbedPane.this, tabNumber);
draggedTabBounds = bounds;
// Paint the tabbed pane to a buffer
Image totalImage = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics totalGraphics = totalImage.getGraphics();
totalGraphics.setClip(bounds);
// Don't be double buffered when painting to a static image.
setDoubleBuffered(false);
paintComponent(totalGraphics);
// Paint just the dragged tab to the buffer
tabImage = new BufferedImage(bounds.width, bounds.height, BufferedImage.TYPE_INT_ARGB);
Graphics graphics = tabImage.getGraphics();
graphics.drawImage(totalImage,
0,
0,
bounds.width,
bounds.height,
bounds.x,
bounds.y,
bounds.x + bounds.width,
bounds.y + bounds.height,
DraggableTabbedPane.this);
dragging = true;
repaint();
}
}
else
{
currentMouseLocation = e.getPoint();
// Need to repaint
repaint();
}
super.mouseDragged(e);
}
});
addMouseListener(new MouseAdapter()
{
@Override
public void mouseReleased(MouseEvent e)
{
if (dragging)
{
int tabNumber = -1;
Rectangle lastTabBounds = getUI().getTabBounds(DraggableTabbedPane.this, getTabCount() - 2);
int draggedTabXposToCheck = e.getX() + draggedTabBounds.width / 2;
//Dragging left of first tab always puts the tab first
if (e.getX() <= 0)
{
tabNumber = 0;
}
//Dragging right of next-to-last tab always puts the tab last
else if (lastTabBounds.x + lastTabBounds.width / 2 < draggedTabXposToCheck)
{
//Add in last position (before "+")
tabNumber = getTabCount() - 2;
}
else
{
tabNumber = getUI().tabForCoordinate(DraggableTabbedPane.this, draggedTabXposToCheck, 10);
Rectangle tabBounds = getUI().getTabBounds(DraggableTabbedPane.this, tabNumber);
int halfTabPosition = tabBounds.x + tabBounds.width / 2;
//Dragging right
if (e.getX() > draggedTabBounds.x)
{
if (draggedTabXposToCheck < halfTabPosition)
{
//Do not move the tab
tabNumber--;
}
}
//Dragging left
else
{
if (draggedTabXposToCheck > halfTabPosition)
{
//Do not move the tab
tabNumber++;
}
}
}
if (tabNumber == draggedTabIndex)
{
//Do nothing
}
else if (tabNumber >= 0 && tabNumber < (getTabCount() - 1))
{
Component comp = getComponentAt(draggedTabIndex);
String title = getTitleAt(draggedTabIndex);
removeTabAt(draggedTabIndex);
insertTab(title, null, comp, null, tabNumber);
notifyTabDraggedListener(tabNumber);
notifyTabStructureChangedListener();
setSelectedIndex(tabNumber);
}
}
dragging = false;
tabImage = null;
// 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());
}
}
}
});
}
public void addTabDraggedListener(ActionListener listener)
{
draggedTabListener = listener;
}
public void addTabStructureChangedListener(ActionListener listener)
{
tabStructureChangedListener = listener;
}
private void notifyTabDraggedListener(int tabNumber)
{
if (draggedTabListener != null)
{
draggedTabListener.actionPerformed(new ActionEvent(this, tabNumber, "inserted"));
}
}
private void notifyTabStructureChangedListener()
{
if (tabStructureChangedListener != null)
{
tabStructureChangedListener.actionPerformed(new ActionEvent(this, 0, "structure changed"));
}
}
public boolean isDragging()
{
return dragging;
}
public int getPreviouslySelectedIndex()
{
return previouslySelectedIndex;
}
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
// Are we dragging?
if (dragging && currentMouseLocation != null && tabImage != null)
{
// Draw the dragged tab
g.drawImage(tabImage, currentMouseLocation.x, 0, this);//currentMouseLocation.y, this);
}
}
public static void main(String[] args)
{
JFrame test = new JFrame("Tab test");
test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
test.setSize(800, 800);
DraggableTabbedPane tabs = new DraggableTabbedPane();
tabs.addTab("One", new JButton("One"));
tabs.addTab("Two", new JButton("Two"));
tabs.addTab("Three", new JButton("Three"));
tabs.addTab("+", new JButton("+"));
test.add(tabs);
test.setVisible(true);
}
}

View File

@ -1,17 +1,13 @@
package se.lantz.gui; package se.lantz.gui;
import java.awt.BorderLayout; import java.awt.BorderLayout;
import java.awt.event.InputEvent; import java.util.ArrayList;
import java.awt.event.KeyEvent;
import java.util.List; import java.util.List;
import javax.swing.InputMap;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JSplitPane; import javax.swing.JSplitPane;
import javax.swing.KeyStroke;
import javax.swing.ToolTipManager;
import se.lantz.model.MainViewModel; import se.lantz.model.MainViewModel;
import se.lantz.model.data.GameListData; import se.lantz.model.data.GameListData;
@ -20,21 +16,94 @@ public class MainPanel extends JPanel
{ {
private JSplitPane splitPane; private JSplitPane splitPane;
private ListPanel listPanel; private ListPanel listPanel;
private DraggableTabbedPane tabbedPane;
private GameDetailsBackgroundPanel gameDetailsBackgroundPanel; private GameDetailsBackgroundPanel gameDetailsBackgroundPanel;
private final MainViewModel uiModel; private final MainViewModel uiModel;
private int previouslySelectedIndex = 0;
private boolean ignoreTabChange = false;
public MainPanel(final MainViewModel uiModel) public MainPanel(final MainViewModel uiModel)
{ {
this.uiModel = uiModel; this.uiModel = uiModel;
setLayout(new BorderLayout(0, 0)); setLayout(new BorderLayout(0, 0));
add(getSplitPane(), BorderLayout.CENTER); add(getTabbedPane(), BorderLayout.CENTER);
uiModel.addSaveChangeListener(e -> { uiModel.addSaveChangeListener(e -> {
listPanel.checkSaveChangeStatus(); listPanel.checkSaveChangeStatus();
}); });
uiModel.addRequireFieldsListener(e -> showRequiredFieldsDialog((List<String>) e.getNewValue())); uiModel.addRequiredFieldsListener(e -> showRequiredFieldsDialog((List<String>) e.getNewValue()));
}
private DraggableTabbedPane getTabbedPane()
{
if (tabbedPane == null)
{
tabbedPane = new DraggableTabbedPane();
for (int i = 0; i < uiModel.getAvailableDatabases().size(); i++)
{
if (i == 0)
{
tabbedPane.addTab(uiModel.getAvailableDatabases().get(i), getNewContentPanel(getSplitPane()));
}
else
{
tabbedPane.addTab(uiModel.getAvailableDatabases().get(i), getNewContentPanel(null));
}
}
tabbedPane.addTab(" + ", getNewContentPanel(null));
//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)
tabbedPane.addTabStructureChangedListener(e -> updateTabOrderPreferences());
tabbedPane.addChangeListener(e -> {
if (!tabbedPane.isDragging())
{
if (tabbedPane.getSelectedIndex() == uiModel.getAvailableDatabases().size())
{
ignoreTabChange = true;
tabbedPane.setSelectedIndex(previouslySelectedIndex);
ignoreTabChange = false;
String name = JOptionPane.showInputDialog(this, "Write a new name!");
//Create a new empty one!
return;
}
else if (ignoreTabChange)
{
//Do nothing
return;
}
MainWindow.getInstance().setWaitCursor(true);
int selectedIndex = tabbedPane.getSelectedIndex();
((JPanel) tabbedPane.getComponentAt(previouslySelectedIndex)).removeAll();
((JPanel) tabbedPane.getComponentAt(selectedIndex)).add(getSplitPane(), BorderLayout.CENTER);
previouslySelectedIndex = tabbedPane.getSelectedIndex();
uiModel.setCurrentDatabase(tabbedPane.getTitleAt(selectedIndex));
MainWindow.getInstance().setWaitCursor(false);
invalidate();
repaint();
}
});
}
return tabbedPane;
}
private void updateTabOrderPreferences()
{
List<String> tabTitles = new ArrayList<>();
for (int i = 0; i < tabbedPane.getTabCount() - 1; i++)
{
tabTitles.add(tabbedPane.getTitleAt(i));
}
uiModel.updateDbTabPreferences(String.join(",", tabTitles));
} }
private JSplitPane getSplitPane() private JSplitPane getSplitPane()
@ -49,6 +118,16 @@ public class MainPanel extends JPanel
return splitPane; return splitPane;
} }
private JPanel getNewContentPanel(JComponent content)
{
JPanel panel = new JPanel(new BorderLayout());
if (content != null)
{
panel.add(content, BorderLayout.CENTER);
}
return panel;
}
public ListPanel getListPanel() public ListPanel getListPanel()
{ {
if (listPanel == null) if (listPanel == null)

View File

@ -314,7 +314,7 @@ public class SaveStatePanel extends JPanel
String fileName = SavedStatesManager.getGameFolderName(model.getInfoModel().getGamesFile(), model.getInfoModel().getTitle()); String fileName = SavedStatesManager.getGameFolderName(model.getInfoModel().getGamesFile(), model.getInfoModel().getTitle());
logger.debug(fileName.toString()); logger.debug(fileName.toString());
Path saveFolderPath = new File("./saves/" + fileName).toPath(); Path saveFolderPath = new File(FileManager.SAVES + fileName).toPath();
File imagefile = saveFolderPath.resolve(filename).toFile(); File imagefile = saveFolderPath.resolve(filename).toFile();
try try
{ {

View File

@ -273,7 +273,7 @@ public class ScreenshotsPanel extends JPanel
{ {
if (!filename.isEmpty()) if (!filename.isEmpty())
{ {
File imagefile = new File("./covers/" + filename); File imagefile = new File(FileManager.COVERS + filename);
try try
{ {
BufferedImage image = ImageIO.read(imagefile); BufferedImage image = ImageIO.read(imagefile);
@ -297,7 +297,7 @@ public class ScreenshotsPanel extends JPanel
BufferedImage image = null; BufferedImage image = null;
if (!filename.isEmpty()) if (!filename.isEmpty())
{ {
File imagefile = new File("./screens/" + filename); File imagefile = new File(FileManager.SCREENS + filename);
try try
{ {
image = ImageIO.read(imagefile); image = ImageIO.read(imagefile);

View File

@ -42,8 +42,6 @@ public class SavedStatesManager
{ {
private static final Logger logger = LoggerFactory.getLogger(SavedStatesManager.class); private static final Logger logger = LoggerFactory.getLogger(SavedStatesManager.class);
public static final String SAVES = "./saves/";
private static final String MTA0 = "0.mta"; private static final String MTA0 = "0.mta";
private static final String MTA1 = "1.mta"; private static final String MTA1 = "1.mta";
private static final String MTA2 = "2.mta"; private static final String MTA2 = "2.mta";
@ -111,18 +109,18 @@ public class SavedStatesManager
//If the game has been renamed, make sure to rename the saves folder also //If the game has been renamed, make sure to rename the saves folder also
String oldFileName = model.getInfoModel().getOldGamesFile(); String oldFileName = model.getInfoModel().getOldGamesFile();
String newFileName = model.getInfoModel().getGamesFile(); String newFileName = model.getInfoModel().getGamesFile();
File oldSaveFolder = new File(SAVES + getGameFolderName(oldFileName, model.getInfoModel().getTitle())); File oldSaveFolder = new File(FileManager.SAVES + getGameFolderName(oldFileName, model.getInfoModel().getTitle()));
if (!oldFileName.equals(newFileName) && oldSaveFolder.exists()) if (!oldFileName.equals(newFileName) && oldSaveFolder.exists())
{ {
//Rename old folder to new name //Rename old folder to new name
oldSaveFolder.renameTo(new File(SAVES + oldSaveFolder.renameTo(new File(FileManager.SAVES +
getGameFolderName(model.getInfoModel().getGamesFile(), model.getInfoModel().getTitle()))); getGameFolderName(model.getInfoModel().getGamesFile(), model.getInfoModel().getTitle())));
} }
String fileName = model.getInfoModel().getGamesFile(); String fileName = model.getInfoModel().getGamesFile();
String gameFolderName = getGameFolderName(fileName, model.getInfoModel().getTitle()); String gameFolderName = getGameFolderName(fileName, model.getInfoModel().getTitle());
Path saveFolder = new File(SAVES + gameFolderName).toPath(); Path saveFolder = new File(FileManager.SAVES + gameFolderName).toPath();
int numberofSaves = 0; int numberofSaves = 0;
//Check which ones are available //Check which ones are available
Path mta0Path = saveFolder.resolve(MTA0); Path mta0Path = saveFolder.resolve(MTA0);
@ -178,7 +176,7 @@ public class SavedStatesManager
{ {
fileName = fileName.trim(); fileName = fileName.trim();
//Check if folder is available //Check if folder is available
Path saveFolder = new File(SAVES + fileName).toPath(); Path saveFolder = new File(FileManager.SAVES + fileName).toPath();
if (Files.exists(saveFolder)) if (Files.exists(saveFolder))
{ {
//Check which ones are available //Check which ones are available
@ -349,7 +347,7 @@ public class SavedStatesManager
private void deleteSavedState(SAVESTATE state) private void deleteSavedState(SAVESTATE state)
{ {
String fileName = getGameFolderName(model.getInfoModel().getGamesFile(), model.getInfoModel().getTitle()); String fileName = getGameFolderName(model.getInfoModel().getGamesFile(), model.getInfoModel().getTitle());
Path saveFolder = new File(SAVES + fileName).toPath(); Path saveFolder = new File(FileManager.SAVES + fileName).toPath();
try try
{ {
switch (state) switch (state)
@ -399,7 +397,7 @@ public class SavedStatesManager
public void exportSavedStates(PublishWorker worker) public void exportSavedStates(PublishWorker worker)
{ {
noFilesCopied = 0; noFilesCopied = 0;
File saveFolder = new File(SAVES); File saveFolder = new File(FileManager.SAVES);
try (Stream<Path> stream = Files.walk(saveFolder.toPath().toAbsolutePath())) try (Stream<Path> stream = Files.walk(saveFolder.toPath().toAbsolutePath()))
{ {
stream.forEachOrdered(sourcePath -> { stream.forEachOrdered(sourcePath -> {
@ -452,7 +450,7 @@ public class SavedStatesManager
public void importSavedStates(PublishWorker worker) public void importSavedStates(PublishWorker worker)
{ {
noFilesCopied = 0; noFilesCopied = 0;
File saveFolder = new File(SAVES); File saveFolder = new File(FileManager.SAVES);
try (Stream<Path> stream = Files.walk(importDir.toPath().toAbsolutePath())) try (Stream<Path> stream = Files.walk(importDir.toPath().toAbsolutePath()))
{ {
stream.forEachOrdered(sourcePath -> { stream.forEachOrdered(sourcePath -> {
@ -568,7 +566,7 @@ public class SavedStatesManager
{ {
savedStatesMap.clear(); savedStatesMap.clear();
//Read all files in the saves folder //Read all files in the saves folder
File saveFolder = new File(SAVES); File saveFolder = new File(FileManager.SAVES);
try (Stream<Path> stream = Files.walk(saveFolder.toPath().toAbsolutePath(), 1)) try (Stream<Path> stream = Files.walk(saveFolder.toPath().toAbsolutePath(), 1))
{ {
stream.forEachOrdered(sourcePath -> { stream.forEachOrdered(sourcePath -> {
@ -634,7 +632,7 @@ public class SavedStatesManager
if (!fileName.isEmpty() && fileName.contains(".vsf")) if (!fileName.isEmpty() && fileName.contains(".vsf"))
{ {
//Check if folder is available //Check if folder is available
Path saveFolder = new File(SAVES + getGameFolderName(fileName, model.getInfoModel().getTitle())).toPath(); Path saveFolder = new File(FileManager.SAVES + getGameFolderName(fileName, model.getInfoModel().getTitle())).toPath();
if (Files.exists(saveFolder)) if (Files.exists(saveFolder))
{ {
//Check which ones are available //Check which ones are available
@ -654,7 +652,7 @@ public class SavedStatesManager
String gamesFile = model.getInfoModel().getGamesFile(); String gamesFile = model.getInfoModel().getGamesFile();
Path gameFilePath = new File(FileManager.GAMES + gamesFile).toPath(); Path gameFilePath = new File(FileManager.GAMES + gamesFile).toPath();
Path firstSavedStatePath = Path firstSavedStatePath =
new File(SAVES + getGameFolderName(gamesFile, model.getInfoModel().getTitle())).toPath().resolve(VSZ0); new File(FileManager.SAVES + getGameFolderName(gamesFile, model.getInfoModel().getTitle())).toPath().resolve(VSZ0);
Path tempFilePath = new File(FileManager.GAMES + "temp.gz").toPath(); Path tempFilePath = new File(FileManager.GAMES + "temp.gz").toPath();
try try
@ -709,7 +707,7 @@ public class SavedStatesManager
public void convertToCarousel152Version() public void convertToCarousel152Version()
{ {
File saveFolder = new File(SAVES); File saveFolder = new File(FileManager.SAVES);
try (Stream<Path> stream = Files.walk(saveFolder.toPath().toAbsolutePath(), 1)) try (Stream<Path> stream = Files.walk(saveFolder.toPath().toAbsolutePath(), 1))
{ {
stream.forEachOrdered(sourcePath -> { stream.forEachOrdered(sourcePath -> {
@ -798,7 +796,7 @@ public class SavedStatesManager
{ {
//1. look through all folders and try to find a game in the db that matches the file name. //1. look through all folders and try to find a game in the db that matches the file name.
//2. for all that matches, get the title and copy the existing folder to a folder named as the title //2. for all that matches, get the title and copy the existing folder to a folder named as the title
File saveFolder = new File(SAVES); File saveFolder = new File(FileManager.SAVES);
try (Stream<Path> stream = Files.walk(saveFolder.toPath().toAbsolutePath(), 1)) try (Stream<Path> stream = Files.walk(saveFolder.toPath().toAbsolutePath(), 1))
{ {
List<GameValidationDetails> allGamesDetailsList = this.model.getDbConnector().fetchAllGamesForDbValdation(); List<GameValidationDetails> allGamesDetailsList = this.model.getDbConnector().fetchAllGamesForDbValdation();
@ -872,7 +870,7 @@ public class SavedStatesManager
public int checkFor132SavedStates() public int checkFor132SavedStates()
{ {
File saveFolder = new File(SAVES); File saveFolder = new File(FileManager.SAVES);
long returnValue = 0; long returnValue = 0;
try (Stream<Path> stream = Files.walk(saveFolder.toPath().toAbsolutePath(), 1)) try (Stream<Path> stream = Files.walk(saveFolder.toPath().toAbsolutePath(), 1))
{ {
@ -902,7 +900,7 @@ public class SavedStatesManager
{ {
//1. look through all folders and try to find a game in the db that matches the file name. //1. look through all folders and try to find a game in the db that matches the file name.
//2. for all that matches, get the title and check so that no folder exists already //2. for all that matches, get the title and check so that no folder exists already
File saveFolder = new File(SAVES); File saveFolder = new File(FileManager.SAVES);
try (Stream<Path> stream = Files.walk(saveFolder.toPath().toAbsolutePath(), 1)) try (Stream<Path> stream = Files.walk(saveFolder.toPath().toAbsolutePath(), 1))
{ {
List<GameValidationDetails> allGamesDetailsList = this.model.getDbConnector().fetchAllGamesForDbValdation(); List<GameValidationDetails> allGamesDetailsList = this.model.getDbConnector().fetchAllGamesForDbValdation();

View File

@ -8,10 +8,18 @@ import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Properties;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.swing.DefaultComboBoxModel; import javax.swing.DefaultComboBoxModel;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
@ -28,11 +36,14 @@ import se.lantz.model.data.GameListData;
import se.lantz.model.data.GameView; import se.lantz.model.data.GameView;
import se.lantz.scraper.MobyGamesScraper; import se.lantz.scraper.MobyGamesScraper;
import se.lantz.scraper.Scraper; import se.lantz.scraper.Scraper;
import se.lantz.util.ExceptionHandler;
import se.lantz.util.FileManager; import se.lantz.util.FileManager;
import se.lantz.util.TextComponentSupport; import se.lantz.util.TextComponentSupport;
public class MainViewModel extends AbstractModel public class MainViewModel extends AbstractModel
{ {
public static final String DB_TAB_ORDER = "dbTabOrder";
private static final Logger logger = LoggerFactory.getLogger(MainViewModel.class); private static final Logger logger = LoggerFactory.getLogger(MainViewModel.class);
DbConnector dbConnector; DbConnector dbConnector;
@ -85,6 +96,47 @@ public class MainViewModel extends AbstractModel
private boolean notifyGameListChange = true; private boolean notifyGameListChange = true;
private boolean notifyGameSelected = true; private boolean notifyGameSelected = true;
private List<String> availableDatabases = new ArrayList<>();
private String selectedDatabase = "Main";
public MainViewModel()
{
//Read available databases and preferences for them
try (Stream<Path> stream = Files.list(Paths.get("./databases")))
{
availableDatabases = stream.filter(file -> Files.isDirectory(file)).map(Path::getFileName).map(Path::toString)
.collect(Collectors.toList());
}
catch (IOException ex)
{
ExceptionHandler.handleException(ex, "Could not read databases");
}
if (availableDatabases.size() > 0)
{
//Read preferences for tab order
Properties configuredProperties = FileManager.getConfiguredProperties();
String tabOrder = (String) configuredProperties.get(DB_TAB_ORDER);
if (tabOrder != null)
{
List<String> preferencesOrder = Arrays.asList(tabOrder.split("\\s*,\\s*"));
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 setSavedStatesManager(SavedStatesManager savedStatesManager) public void setSavedStatesManager(SavedStatesManager savedStatesManager)
{ {
this.stateManager = savedStatesManager; this.stateManager = savedStatesManager;
@ -98,7 +150,9 @@ public class MainViewModel extends AbstractModel
public void initialize() public void initialize()
{ {
logger.debug("Creating DBConnector..."); logger.debug("Creating DBConnector...");
dbConnector = new DbConnector(); //Pass the selected db here
dbConnector = new DbConnector(availableDatabases);
DbConnector.setCurrentDbFolder(selectedDatabase);
logger.debug("...done."); logger.debug("...done.");
setupGameViews(); setupGameViews();
@ -635,7 +689,7 @@ public class MainViewModel extends AbstractModel
getSavedStatesModel().addPropertyChangeListener(saveChangeListener); getSavedStatesModel().addPropertyChangeListener(saveChangeListener);
} }
public void addRequireFieldsListener(PropertyChangeListener requiredFieldsListener) public void addRequiredFieldsListener(PropertyChangeListener requiredFieldsListener)
{ {
this.requiredFieldsListener = requiredFieldsListener; this.requiredFieldsListener = requiredFieldsListener;
} }
@ -1275,4 +1329,19 @@ public class MainViewModel extends AbstractModel
{ {
return this.currentGameDetails; return this.currentGameDetails;
} }
public List<String> getAvailableDatabases()
{
return availableDatabases;
}
public void setCurrentDatabase(String database)
{
selectedDatabase = database;
//Update all
FileManager.setCurrentDbFolder(selectedDatabase);
DbConnector.setCurrentDbFolder(selectedDatabase);
stateManager.readSavedStatesAndUpdateMap();
reloadGameViews();
}
} }

View File

@ -69,12 +69,13 @@ public class FileManager
public static BufferedImage infoSlotC64Cover; public static BufferedImage infoSlotC64Cover;
public static BufferedImage infoSlotVic20Cover; public static BufferedImage infoSlotVic20Cover;
public static final String GAMES = "./games/"; private static String currentDbPath = "./";
private static final String SCREENS = "./screens/"; public static String GAMES = "./games/";
private static final String COVERS = "./covers/"; public static String SCREENS = "./screens/";
private static final String SAVES = "./saves/"; public static String COVERS = "./covers/";
private static final String BACKUP = "./backup/"; public static String SAVES = "./saves/";
public static final String DISKS = "./extradisks/"; private static String BACKUP = "./backup/";
public static String DISKS = "./extradisks/";
private static final Path TEMP_PATH = Paths.get("./temp"); private static final Path TEMP_PATH = Paths.get("./temp");
private static final Logger logger = LoggerFactory.getLogger(FileManager.class); private static final Logger logger = LoggerFactory.getLogger(FileManager.class);
@ -131,6 +132,17 @@ public class FileManager
dbconnector = ref; dbconnector = ref;
} }
public static void setCurrentDbFolder(String dbFolder)
{
currentDbPath = "./databases/" + dbFolder + "/";
GAMES = currentDbPath + "games/";
SCREENS = currentDbPath + "screens/";
COVERS = currentDbPath + "covers/";
SAVES = currentDbPath + "saves/";
BACKUP = currentDbPath + "backup/";
DISKS = currentDbPath + "extradisks/";
}
public static InputStream getMissingC64GameFile() throws URISyntaxException public static InputStream getMissingC64GameFile() throws URISyntaxException
{ {
return FileManager.class.getResourceAsStream("/se/lantz/MissingGame-C64.vsf.gz"); return FileManager.class.getResourceAsStream("/se/lantz/MissingGame-C64.vsf.gz");
@ -958,7 +970,7 @@ public class FileManager
} }
else else
{ {
gamePathString = SavedStatesManager.SAVES + gamePathString = SAVES +
SavedStatesManager.getGameFolderName(infoModel.getGamesFile(), infoModel.getTitle()) + "/" + SavedStatesManager.getGameFolderName(infoModel.getGamesFile(), infoModel.getTitle()) + "/" +
savedStatesModel.getState1File(); savedStatesModel.getState1File();
} }
@ -973,7 +985,7 @@ public class FileManager
} }
else else
{ {
gamePathString = SavedStatesManager.SAVES + gamePathString = SAVES +
SavedStatesManager.getGameFolderName(infoModel.getGamesFile(), infoModel.getTitle()) + "/" + SavedStatesManager.getGameFolderName(infoModel.getGamesFile(), infoModel.getTitle()) + "/" +
savedStatesModel.getState2File(); savedStatesModel.getState2File();
} }
@ -987,7 +999,7 @@ public class FileManager
} }
else else
{ {
gamePathString = SavedStatesManager.SAVES + gamePathString = SAVES +
SavedStatesManager.getGameFolderName(infoModel.getGamesFile(), infoModel.getTitle()) + "/" + SavedStatesManager.getGameFolderName(infoModel.getGamesFile(), infoModel.getTitle()) + "/" +
savedStatesModel.getState3File(); savedStatesModel.getState3File();
} }
@ -1001,7 +1013,7 @@ public class FileManager
} }
else else
{ {
gamePathString = SavedStatesManager.SAVES + gamePathString = SAVES +
SavedStatesManager.getGameFolderName(infoModel.getGamesFile(), infoModel.getTitle()) + "/" + SavedStatesManager.getGameFolderName(infoModel.getGamesFile(), infoModel.getTitle()) + "/" +
savedStatesModel.getState4File(); savedStatesModel.getState4File();
} }
@ -1384,9 +1396,9 @@ public class FileManager
File outputFolder = new File(BACKUP + "/" + targetFolderName + "/"); File outputFolder = new File(BACKUP + "/" + targetFolderName + "/");
try try
{ {
File dbFile = new File("./" + DbConnector.DB_NAME); File dbFile = new File("./" + DbConnector.DB_FILE);
Files.createDirectories(outputFolder.toPath()); Files.createDirectories(outputFolder.toPath());
Path targetFile = outputFolder.toPath().resolve(DbConnector.DB_NAME); Path targetFile = outputFolder.toPath().resolve(DbConnector.DB_FILE);
Files.copy(dbFile.toPath(), targetFile); Files.copy(dbFile.toPath(), targetFile);
} }
catch (IOException e) catch (IOException e)
@ -1574,8 +1586,8 @@ public class FileManager
File backupFolder = new File(BACKUP + "/" + backupFolderName + "/"); File backupFolder = new File(BACKUP + "/" + backupFolderName + "/");
try try
{ {
Path backupFile = backupFolder.toPath().resolve(DbConnector.DB_NAME); Path backupFile = backupFolder.toPath().resolve(DbConnector.DB_FILE);
Path dbFile = new File("./" + DbConnector.DB_NAME).toPath(); Path dbFile = new File("./" + DbConnector.DB_FILE).toPath();
Files.copy(backupFile, dbFile, StandardCopyOption.REPLACE_EXISTING); Files.copy(backupFile, dbFile, StandardCopyOption.REPLACE_EXISTING);
} }
catch (IOException e) catch (IOException e)