diff --git a/Ghidra/Features/Base/src/main/java/ghidra/plugin/importer/ImporterLanguageDialog.java b/Ghidra/Features/Base/src/main/java/ghidra/plugin/importer/ImporterLanguageDialog.java
index eecf71d3fe..acb3079571 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/plugin/importer/ImporterLanguageDialog.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/plugin/importer/ImporterLanguageDialog.java
@@ -135,7 +135,7 @@ public class ImporterLanguageDialog extends DialogComponentProvider {
}
}
- LanguageCompilerSpecPair getSelectedLanguage() {
+ public LanguageCompilerSpecPair getSelectedLanguage() {
if (wasDialogCancelled) {
return null;
}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/plugins/importer/batch/BatchGroup.java b/Ghidra/Features/Base/src/main/java/ghidra/plugins/importer/batch/BatchGroup.java
index fbb53138f1..23334d7646 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/plugins/importer/batch/BatchGroup.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/plugins/importer/batch/BatchGroup.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.
@@ -59,12 +59,10 @@ public class BatchGroup {
}
public LoadSpec getLoadSpec(BatchGroupLoadSpec batchGroupLoadSpec) {
- for (LoadSpec loadSpec : loadSpecs) {
- if (batchGroupLoadSpec.matches(loadSpec)) {
- return loadSpec;
- }
- }
- return null;
+ return loadSpecs.stream()
+ .filter(batchGroupLoadSpec::matches)
+ .findFirst()
+ .orElse(new LoadSpec(loader, 0, batchGroupLoadSpec.lcsPair(), false));
}
public UserAddedSourceInfo getUasi() {
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/plugins/importer/batch/BatchGroupLoadSpec.java b/Ghidra/Features/Base/src/main/java/ghidra/plugins/importer/batch/BatchGroupLoadSpec.java
index 0cdb7ce725..c783d6f9d1 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/plugins/importer/batch/BatchGroupLoadSpec.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/plugins/importer/batch/BatchGroupLoadSpec.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.
@@ -24,14 +24,15 @@ import ghidra.program.model.lang.LanguageCompilerSpecPair;
*
* This has the same information as a {@link LoadSpec}, but for all the members of a
* {@link BatchGroup}.
+ *
+ * @param lcsPair The language/compiler spec ID
+ * @param preferred true if this {@link BatchGroupLoadSpec} is preferred; otherwise, false
*/
-public class BatchGroupLoadSpec implements Comparable {
- public LanguageCompilerSpecPair lcsPair;
- public boolean preferred;
+public record BatchGroupLoadSpec(LanguageCompilerSpecPair lcsPair, boolean preferred)
+ implements Comparable {
public BatchGroupLoadSpec(LoadSpec loadSpec) {
- lcsPair = loadSpec.getLanguageCompilerSpec();
- preferred = loadSpec.isPreferred();
+ this(loadSpec.getLanguageCompilerSpec(), loadSpec.isPreferred());
}
@Override
@@ -45,41 +46,6 @@ public class BatchGroupLoadSpec implements Comparable {
loadSpec.getLanguageCompilerSpec().equals(lcsPair));
}
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((lcsPair == null) ? 0 : lcsPair.hashCode());
- result = prime * result + (preferred ? 1231 : 1237);
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (!(obj instanceof BatchGroupLoadSpec)) {
- return false;
- }
- BatchGroupLoadSpec other = (BatchGroupLoadSpec) obj;
- if (lcsPair == null) {
- if (other.lcsPair != null) {
- return false;
- }
- }
- else if (!lcsPair.equals(other.lcsPair)) {
- return false;
- }
- if (preferred != other.preferred) {
- return false;
- }
- return true;
- }
-
@Override
public int compareTo(BatchGroupLoadSpec o) {
String s1 = this.toString();
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/plugins/importer/batch/BatchImportDialog.java b/Ghidra/Features/Base/src/main/java/ghidra/plugins/importer/batch/BatchImportDialog.java
index 70cbfd1b66..59e3f92c0e 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/plugins/importer/batch/BatchImportDialog.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/plugins/importer/batch/BatchImportDialog.java
@@ -40,15 +40,18 @@ import docking.widgets.label.GDLabel;
import docking.widgets.table.*;
import generic.theme.GThemeDefaults.Colors.Messages;
import ghidra.app.services.ProgramManager;
+import ghidra.app.util.opinion.LoadSpec;
import ghidra.formats.gfilesystem.FSRL;
import ghidra.formats.gfilesystem.FileSystemService;
import ghidra.framework.main.AppInfo;
import ghidra.framework.model.DomainFolder;
import ghidra.framework.plugintool.PluginTool;
import ghidra.framework.preferences.Preferences;
+import ghidra.plugin.importer.ImporterLanguageDialog;
import ghidra.plugin.importer.ImporterUtilities;
import ghidra.plugins.importer.batch.BatchGroup.BatchLoadConfig;
import ghidra.plugins.importer.tasks.ImportBatchTask;
+import ghidra.program.model.lang.LanguageCompilerSpecPair;
import ghidra.util.*;
import ghidra.util.filechooser.GhidraFileFilter;
import ghidra.util.task.TaskLauncher;
@@ -76,7 +79,8 @@ public class BatchImportDialog extends DialogComponentProvider {
*/
public static void showAndImport(PluginTool tool, BatchInfo batchInfo, List initialFiles,
DomainFolder defaultFolder, ProgramManager programManager) {
- BatchImportDialog dialog = new BatchImportDialog(batchInfo, defaultFolder, programManager);
+ BatchImportDialog dialog =
+ new BatchImportDialog(batchInfo, defaultFolder, programManager, tool);
Swing.runLater(() -> {
if (initialFiles != null && !initialFiles.isEmpty()) {
dialog.addSources(initialFiles);
@@ -91,6 +95,7 @@ public class BatchImportDialog extends DialogComponentProvider {
private BatchInfo batchInfo;
private DomainFolder destinationFolder;
private ProgramManager programManager;
+ private PluginTool tool;
private boolean stripLeading = getBooleanPref(PREF_STRIPLEADING, true);
private boolean stripContainer = getBooleanPref(PREF_STRIPCONTAINER, false);
private boolean mirrorFs = getBooleanPref(PREF_MIRRORFS, false);
@@ -109,13 +114,14 @@ public class BatchImportDialog extends DialogComponentProvider {
private SourcesListModel sourceListModel;
private BatchImportDialog(BatchInfo batchInfo, DomainFolder defaultFolder,
- ProgramManager programManager) {
+ ProgramManager programManager, PluginTool tool) {
super("Batch Import", true);
this.batchInfo = (batchInfo != null) ? batchInfo : new BatchInfo();
this.destinationFolder = defaultFolder != null ? defaultFolder
: AppInfo.getActiveProject().getProjectData().getRootFolder();
this.programManager = programManager;
+ this.tool = tool;
setHelpLocation(new HelpLocation("ImporterPlugin", "Batch_Import_Dialog"));
@@ -150,6 +156,9 @@ public class BatchImportDialog extends DialogComponentProvider {
if (modelIndex == BatchImportTableModel.COLS.FILES.ordinal()) {
showFiles(row);
}
+ else if (modelIndex == BatchImportTableModel.COLS.LANG.ordinal()) {
+ showLanguages(row);
+ }
}
});
@@ -171,7 +180,6 @@ public class BatchImportDialog extends DialogComponentProvider {
TableColumn langColumn =
table.getColumnModel().getColumn(BatchImportTableModel.COLS.LANG.ordinal());
- langColumn.setCellEditor(createLangColumnCellEditor());
langColumn.setCellRenderer(createLangColumnCellRenderer());
JScrollPane scrollPane = new JScrollPane(table);
@@ -377,13 +385,10 @@ public class BatchImportDialog extends DialogComponentProvider {
BatchGroup group = tableModel.getRowObject(row);
List batchLoadConfigs = group.getBatchLoadConfig();
- //@formatter:off
List names = batchLoadConfigs.stream()
- .map(batchLoadConfig -> batchLoadConfig.getPreferredFileName())
- .sorted()
- .collect(Collectors.toList())
- ;
- //@formatter:on
+ .map(batchLoadConfig -> batchLoadConfig.getPreferredFileName())
+ .sorted()
+ .collect(Collectors.toList());
ListSelectionTableDialog dialog =
new ListSelectionTableDialog<>("Application Files", names);
@@ -391,6 +396,36 @@ public class BatchImportDialog extends DialogComponentProvider {
dialog.showSelectMultiple(table);
}
+ private void showLanguages(int row) {
+
+ BatchGroup group = tableModel.getRowObject(row);
+ List batchLoadConfigs = group.getBatchLoadConfig();
+
+ List loadSpecs = batchLoadConfigs.stream()
+ .flatMap(entry -> entry.getLoadSpecs().stream())
+ .distinct()
+ .collect(Collectors.toList());
+
+ BatchGroupLoadSpec selectedLoadSpec = group.getSelectedBatchGroupLoadSpec();
+ ImporterLanguageDialog dialog =
+ new ImporterLanguageDialog(loadSpecs, tool, selectedLoadSpec.lcsPair());
+ dialog.show(getComponent());
+ LanguageCompilerSpecPair dialogResult = dialog.getSelectedLanguage();
+ if (dialogResult != null) {
+ for (BatchLoadConfig loadConfig : batchLoadConfigs) {
+ for (LoadSpec loadSpec : loadConfig.getLoadSpecs()) {
+ if (dialogResult.equals(loadSpec.getLanguageCompilerSpec())) {
+ tableModel.setValueAt(new BatchGroupLoadSpec(loadSpec), row,
+ BatchImportTableModel.COLS.LANG.ordinal());
+ return;
+ }
+ }
+ }
+ tableModel.setValueAt(new BatchGroupLoadSpec(dialogResult, false), row,
+ BatchImportTableModel.COLS.LANG.ordinal());
+ }
+ }
+
private void setOpenAfterImporting(boolean b) {
this.openAfterImporting = b;
}
@@ -534,30 +569,6 @@ public class BatchImportDialog extends DialogComponentProvider {
return cellRenderer;
}
- private TableCellEditor createLangColumnCellEditor() {
- JComboBox