diff --git a/src/main/java/de/neemann/digital/FileLocator.java b/src/main/java/de/neemann/digital/FileLocator.java new file mode 100644 index 000000000..0a4218b4b --- /dev/null +++ b/src/main/java/de/neemann/digital/FileLocator.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2019 Helmut Neemann. + * Use of this source code is governed by the GPL v3 license + * that can be found in the LICENSE file. + */ +package de.neemann.digital; + +import de.neemann.digital.draw.library.ElementLibrary; +import de.neemann.digital.gui.FileHistory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; + +/** + * Helper to find a file if only the filename is known. + */ +public class FileLocator { + private static final Logger LOGGER = LoggerFactory.getLogger(FileLocator.class); + private static final int MAX_FILE_COUNTER = 5000; + + private final String filename; + private FileHistory history; + private ElementLibrary library; + private File baseFile; + private int fileCounter; + + /** + * Creates a new instance + * + * @param filename the file name + */ + public FileLocator(String filename) { + this.filename = filename; + } + + /** + * Sets the relevant file history + * + * @param history the file history + * @return this for chained calls + */ + public FileLocator setHistory(FileHistory history) { + this.history = history; + return this; + } + + /** + * Sets the used library. + * If called the library folder is scanned to locate the file. + * + * @param library the library + * @return this for chained calls + */ + public FileLocator setLibrary(ElementLibrary library) { + this.library = library; + return this; + } + + /** + * The base file from which the specified file name originates. + * Often the base file is a file with a different extension, + * which is located in the same directory. + * + * @param baseFile the base file + * @return this for chained calls + */ + public FileLocator setBaseFile(File baseFile) { + this.baseFile = baseFile; + return this; + } + + /** + * Tries to locate the given file. + * + * @return the file or null if not found + */ + public File locate() { + if (filename == null) + return null; + + if (baseFile != null) { + File f = new File(baseFile.getParentFile(), filename); + if (f.isFile() && f.exists()) { + LOGGER.debug(filename + " found in base file folder"); + return f; + } + } + + if (history != null) { + for (File h : history.getFiles()) { + if (h.getName().equals(filename) && h.exists()) { + LOGGER.debug(filename + " found in file history"); + return h; + } + } + } + + if (library != null) { + final File rootFilePath = library.getRootFilePath(); + if (rootFilePath != null) { + LOGGER.debug(filename + ": start library folder lookup"); + fileCounter = 0; + File f = search(rootFilePath); + if (f != null) { + LOGGER.debug(filename + " found in library folder"); + return f; + } + } + } + + LOGGER.debug(filename + " not found"); + return null; + } + + private File search(File path) { + if (fileCounter > MAX_FILE_COUNTER) + return null; + + File[] list = path.listFiles(); + if (list != null) { + for (File f : list) { + if (f.isFile() && f.getName().equals(filename)) + return f; + fileCounter++; + } + for (File f : list) { + if (f.isDirectory() && !f.getName().startsWith(".")) { + File af = search(f); + if (af != null) + return af; + } + } + } + return null; + } + +} diff --git a/src/main/java/de/neemann/digital/fsm/gui/FSMFrame.java b/src/main/java/de/neemann/digital/fsm/gui/FSMFrame.java index 8b8c6c861..3a296c459 100644 --- a/src/main/java/de/neemann/digital/fsm/gui/FSMFrame.java +++ b/src/main/java/de/neemann/digital/fsm/gui/FSMFrame.java @@ -5,6 +5,7 @@ */ package de.neemann.digital.fsm.gui; +import de.neemann.digital.FileLocator; import de.neemann.digital.core.*; import de.neemann.digital.core.element.ElementAttributes; import de.neemann.digital.draw.graphics.*; @@ -141,7 +142,11 @@ public class FSMFrame extends JFrame implements ClosingWindowListener.ConfirmSav setFSM(new FSM()); SwingUtilities.invokeLater(() -> { - File f = getFileNameFromHistory(); + File f = new FileLocator(probeLabelName) + .setBaseFile(baseFilename) + .setHistory(fileHistory) + .setLibrary(library) + .locate(); if (f != null) loadFile(f); }); @@ -402,15 +407,6 @@ public class FSMFrame extends JFrame implements ClosingWindowListener.ConfirmSav return this; } - private File getFileNameFromHistory() { - File f = fileHistory.getMostRecent(); - if (f != null) - for (File hf : fileHistory.getFiles()) - if (hf.getName().equals(probeLabelName)) - f = hf; - return f; - } - private void createHelpMenu(JMenuBar bar, JToolBar toolBar) { JMenu helpMenu = new JMenu(Lang.get("menu_help"));