Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(gui): Quick Tabs Optimization #2242

Merged
merged 6 commits into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions jadx-gui/src/main/java/jadx/gui/jobs/BackgroundExecutor.java
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,17 @@ protected TaskStatus doInBackground() throws Exception {
task.onDone(this);
// treat UI task operations as part of the task to not mix with others
UiUtils.uiRunAndWait(() -> {
progressPane.setVisible(false);
task.onFinish(this);
try {
progressPane.setVisible(false);
task.onFinish(this);
} catch (Throwable e) {
LOG.error("Task onFinish failed", e);
status = TaskStatus.ERROR;
}
});
} catch (Throwable e) {
LOG.error("Task onDone failed", e);
status = TaskStatus.ERROR;
} finally {
taskComplete(id);
progressPane.changeVisibility(this, false);
Expand Down
8 changes: 4 additions & 4 deletions jadx-gui/src/main/java/jadx/gui/logs/LogPanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import jadx.gui.treemodel.JNode;
import jadx.gui.ui.MainWindow;
import jadx.gui.ui.codearea.AbstractCodeArea;
import jadx.gui.ui.panel.ContentPanel;
import jadx.gui.ui.tab.TabBlueprint;
import jadx.gui.utils.NLS;

public class LogPanel extends JPanel {
Expand Down Expand Up @@ -141,9 +141,9 @@ private void registerLogListener(LogOptions logOptions) {
}

private @Nullable String getCurrentScriptName() {
ContentPanel selectedCodePanel = mainWindow.getTabbedPane().getSelectedContentPanel();
if (selectedCodePanel != null) {
JNode node = selectedCodePanel.getNode();
TabBlueprint selectedTab = mainWindow.getTabsController().getSelectedTab();
if (selectedTab != null) {
JNode node = selectedTab.getNode();
if (node instanceof JInputScript) {
return node.getName();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ public boolean open(ICodeNodeRef ref) {
return false;
}

commonContext.getMainWindow().getTabbedPane().codeJump(node);
commonContext.getMainWindow().getTabsController().codeJump(node);
return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ private void loadReport() {
root.replaceCustomNode(quarkNode);
root.update();
mainWindow.reloadTree();
mainWindow.getTabbedPane().showNode(quarkNode);
mainWindow.getTabsController().selectTab(quarkNode);
} catch (Exception e) {
UiUtils.errorMessage(mainWindow, "Failed to load Quark report.");
LOG.error("Failed to load Quark report.", e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ public void mouseClicked(MouseEvent event) {
Object node = getNodeUnderMouse(tree, event);
if (node instanceof MethodTreeNode) {
JMethod method = ((MethodTreeNode) node).getJMethod();
tabbedPane.codeJump(method);
tabbedPane.getTabsController().codeJump(method);
}
}
}
Expand Down Expand Up @@ -159,7 +159,7 @@ private String buildHeader() {

@Override
public void loadSettings() {
Font settingsFont = getTabbedPane().getMainWindow().getSettings().getFont();
Font settingsFont = getMainWindow().getSettings().getFont();
this.font = settingsFont.deriveFont(settingsFont.getSize2D() + 1.f);
this.boldFont = font.deriveFont(Font.BOLD);
header.setFont(font);
Expand Down Expand Up @@ -279,7 +279,7 @@ public MutableTreeNode resolveMethod(String descr) {
String[] parts = removeQuotes(descr).split(" ", 3);
String cls = Utils.cleanObjectName(parts[0].replace('$', '.'));
String mth = parts[1] + parts[2].replace(" ", "");
MainWindow mainWindow = getTabbedPane().getMainWindow();
MainWindow mainWindow = getMainWindow();
JadxWrapper wrapper = mainWindow.getWrapper();
JavaClass javaClass = wrapper.searchJavaClassByRawName(cls);
if (javaClass == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ public ScriptCodeArea(ContentPanel contentPanel, JInputScript node) {
setCodeFoldingEnabled(true);
setCloseCurlyBraces(true);

shortcutsController = contentPanel.getTabbedPane().getMainWindow().getShortcutsController();
JadxSettings settings = contentPanel.getTabbedPane().getMainWindow().getSettings();
shortcutsController = contentPanel.getMainWindow().getShortcutsController();
JadxSettings settings = contentPanel.getMainWindow().getSettings();
autoCompletion = addAutoComplete(settings);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ private void applySettings() {
}

private void showScriptLog() {
getTabbedPane().getMainWindow().showLogViewer(LogOptions.forScript(getNode().getName()));
getMainWindow().showLogViewer(LogOptions.forScript(getNode().getName()));
}

@Override
Expand Down
3 changes: 1 addition & 2 deletions jadx-gui/src/main/java/jadx/gui/treemodel/JNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@ public ICodeNodeRef getCodeNodeRef() {
return null;
}

@Nullable
public ContentPanel getContentPanel(TabbedPane tabbedPane) {
public @Nullable ContentPanel getContentPanel(TabbedPane tabbedPane) {
return null;
}

Expand Down
60 changes: 35 additions & 25 deletions jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@
import jadx.gui.ui.panel.JDebuggerPanel;
import jadx.gui.ui.panel.ProgressPanel;
import jadx.gui.ui.popupmenu.RecentProjectsMenuListener;
import jadx.gui.ui.tab.EditorSyncManager;
import jadx.gui.ui.tab.NavigationController;
import jadx.gui.ui.tab.QuickTabsTree;
import jadx.gui.ui.tab.TabbedPane;
import jadx.gui.ui.tab.TabsController;
Expand Down Expand Up @@ -195,6 +197,10 @@ public class MainWindow extends JFrame {
private final transient CacheManager cacheManager;
private final transient BackgroundExecutor backgroundExecutor;

private final TabsController tabsController;
private final NavigationController navController;
private final EditorSyncManager editorSyncManager;

private transient @NotNull JadxProject project;

private transient JadxGuiAction newProjectAction;
Expand All @@ -209,7 +215,6 @@ public class MainWindow extends JFrame {
private JTree tree;
private DefaultTreeModel treeModel;
private JRoot treeRoot;
private TabsController tabsController;
private TabbedPane tabbedPane;
private HeapUsageBar heapUsageBar;
private transient boolean treeReloading;
Expand Down Expand Up @@ -238,7 +243,7 @@ public class MainWindow extends JFrame {
private boolean loaded;
private boolean settingsOpen = false;

private ShortcutsController shortcutsController;
private final ShortcutsController shortcutsController;
private JadxMenuBar menuBar;
private JMenu pluginsMenu;

Expand All @@ -253,16 +258,19 @@ public MainWindow(JadxSettings settings) {
this.renameMappings = new RenameMappingsGui(this);
this.cacheManager = new CacheManager(settings);
this.shortcutsController = new ShortcutsController(settings);
this.tabsController = new TabsController(this);
this.navController = new NavigationController(this);

JadxEventQueue.register();
resetCache();
FontUtils.registerBundledFonts();
setEditorTheme(settings.getEditorThemePath());
initUI();
this.editorSyncManager = new EditorSyncManager(this, tabbedPane);
this.backgroundExecutor = new BackgroundExecutor(settings, progressPane);
initMenuAndToolbar();
UiUtils.setWindowIcons(this);
shortcutsController.registerMouseEventListener(this);
this.shortcutsController.registerMouseEventListener(this);
loadSettings();

update();
Expand All @@ -288,7 +296,7 @@ public void windowClosing(WindowEvent e) {

private void processCommandLineArgs() {
if (settings.getFiles().isEmpty()) {
tabbedPane.showNode(new StartPageNode());
tabsController.selectTab(new StartPageNode());
} else {
open(FileUtils.fileNamesToPaths(settings.getFiles()), this::handleSelectClassOption);
}
Expand All @@ -306,7 +314,7 @@ private void handleSelectClassOption() {
NLS.str("error_dialog.title"), JOptionPane.ERROR_MESSAGE);
return;
}
tabbedPane.codeJump(cacheObject.getNodeCache().makeFrom(javaNode));
tabsController.codeJump(cacheObject.getNodeCache().makeFrom(javaNode));
}
}

Expand Down Expand Up @@ -517,7 +525,7 @@ private void openProject(Path path, Runnable onFinish) {

private void loadFiles(Runnable onFinish) {
if (project.getFilePaths().isEmpty()) {
tabbedPane.showNode(new StartPageNode());
tabsController.selectTab(new StartPageNode());
return;
}
AtomicReference<Exception> wrapperException = new AtomicReference<>();
Expand Down Expand Up @@ -562,6 +570,8 @@ private void saveAll() {
private void closeAll() {
notifyLoadListeners(false);
cancelBackgroundJobs();
navController.reset();
tabbedPane.reset();
clearTree();
resetCache();
LogCollector.getInstance().reset();
Expand Down Expand Up @@ -783,7 +793,6 @@ public void initTree() {
}

private void clearTree() {
tabbedPane.reset();
treeRoot = null;
treeModel.setRoot(null);
treeModel.reload();
Expand Down Expand Up @@ -864,15 +873,17 @@ private boolean nodeClickAction(@Nullable Object obj) {
JResource res = (JResource) obj;
ResourceFile resFile = res.getResFile();
if (resFile != null && JResource.isSupportedForView(resFile.getType())) {
return tabbedPane.showNode(res);
tabsController.selectTab(res);
return true;
}
} else if (obj instanceof JNode) {
JNode node = (JNode) obj;
if (node.getRootClass() != null) {
tabbedPane.codeJump(node);
tabsController.codeJump(node);
return true;
}
return tabbedPane.showNode(node);
tabsController.selectTab(node);
return true;
}
} catch (Exception e) {
LOG.error("Content loading error", e);
Expand Down Expand Up @@ -901,12 +912,8 @@ private JNode getJNodeUnderMouse(MouseEvent mouseEvent) {
return null;
}

public void syncWithEditor() {
ContentPanel selectedContentPanel = tabbedPane.getSelectedContentPanel();
if (selectedContentPanel == null) {
return;
}
JNode node = selectedContentPanel.getNode();
// TODO: extract tree component into new class
public void selectNodeInTree(JNode node) {
if (node.getParent() == null && treeRoot != null) {
// node not register in tree
node = treeRoot.searchNode(node);
Expand Down Expand Up @@ -962,7 +969,7 @@ public void goToMainActivity() {
if (mainActivityClass == null) {
throw new JadxRuntimeException("Failed to find main activity class: " + results.getMainActivity());
}
tabbedPane.codeJump(getCacheObject().getNodeCache().makeFrom(mainActivityClass));
tabsController.codeJump(getCacheObject().getNodeCache().makeFrom(mainActivityClass));
} catch (Exception e) {
LOG.error("Main activity not found", e);
JOptionPane.showMessageDialog(MainWindow.this,
Expand Down Expand Up @@ -992,7 +999,7 @@ public void goToApplication() {
if (applicationClass == null) {
throw new JadxRuntimeException("Failed to find application class: " + results.getApplication());
}
tabbedPane.codeJump(getCacheObject().getNodeCache().makeFrom(applicationClass));
tabsController.codeJump(getCacheObject().getNodeCache().makeFrom(applicationClass));
} catch (Exception e) {
LOG.error("Application not found", e);
JOptionPane.showMessageDialog(MainWindow.this,
Expand Down Expand Up @@ -1042,7 +1049,7 @@ private void initMenuAndToolbar() {
alwaysSelectOpened.addActionListener(event -> {
settings.setAlwaysSelectOpened(!settings.isAlwaysSelectOpened());
if (settings.isAlwaysSelectOpened()) {
this.syncWithEditor();
this.editorSyncManager.sync();
}
});

Expand All @@ -1061,7 +1068,7 @@ private void initMenuAndToolbar() {
setQuickTabsVisibility(true);
}

JadxGuiAction syncAction = new JadxGuiAction(ActionModel.SYNC, this::syncWithEditor);
JadxGuiAction syncAction = new JadxGuiAction(ActionModel.SYNC, this.editorSyncManager::sync);
JadxGuiAction textSearchAction = new JadxGuiAction(ActionModel.TEXT_SEARCH, this::textSearch);
JadxGuiAction clsSearchAction = new JadxGuiAction(ActionModel.CLASS_SEARCH,
() -> SearchDialog.search(MainWindow.this, SearchDialog.SearchPreset.CLASS));
Expand All @@ -1085,10 +1092,10 @@ private void initMenuAndToolbar() {
JadxGuiAction showLogAction = new JadxGuiAction(ActionModel.SHOW_LOG,
() -> showLogViewer(LogOptions.current()));
JadxGuiAction aboutAction = new JadxGuiAction(ActionModel.ABOUT, () -> new AboutDialog().setVisible(true));
JadxGuiAction backAction = new JadxGuiAction(ActionModel.BACK, tabbedPane::navBack);
JadxGuiAction backVariantAction = new JadxGuiAction(ActionModel.BACK_V, tabbedPane::navBack);
JadxGuiAction forwardAction = new JadxGuiAction(ActionModel.FORWARD, tabbedPane::navForward);
JadxGuiAction forwardVariantAction = new JadxGuiAction(ActionModel.FORWARD_V, tabbedPane::navForward);
JadxGuiAction backAction = new JadxGuiAction(ActionModel.BACK, navController::navBack);
JadxGuiAction backVariantAction = new JadxGuiAction(ActionModel.BACK_V, navController::navBack);
JadxGuiAction forwardAction = new JadxGuiAction(ActionModel.FORWARD, navController::navForward);
JadxGuiAction forwardVariantAction = new JadxGuiAction(ActionModel.FORWARD_V, navController::navForward);
JadxGuiAction quarkAction = new JadxGuiAction(ActionModel.QUARK,
() -> new QuarkDialog(MainWindow.this).setVisible(true));
JadxGuiAction openDeviceAction = new JadxGuiAction(ActionModel.OPEN_DEVICE,
Expand Down Expand Up @@ -1345,7 +1352,6 @@ public void treeWillCollapse(TreeExpansionEvent event) {
leftPane.add(bottomPane, BorderLayout.PAGE_END);
treeSplitPane.setLeftComponent(leftPane);

tabsController = new TabsController(this);
tabbedPane = new TabbedPane(this, tabsController);
tabbedPane.setMinimumSize(new Dimension(150, 150));
new TabDndController(tabbedPane, settings);
Expand Down Expand Up @@ -1581,6 +1587,10 @@ public TabsController getTabsController() {
return tabsController;
}

public NavigationController getNavController() {
return navController;
}

public JadxSettings getSettings() {
return settings;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public AbstractCodeArea(ContentPanel contentPanel, JNode node) {
applyEditableProperties(node);
loadSettings();

JadxSettings settings = contentPanel.getTabbedPane().getMainWindow().getSettings();
JadxSettings settings = contentPanel.getMainWindow().getSettings();
setLineWrap(settings.isCodeAreaLineWrap());

ZoomActions.register(this, settings, this::loadSettings);
Expand Down Expand Up @@ -147,7 +147,7 @@ protected void appendFoldingMenu(JPopupMenu popup) {
}

private void appendWrapLineMenu(JPopupMenu popupMenu) {
JadxSettings settings = contentPanel.getTabbedPane().getMainWindow().getSettings();
JadxSettings settings = contentPanel.getMainWindow().getSettings();
popupMenu.addSeparator();
JCheckBoxMenuItem wrapItem = new JCheckBoxMenuItem(NLS.str("popup.line_wrap"), getLineWrap());
wrapItem.setAction(new AbstractAction(NLS.str("popup.line_wrap")) {
Expand Down Expand Up @@ -378,7 +378,7 @@ public static void loadCommonSettings(MainWindow mainWindow, RSyntaxTextArea are
}

public void loadSettings() {
loadCommonSettings(contentPanel.getTabbedPane().getMainWindow(), this);
loadCommonSettings(contentPanel.getMainWindow(), this);
}

public void scrollToPos(int pos) {
Expand Down
4 changes: 2 additions & 2 deletions jadx-gui/src/main/java/jadx/gui/ui/codearea/CodeArea.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ private void navToDecl(Point point) {
int offs = viewToModel2D(point);
JNode node = getJNodeAtOffset(adjustOffsetForWordToken(offs));
if (node != null) {
contentPanel.getTabbedPane().codeJump(node);
contentPanel.getTabsController().codeJump(node);
}
}

Expand Down Expand Up @@ -332,7 +332,7 @@ public void refreshClass() {
}

public MainWindow getMainWindow() {
return contentPanel.getTabbedPane().getMainWindow();
return contentPanel.getMainWindow();
}

public JadxWrapper getJadxWrapper() {
Expand Down
2 changes: 1 addition & 1 deletion jadx-gui/src/main/java/jadx/gui/ui/codearea/CodePanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public void actionPerformed(ActionEvent e) {
AbstractAction globalSearchAction = new AbstractAction(NLS.str("popup.search_global", "")) {
@Override
public void actionPerformed(ActionEvent e) {
MainWindow mainWindow = codeArea.getContentPanel().getTabbedPane().getMainWindow();
MainWindow mainWindow = codeArea.getContentPanel().getMainWindow();
SearchDialog.searchText(mainWindow, codeArea.getSelectedText());
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ public GoToDeclarationAction(CodeArea codeArea) {

@Override
public void runAction(JNode node) {
getCodeArea().getContentPanel().getTabbedPane().codeJump(node);
getCodeArea().getContentPanel().getTabsController().codeJump(node);
}
}
4 changes: 2 additions & 2 deletions jadx-gui/src/main/java/jadx/gui/ui/codearea/HexArea.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,10 @@ public void loadSettings() {
}

private void applyTheme() {
Font font = getContentPanel().getTabbedPane().getMainWindow().getSettings().getSmaliFont();
Font font = getContentPanel().getMainWindow().getSettings().getSmaliFont();
setFont(font);

Theme theme = contentPanel.getTabbedPane().getMainWindow().getEditorTheme();
Theme theme = contentPanel.getMainWindow().getEditorTheme();
if (hexPreviewPanel != null) {
hexPreviewPanel.applyTheme(theme, font);
}
Expand Down
Loading