diff --git a/key.core/src/main/java/de/uka/ilkd/key/settings/GeneralSettings.java b/key.core/src/main/java/de/uka/ilkd/key/settings/GeneralSettings.java index dd95bf006ee..50436bb9722 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/settings/GeneralSettings.java +++ b/key.core/src/main/java/de/uka/ilkd/key/settings/GeneralSettings.java @@ -3,11 +3,12 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.settings; -import java.util.*; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.File; +import java.util.*; + public class GeneralSettings extends AbstractSettings { private static final Logger LOGGER = LoggerFactory.getLogger(GeneralSettings.class); @@ -43,20 +44,30 @@ public class GeneralSettings extends AbstractSettings { public static final String RIGHT_CLICK_MACROS_KEY = "RightClickMacros"; public static final String AUTO_SAVE = "AutoSavePeriod"; + public static final String LAST_USED_PATH = "LastUsedPath"; + /** * The key for storing the ensureSourceConsistency flag in settings */ private static final String ENSURE_SOURCE_CONSISTENCY = "EnsureSourceConsistency"; - /** Whether automatic proof search uses the multi-core (parallel) prover. */ + /** + * Whether automatic proof search uses the multi-core (parallel) prover. + */ public static final String PARALLEL_PROVER_ENABLED = "ParallelProverEnabled"; - /** The number of worker threads the multi-core prover uses. */ + /** + * The number of worker threads the multi-core prover uses. + */ public static final String PARALLEL_PROVER_THREADS = "ParallelProverThreadCount"; - /** Default worker count when the multi-core prover is first enabled. */ + /** + * Default worker count when the multi-core prover is first enabled. + */ public static final int PARALLEL_PROVER_THREADS_DEFAULT = 4; - /** Default value for {@link #getJmlEnabledKeys()} */ + /** + * Default value for {@link #getJmlEnabledKeys()} + */ public static final Set JML_ENABLED_KEYS_DEFAULT = Set.of("key"); private Set jmlEnabledKeys = new TreeSet<>(JML_ENABLED_KEYS_DEFAULT); @@ -86,6 +97,11 @@ public class GeneralSettings extends AbstractSettings { */ private int autoSave = 0; + /** + * + */ + private String lastUsedPath; + /** * If enabled, source files are cached at first use to ensure consistency between proof and * source code. Toggles between SimpleFilerepo (false) and DiskFileRepo (true). @@ -157,7 +173,7 @@ public boolean isParallelProverEnabled() { /** * @return the configured number of worker threads for the multi-core prover (not yet clamped to - * the available processors) + * the available processors) */ public int getParallelProverThreadCount() { return parallelProverThreadCount; @@ -218,6 +234,28 @@ public void setParallelProverThreadCount(int count) { firePropertyChange(PARALLEL_PROVER_THREADS, old, parallelProverThreadCount); } + public void setLastUsedPath(File f) { + setLastUsedPath(f.getAbsolutePath()); + } + + public void setLastUsedPath(String absolutePath) { + var old = lastUsedPath; + lastUsedPath = absolutePath; + firePropertyChange(LAST_USED_PATH, old, lastUsedPath); + } + + public File getLastUsedPath() { + if (lastUsedPath == null) { + setLastUsedPath(new File(".")); + } + return new File(lastUsedPath); + } + + public File getLastUsedPathEnsureFolder() { + if (getLastUsedPath().isFile()) return getLastUsedPath().getParentFile(); + else return getLastUsedPath(); + } + /** * gets a Properties object and has to perform the necessary steps in order to change this * object in a way that it represents the stored settings @@ -302,15 +340,15 @@ public void writeSettings(Properties props) { var prefix = "[" + CATEGORY + "]"; props.setProperty(prefix + TACLET_FILTER, String.valueOf(tacletFilter)); props.setProperty(prefix + DND_DIRECTION_SENSITIVE_KEY, - String.valueOf(dndDirectionSensitive)); + String.valueOf(dndDirectionSensitive)); props.setProperty(prefix + RIGHT_CLICK_MACROS_KEY, String.valueOf(rightClickMacros)); props.setProperty(prefix + USE_JML_KEY, String.valueOf(useJML)); props.setProperty(prefix + AUTO_SAVE, String.valueOf(autoSave)); props.setProperty(prefix + ENSURE_SOURCE_CONSISTENCY, - String.valueOf(ensureSourceConsistency)); + String.valueOf(ensureSourceConsistency)); props.setProperty(prefix + PARALLEL_PROVER_ENABLED, String.valueOf(parallelProverEnabled)); props.setProperty(prefix + PARALLEL_PROVER_THREADS, - String.valueOf(parallelProverThreadCount)); + String.valueOf(parallelProverThreadCount)); props.setProperty(KEY_JML_ENABLED_KEYS, String.join(",", jmlEnabledKeys)); } @@ -331,7 +369,7 @@ public void readSettings(Configuration props) { setEnsureSourceConsistency(props.getBool(ENSURE_SOURCE_CONSISTENCY)); setParallelProverEnabled(props.getBool(PARALLEL_PROVER_ENABLED, false)); setParallelProverThreadCount( - props.getInt(PARALLEL_PROVER_THREADS, PARALLEL_PROVER_THREADS_DEFAULT)); + props.getInt(PARALLEL_PROVER_THREADS, PARALLEL_PROVER_THREADS_DEFAULT)); var sysProp = System.getProperty(KEY_JML_ENABLED_KEYS); if (sysProp != null) { @@ -340,6 +378,8 @@ public void readSettings(Configuration props) { } else { setJmlEnabledKeys(new TreeSet<>(props.getStringList(KEY_JML_ENABLED_KEYS))); } + + setLastUsedPath(props.getString(LAST_USED_PATH, new File(".").getAbsolutePath())); } @Override @@ -354,4 +394,6 @@ public void writeSettings(Configuration props) { props.set(PARALLEL_PROVER_THREADS, parallelProverThreadCount); props.set(KEY_JML_ENABLED_KEYS, jmlEnabledKeys.stream().toList()); } + + } diff --git a/key.ui/src/main/java/de/uka/ilkd/key/core/Main.java b/key.ui/src/main/java/de/uka/ilkd/key/core/Main.java index 0b144d16d38..d03a56f7e4e 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/core/Main.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/core/Main.java @@ -533,24 +533,6 @@ private static File createTempDirectory() throws IOException { return tempDir; } - /** - * Used by {@link de.uka.ilkd.key.gui.KeYFileChooser} (and potentially others) - * to determine - * working directory. In case there is at least one location (i.e. a file or - * directory) - * specified as command line argument, working directory is determined based on - * first location - * that occurred in the list of arguments. Otherwise, value of - * System.getProperty("user.home") - * is used to determine working directory. - * - * @return {@link File} object representing working directory. - */ - public static Path getWorkingDir() { - return workingDir; - } - - /** * Perform necessary actions before loading any problem files. Currently only * performs RIFL to JML transformation. diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/KeYFileChooser.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/KeYFileChooser.java index 1fdb397a8c5..70e204bd5c3 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/KeYFileChooser.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/KeYFileChooser.java @@ -13,6 +13,8 @@ import de.uka.ilkd.key.core.Main; +import de.uka.ilkd.key.settings.ProofIndependentSettings; +import org.jspecify.annotations.Nullable; import org.key_project.util.java.IOUtil; /** @@ -307,10 +309,11 @@ private int showOverwriteDialog(File file) { * * @return the key file chooser */ - public static KeYFileChooser getFileChooser(String title) { + public static KeYFileChooser getFileChooser(String title, @Nullable File startFolder) { if (INSTANCE == null) { - File initDir = Main.getWorkingDir().toFile(); - INSTANCE = new KeYFileChooser(initDir); + INSTANCE = new KeYFileChooser(startFolder == null + ? ProofIndependentSettings.DEFAULT_INSTANCE.getGeneralSettings().getLastUsedPath() + : startFolder); // not the best design probably: this constructor has the side effect of connecting // the new bookmark panel to the file chooser. diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/actions/OpenFileAction.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/actions/OpenFileAction.java index 06465bf2ad8..25c61abdc84 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/actions/OpenFileAction.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/actions/OpenFileAction.java @@ -24,14 +24,12 @@ public OpenFileAction(MainWindow mainWindow) { setName("Load..."); setIcon(IconFactory.openKeYFile(MainWindow.TOOLBAR_ICON_SIZE)); setTooltip("Browse and load problem or proof files."); - lastSelectedPath = Main.getWorkingDir().toFile(); + lastSelectedPath = ProofIndependentSettings.DEFAULT_INSTANCE.getGeneralSettings().getLastUsedPath(); } public void actionPerformed(ActionEvent e) { - KeYFileChooser fc = new KeYFileChooser(lastSelectedPath); + KeYFileChooser fc = KeYFileChooser.getFileChooser("Select file to load proof or problem", lastSelectedPath); fc.setDialogTitle("Select file to load proof or problem"); - fc.setSelectedFile(KeYFileChooser.getFileChooser("Select file to load proof or problem") - .getSelectedFile()); KeYFileChooserLoadingOptions options = fc.addLoadingOptions(); fc.addBookmarkPanel(); fc.prepare(); @@ -42,6 +40,7 @@ public void actionPerformed(ActionEvent e) { if (result == JFileChooser.APPROVE_OPTION) { Path file = fc.getSelectedFile().toPath(); lastSelectedPath = fc.getSelectedFile(); + ProofIndependentSettings.DEFAULT_INSTANCE.getGeneralSettings().setLastUsedPath(lastSelectedPath); // special case proof bundles -> allow to select the proof to load if (ProofSelectionDialog.isProofBundle(file)) { diff --git a/key.ui/src/main/java/de/uka/ilkd/key/ui/AbstractMediatorUserInterfaceControl.java b/key.ui/src/main/java/de/uka/ilkd/key/ui/AbstractMediatorUserInterfaceControl.java index 2d371f51113..e73134feaaf 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/ui/AbstractMediatorUserInterfaceControl.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/ui/AbstractMediatorUserInterfaceControl.java @@ -30,6 +30,7 @@ import de.uka.ilkd.key.proof.mgt.ProofEnvironmentEvent; import de.uka.ilkd.key.proof.mgt.ProofEnvironmentListener; import de.uka.ilkd.key.prover.impl.DefaultTaskStartedInfo; +import de.uka.ilkd.key.settings.ProofIndependentSettings; import de.uka.ilkd.key.util.KeYResourceManager; import de.uka.ilkd.key.util.MiscTools; import de.uka.ilkd.key.util.ThreadUtilities; @@ -211,7 +212,8 @@ private void saveSideProof(Proof proof) { if (proof.getProofFile() != null) { proofFolder = proof.getProofFile().getParent(); } else { // happens when a Java file is loaded - proofFolder = Main.getWorkingDir(); + proofFolder = ProofIndependentSettings.DEFAULT_INSTANCE.getGeneralSettings() + .getLastUsedPathEnsureFolder(); } final Path toSave = proofFolder.resolve(filename); final KeYResourceManager krm = KeYResourceManager.getManager();