From a3ff03c8f3ac25829a44f42cf8ddf8d0544fa411 Mon Sep 17 00:00:00 2001 From: Ahmed Ashour Date: Wed, 20 Mar 2019 09:37:57 +0100 Subject: [PATCH] GUI: disable package if "excluded" --- .../src/main/java/jadx/gui/JadxWrapper.java | 29 +++++- .../java/jadx/gui/settings/JadxSettings.java | 1 + .../jadx/gui/settings/JadxSettingsWindow.java | 4 + .../java/jadx/gui/treemodel/JPackage.java | 45 +++++++-- .../java/jadx/gui/treemodel/JSources.java | 6 +- .../src/main/java/jadx/gui/ui/MainWindow.java | 99 +++++++++++++++---- 6 files changed, 146 insertions(+), 38 deletions(-) diff --git a/jadx-gui/src/main/java/jadx/gui/JadxWrapper.java b/jadx-gui/src/main/java/jadx/gui/JadxWrapper.java index 52ec3908b..69bd82107 100644 --- a/jadx-gui/src/main/java/jadx/gui/JadxWrapper.java +++ b/jadx-gui/src/main/java/jadx/gui/JadxWrapper.java @@ -1,12 +1,15 @@ package jadx.gui; -import javax.swing.*; import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.concurrent.ThreadPoolExecutor; import java.util.stream.Collectors; +import javax.swing.ProgressMonitor; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -78,14 +81,13 @@ public class JadxWrapper { */ public List getIncludedClasses() { List classList = decompiler.getClasses(); - String excludedPackages = settings.getExcludedPackages().trim(); - if (excludedPackages.length() == 0) { + List excludedPackages = getExcludedPackages(); + if (excludedPackages.isEmpty()) { return classList; } - String[] excluded = excludedPackages.split("[ ]+"); return classList.stream().filter(cls -> { - for (String exclude : excluded) { + for (String exclude : excludedPackages) { if (cls.getFullName().startsWith(exclude)) { return false; } @@ -94,6 +96,23 @@ public class JadxWrapper { }).collect(Collectors.toList()); } + public List getExcludedPackages() { + String excludedPackages = settings.getExcludedPackages().trim(); + return Arrays.asList(excludedPackages.split("[ ]+")); + } + + public void addExcludedPackage(String packageToExclude) { + settings.setExcludedPackages(settings.getExcludedPackages() + ' ' + packageToExclude); + settings.sync(); + } + + public void removeExcludedPackage(String packageToRemoveFromExclusion) { + List list = new ArrayList<>(getExcludedPackages()); + list.remove(packageToRemoveFromExclusion); + settings.setExcludedPackages(String.join(" ", list)); + settings.sync(); + } + public List getPackages() { return decompiler.getPackages(); } diff --git a/jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java b/jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java index f0c190229..7a7c04c33 100644 --- a/jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java +++ b/jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java @@ -333,4 +333,5 @@ public class JadxSettings extends JadxCLIArgs { settingsVersion = CURRENT_SETTINGS_VERSION; sync(); } + } diff --git a/jadx-gui/src/main/java/jadx/gui/settings/JadxSettingsWindow.java b/jadx-gui/src/main/java/jadx/gui/settings/JadxSettingsWindow.java index 81579a996..c2252a9a7 100644 --- a/jadx-gui/src/main/java/jadx/gui/settings/JadxSettingsWindow.java +++ b/jadx-gui/src/main/java/jadx/gui/settings/JadxSettingsWindow.java @@ -247,10 +247,14 @@ public class JadxSettingsWindow extends JDialog { JButton editExcludedPackages = new JButton(NLS.str("preferences.excludedPackages.button")); editExcludedPackages.addActionListener(event -> { + String oldExcludedPackages = settings.getExcludedPackages(); String result = JOptionPane.showInputDialog(this, NLS.str("preferences.excludedPackages.editDialog"), settings.getExcludedPackages()); if (result != null) { settings.setExcludedPackages(result); + if (!oldExcludedPackages.equals(result)) { + needReload(); + } } }); diff --git a/jadx-gui/src/main/java/jadx/gui/treemodel/JPackage.java b/jadx-gui/src/main/java/jadx/gui/treemodel/JPackage.java index bfb8ce6bc..8481bbbcb 100644 --- a/jadx-gui/src/main/java/jadx/gui/treemodel/JPackage.java +++ b/jadx-gui/src/main/java/jadx/gui/treemodel/JPackage.java @@ -1,13 +1,16 @@ package jadx.gui.treemodel; -import javax.swing.*; import java.util.ArrayList; import java.util.List; +import javax.swing.Icon; +import javax.swing.ImageIcon; + import org.jetbrains.annotations.NotNull; import jadx.api.JavaClass; import jadx.api.JavaPackage; +import jadx.gui.JadxWrapper; import jadx.gui.utils.Utils; public class JPackage extends JNode implements Comparable { @@ -15,12 +18,16 @@ public class JPackage extends JNode implements Comparable { private static final ImageIcon PACKAGE_ICON = Utils.openIcon("package_obj"); + private final String fullName; private String name; + private boolean enabled; private final List classes; private final List innerPackages = new ArrayList<>(1); - public JPackage(JavaPackage pkg) { + public JPackage(JavaPackage pkg, JadxWrapper wrapper) { + this.fullName = pkg.getName(); this.name = pkg.getName(); + setEnabled(wrapper); List javaClasses = pkg.getClasses(); this.classes = new ArrayList<>(javaClasses.size()); for (JavaClass javaClass : javaClasses) { @@ -29,20 +36,30 @@ public class JPackage extends JNode implements Comparable { update(); } - public JPackage(String name) { + public JPackage(String name, JadxWrapper wrapper) { + this.fullName = name; this.name = name; + setEnabled(wrapper); this.classes = new ArrayList<>(1); } + private void setEnabled(JadxWrapper wrapper) { + List excludedPackages = wrapper.getExcludedPackages(); + this.enabled = excludedPackages.isEmpty() + || excludedPackages.stream().filter(p -> !p.isEmpty()).noneMatch(p -> name.startsWith(p)); + } + public final void update() { removeAllChildren(); - for (JPackage pkg : innerPackages) { - pkg.update(); - add(pkg); - } - for (JClass cls : classes) { - cls.update(); - add(cls); + if (isEnabled()) { + for (JPackage pkg : innerPackages) { + pkg.update(); + add(pkg); + } + for (JClass cls : classes) { + cls.update(); + add(cls); + } } } @@ -51,6 +68,10 @@ public class JPackage extends JNode implements Comparable { return name; } + public String getFullName() { + return fullName; + } + public void setName(String name) { this.name = name; } @@ -108,4 +129,8 @@ public class JPackage extends JNode implements Comparable { public String makeLongString() { return name; } + + public boolean isEnabled() { + return enabled; + } } diff --git a/jadx-gui/src/main/java/jadx/gui/treemodel/JSources.java b/jadx-gui/src/main/java/jadx/gui/treemodel/JSources.java index d6541fb8c..09a66d91d 100644 --- a/jadx-gui/src/main/java/jadx/gui/treemodel/JSources.java +++ b/jadx-gui/src/main/java/jadx/gui/treemodel/JSources.java @@ -33,7 +33,7 @@ public class JSources extends JNode { removeAllChildren(); if (flatPackages) { for (JavaPackage pkg : wrapper.getPackages()) { - add(new JPackage(pkg)); + add(new JPackage(pkg, wrapper)); } } else { // build packages hierarchy @@ -54,7 +54,7 @@ public class JSources extends JNode { List getHierarchyPackages(List packages) { Map pkgMap = new HashMap<>(); for (JavaPackage pkg : packages) { - addPackage(pkgMap, new JPackage(pkg)); + addPackage(pkgMap, new JPackage(pkg, wrapper)); } // merge packages without classes boolean repeat; @@ -114,7 +114,7 @@ public class JSources extends JNode { pkg.setName(shortName); JPackage prevPkg = pkgs.get(prevPart); if (prevPkg == null) { - prevPkg = new JPackage(prevPart); + prevPkg = new JPackage(prevPart, wrapper); addPackage(pkgs, prevPkg); } prevPkg.getInnerPackages().add(pkg); diff --git a/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java b/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java index 4783e984f..608e50c66 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java @@ -1,6 +1,47 @@ package jadx.gui.ui; -import javax.swing.*; +import static javax.swing.KeyStroke.getKeyStroke; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.DisplayMode; +import java.awt.Font; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DropTarget; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.File; +import java.io.FileInputStream; +import java.util.Arrays; +import java.util.Timer; +import java.util.TimerTask; + +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.Box; +import javax.swing.ImageIcon; +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.JScrollPane; +import javax.swing.JSplitPane; +import javax.swing.JToggleButton; +import javax.swing.JToolBar; +import javax.swing.JTree; +import javax.swing.ProgressMonitor; +import javax.swing.SwingUtilities; +import javax.swing.WindowConstants; import javax.swing.event.MenuEvent; import javax.swing.event.MenuListener; import javax.swing.event.TreeExpansionEvent; @@ -12,22 +53,6 @@ import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import javax.swing.tree.TreeSelectionModel; -import java.awt.*; -import java.awt.dnd.DnDConstants; -import java.awt.dnd.DropTarget; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.io.File; -import java.io.FileInputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Timer; -import java.util.TimerTask; import org.fife.ui.rsyntaxtextarea.Theme; import org.slf4j.Logger; @@ -46,6 +71,7 @@ import jadx.gui.treemodel.JCertificate; import jadx.gui.treemodel.JClass; import jadx.gui.treemodel.JLoadableNode; import jadx.gui.treemodel.JNode; +import jadx.gui.treemodel.JPackage; import jadx.gui.treemodel.JResource; import jadx.gui.treemodel.JRoot; import jadx.gui.update.JadxUpdate; @@ -57,8 +83,6 @@ import jadx.gui.utils.Link; import jadx.gui.utils.NLS; import jadx.gui.utils.Utils; -import static javax.swing.KeyStroke.getKeyStroke; - @SuppressWarnings("serial") public class MainWindow extends JFrame { private static final Logger LOG = LoggerFactory.getLogger(MainWindow.class); @@ -315,6 +339,14 @@ public class MainWindow extends JFrame { } } + private void treeRightClickAction(MouseEvent e) { + Object obj = tree.getLastSelectedPathComponent(); + if (obj instanceof JPackage) { + JPackagePopUp menu = new JPackagePopUp((JPackage) obj); + menu.show(e.getComponent(), e.getX(), e.getY()); + } + } + private void syncWithEditor() { ContentPanel selectedContentPanel = tabbedPane.getSelectedCodePanel(); if (selectedContentPanel == null) { @@ -574,7 +606,12 @@ public class MainWindow extends JFrame { tree.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { - treeClickAction(); + if (SwingUtilities.isRightMouseButton(e)) { + treeRightClickAction(e); + } + else { + treeClickAction(); + } } }); tree.addKeyListener(new KeyAdapter() { @@ -594,6 +631,9 @@ public class MainWindow extends JFrame { if (value instanceof JNode) { setIcon(((JNode) value).getIcon()); } + if (value instanceof JPackage) { + setEnabled(((JPackage) value).isEnabled()); + } return c; } }); @@ -740,4 +780,23 @@ public class MainWindow extends JFrame { public void menuCanceled(MenuEvent e) { } } + + private class JPackagePopUp extends JPopupMenu { + JMenuItem excludeItem = new JCheckBoxMenuItem("Exclude"); + + public JPackagePopUp(JPackage pkg) { + excludeItem.setSelected(!pkg.isEnabled()); + add(excludeItem); + excludeItem.addItemListener(e -> { + String fullName = pkg.getFullName(); + if (excludeItem.isSelected()) { + wrapper.addExcludedPackage(fullName); + } + else { + wrapper.removeExcludedPackage(fullName); + } + reOpenFile(); + }); + } + } }