fix(gui): update mappings node instead full reload on 'save as' (#1732)

This commit is contained in:
Skylot
2023-04-20 22:00:06 +01:00
parent e57787393e
commit ee2556ecb6
5 changed files with 58 additions and 11 deletions
@@ -27,9 +27,13 @@ import jadx.core.utils.Utils;
import jadx.gui.jobs.TaskStatus;
import jadx.gui.settings.JadxProject;
import jadx.gui.settings.JadxSettings;
import jadx.gui.treemodel.JNode;
import jadx.gui.treemodel.JRoot;
import jadx.gui.ui.MainWindow;
import jadx.gui.ui.TabbedPane;
import jadx.gui.ui.filedialog.FileDialogWrapper;
import jadx.gui.ui.filedialog.FileOpenMode;
import jadx.gui.ui.panel.ContentPanel;
import jadx.gui.utils.NLS;
import jadx.gui.utils.UiUtils;
import jadx.gui.utils.ui.ActionHandler;
@@ -41,8 +45,8 @@ public class RenameMappingsGui {
private final MainWindow mainWindow;
// private MappingFormat currentMappingFormat;
private boolean renamesChanged = false;
private JInputMapping mappingNode;
private transient JMenu openMappingsMenu;
private transient Action saveMappingsAction;
@@ -52,6 +56,7 @@ public class RenameMappingsGui {
public RenameMappingsGui(MainWindow mainWindow) {
this.mainWindow = mainWindow;
mainWindow.addLoadListener(this::onLoad);
mainWindow.addTreeUpdateListener(this::treeUpdate);
}
public void addMenuActions(JMenu menu) {
@@ -84,6 +89,7 @@ public class RenameMappingsGui {
private boolean onLoad(boolean loaded) {
renamesChanged = false;
mappingNode = null;
if (loaded) {
RootNode rootNode = mainWindow.getWrapper().getRootNode();
rootNode.registerCodeDataUpdateListener(codeData -> onRename());
@@ -119,6 +125,29 @@ public class RenameMappingsGui {
closeMappingsAction.setEnabled(project.getMappingsPath() != null);
}
private void treeUpdate(JRoot treeRoot) {
if (mappingNode != null) {
// already added
return;
}
Path mappingsPath = mainWindow.getProject().getMappingsPath();
if (mappingsPath == null) {
return;
}
JNode node = treeRoot.followStaticPath("JInputs");
JNode currentNode = node.removeNode(n -> n.getClass().equals(JInputMapping.class));
if (currentNode != null) {
// close opened tab
TabbedPane tabbedPane = mainWindow.getTabbedPane();
ContentPanel openedTab = tabbedPane.getOpenTabs().get(currentNode);
if (openedTab != null) {
tabbedPane.closeCodePanel(openedTab);
}
}
mappingNode = new JInputMapping(mappingsPath);
node.add(mappingNode);
}
private void openMappings(MappingFormat mappingFormat, boolean inverted) {
FileDialogWrapper fileDialog = new FileDialogWrapper(mainWindow, FileOpenMode.CUSTOM_OPEN);
fileDialog.setTitle(NLS.str("file.open_mappings"));
@@ -205,7 +234,10 @@ public class RenameMappingsGui {
options.put(RenameMappingsOptions.FORMAT_OPT, mappingFormat.name());
options.put(RenameMappingsOptions.INVERT_OPT, "no");
});
saveInBackground(mappingFormat, savePath, s -> mainWindow.reopen());
saveInBackground(mappingFormat, savePath, s -> {
mappingNode = null;
mainWindow.reloadTree();
});
}
private void saveInBackground(MappingFormat mappingFormat, Path savePath, Consumer<TaskStatus> onFinishUiRunnable) {
@@ -68,7 +68,7 @@ public class TabStateViewAdapter {
.searchNode(node -> node instanceof JInputScript && node.getName().equals(tvs.getTabPath()));
case "mapping":
return mw.getTreeRoot().followStaticPath("JInputs", "JInputMapping");
return mw.getTreeRoot().followStaticPath("JInputs").searchNode(node -> node instanceof JInputMapping);
}
return null;
}
@@ -1,6 +1,5 @@
package jadx.gui.treemodel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Iterator;
@@ -11,7 +10,6 @@ import javax.swing.ImageIcon;
import jadx.core.utils.files.FileUtils;
import jadx.gui.JadxWrapper;
import jadx.gui.plugins.mappings.JInputMapping;
import jadx.gui.settings.JadxProject;
import jadx.gui.utils.NLS;
import jadx.gui.utils.UiUtils;
@@ -35,11 +33,6 @@ public class JInputs extends JNode {
add(new JInputFiles(files));
add(new JInputScripts(scripts));
Path mappingsPath = project.getMappingsPath();
if (mappingsPath != null && Files.isRegularFile(mappingsPath)) {
add(new JInputMapping(mappingsPath));
}
}
@Override
@@ -111,7 +111,7 @@ public abstract class JNode extends DefaultMutableTreeNode implements Comparable
}
public @Nullable JNode searchNode(Predicate<JNode> filter) {
Enumeration<?> en = this.breadthFirstEnumeration();
Enumeration<?> en = this.children();
while (en.hasMoreElements()) {
JNode node = (JNode) en.nextElement();
if (filter.test(node)) {
@@ -121,6 +121,21 @@ public abstract class JNode extends DefaultMutableTreeNode implements Comparable
return null;
}
/**
* Remove and return first found node
*/
public @Nullable JNode removeNode(Predicate<JNode> filter) {
Enumeration<?> en = this.children();
while (en.hasMoreElements()) {
JNode node = (JNode) en.nextElement();
if (filter.test(node)) {
this.remove(node);
return node;
}
}
return null;
}
private static final Comparator<JNode> COMPARATOR = Comparator
.comparing(JNode::makeLongString)
.thenComparingInt(JNode::getPos);
@@ -37,6 +37,7 @@ import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import javax.swing.AbstractAction;
import javax.swing.Action;
@@ -212,6 +213,7 @@ public class MainWindow extends JFrame {
private transient @Nullable JDebuggerPanel debuggerPanel;
private final List<ILoadListener> loadListeners = new ArrayList<>();
private final List<Consumer<JRoot>> treeUpdateListener = new ArrayList<>();
private boolean loaded;
private JMenu pluginsMenu;
@@ -689,6 +691,7 @@ public class MainWindow extends JFrame {
public void reloadTree() {
treeReloading = true;
treeUpdateListener.forEach(listener -> listener.accept(treeRoot));
treeModel.reload();
List<String[]> treeExpansions = project.getTreeExpansions();
@@ -1526,6 +1529,10 @@ public class MainWindow extends JFrame {
loadListeners.removeIf(listener -> listener.update(loaded));
}
public void addTreeUpdateListener(Consumer<JRoot> listener) {
treeUpdateListener.add(listener);
}
public JadxWrapper getWrapper() {
return wrapper;
}