diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/services/FileImporterService.java b/Ghidra/Features/Base/src/main/java/ghidra/app/services/FileImporterService.java index d2fd22f776..1d612e85dd 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/services/FileImporterService.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/services/FileImporterService.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -30,16 +30,17 @@ public interface FileImporterService { /** * Imports the given file into the specified Ghidra project folder. - * @param folder the Ghidra project folder to store the imported file. - * If null, the active project's root folder will be assumed. + * @param folder the folder to use as the destination for the import. If the value is null, + * then the last used folder is preferred, with the root folder being used by default. * @param file the file to import. */ public void importFile(DomainFolder folder, File file); /** * Imports the given files into the specified Ghidra project folder. - * @param folder the Ghidra project folder to store the imported files. - * If null, the active project's root folder will be assumed. + * @param folder the Ghidra project folder to store the imported files. The folder to use as + * the destination for the import. If the value is null, then the last used folder is + * preferred, with the root folder being used by default. * @param files the files to import. */ public void importFiles(DomainFolder folder, List files); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/plugin/importer/ImporterDialog.java b/Ghidra/Features/Base/src/main/java/ghidra/plugin/importer/ImporterDialog.java index 3760ebf483..426c1e929d 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/plugin/importer/ImporterDialog.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/plugin/importer/ImporterDialog.java @@ -65,6 +65,8 @@ import ghidra.util.task.TaskBuilder; */ public class ImporterDialog extends DialogComponentProvider { + private static final String PREFERENCES_LAST_FOLDER = "IMPORTER_DIALOG_LAST_FOLDER"; + protected PluginTool tool; private ProgramManager programManager; protected FSRL fsrl; @@ -131,7 +133,8 @@ public class ImporterDialog extends DialogComponentProvider { setDefaultButton(okButton); setOkEnabled(false); - setDestinationFolder(getProjectRootFolder()); + DomainFolder folder = initializeDestinationFolder(); + setDestinationFolder(folder); selectedLoaderChanged(); setMinimumSize(new Dimension(500, getPreferredSize().height)); setRememberSize(false); @@ -367,6 +370,15 @@ public class ImporterDialog extends DialogComponentProvider { //@formatter:on close(); + + saveLastUsedFolder(); + } + + private void saveLastUsedFolder() { + + String path = destinationFolder.getPathname(); + Preferences.setProperty(PREFERENCES_LAST_FOLDER, path); + Preferences.store(); } private String removeTrailingSlashes(String path) { @@ -586,15 +598,26 @@ public class ImporterDialog extends DialogComponentProvider { return preferredSpecPair; } - private DomainFolder getProjectRootFolder() { + private DomainFolder initializeDestinationFolder() { Project project = AppInfo.getActiveProject(); ProjectData projectData = project.getProjectData(); + String lastFolderPath = Preferences.getProperty(PREFERENCES_LAST_FOLDER); + if (lastFolderPath == null) { + return projectData.getRootFolder(); + } + + DomainFolder folder = projectData.getFolder(lastFolderPath); + if (folder != null) { + return folder; + } + return projectData.getRootFolder(); } private void chooseProjectFolder() { + JComponent component = getComponent(); DataTreeDialog dataTreeDialog = - new DataTreeDialog(getComponent(), "Choose a project folder", CHOOSE_FOLDER); + new DataTreeDialog(component, "Choose a Project Folder", CHOOSE_FOLDER); dataTreeDialog.setSelectedFolder(destinationFolder); dataTreeDialog.showComponent(); DomainFolder folder = dataTreeDialog.getDomainFolder(); @@ -603,9 +626,10 @@ public class ImporterDialog extends DialogComponentProvider { } } - /////////////////////////////////////// - // Methods for testing /// - /////////////////////////////////////// + public DomainFolder getDestinationFolder() { + return destinationFolder; + } + JComboBox getFormatComboBox() { return loaderComboBox; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/plugin/importer/ImporterPlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/plugin/importer/ImporterPlugin.java index a6ce4e3d4f..1651eb7299 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/plugin/importer/ImporterPlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/plugin/importer/ImporterPlugin.java @@ -28,13 +28,14 @@ import docking.action.*; import docking.tool.ToolConstants; import docking.widgets.filechooser.GhidraFileChooser; import docking.widgets.filechooser.GhidraFileChooserMode; -import docking.widgets.tree.GTreeNode; import ghidra.app.CorePluginPackage; import ghidra.app.context.ListingActionContext; import ghidra.app.events.ProgramActivatedPluginEvent; +import ghidra.app.nav.Navigatable; import ghidra.app.plugin.PluginCategoryNames; import ghidra.app.services.FileImporterService; import ghidra.app.services.ProgramManager; +import ghidra.app.util.Option; import ghidra.app.util.bin.ByteProvider; import ghidra.app.util.opinion.*; import ghidra.formats.gfilesystem.FSRL; @@ -42,8 +43,7 @@ import ghidra.formats.gfilesystem.FileCache.FileCacheEntry; import ghidra.formats.gfilesystem.FileCache.FileCacheEntryBuilder; import ghidra.formats.gfilesystem.FileSystemService; import ghidra.framework.main.*; -import ghidra.framework.main.datatree.DataTree; -import ghidra.framework.main.datatree.JavaFileListHandler; +import ghidra.framework.main.datatree.*; import ghidra.framework.model.*; import ghidra.framework.options.ToolOptions; import ghidra.framework.plugintool.*; @@ -52,6 +52,7 @@ import ghidra.framework.preferences.Preferences; import ghidra.framework.store.local.ItemDeserializer; import ghidra.framework.store.local.LocalFileSystem; import ghidra.plugins.importer.batch.BatchImportDialog; +import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressRange; import ghidra.program.model.listing.Program; import ghidra.program.model.mem.*; @@ -169,37 +170,28 @@ public class ImporterPlugin extends Plugin if (loadSpec == null) { return false; } - return loadSpec.getLoader() - .getDefaultOptions(provider, loadSpec, null, false, false) - .stream() - .anyMatch(e -> e.getName() - .equals(AbstractLibrarySupportLoader.LOAD_ONLY_LIBRARIES_OPTION_NAME)); + + String option = AbstractLibrarySupportLoader.LOAD_ONLY_LIBRARIES_OPTION_NAME; + Loader loader = loadSpec.getLoader(); + List