fix: workaround for link clicks in RSyntaxTextArea (#929)
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
package jadx.gui.ui.codearea;
|
||||
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import org.fife.ui.rsyntaxtextarea.RSyntaxDocument;
|
||||
@@ -38,9 +42,21 @@ public final class CodeArea extends AbstractCodeArea {
|
||||
}
|
||||
|
||||
setHyperlinksEnabled(true);
|
||||
CodeLinkGenerator codeLinkProcessor = new CodeLinkGenerator(this);
|
||||
setLinkGenerator(codeLinkProcessor);
|
||||
addHyperlinkListener(codeLinkProcessor);
|
||||
setLinkScanningMask(InputEvent.CTRL_DOWN_MASK);
|
||||
CodeLinkGenerator codeLinkGenerator = new CodeLinkGenerator(this);
|
||||
setLinkGenerator(codeLinkGenerator);
|
||||
addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (e.isControlDown()) {
|
||||
int offs = viewToModel(e.getPoint());
|
||||
JumpPosition jump = codeLinkGenerator.getJumpLinkAtOffset(CodeArea.this, offs);
|
||||
if (jump != null) {
|
||||
contentPanel.getTabbedPane().codeJump(jump);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -3,52 +3,61 @@ package jadx.gui.ui.codearea;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.swing.event.HyperlinkEvent;
|
||||
import javax.swing.event.HyperlinkListener;
|
||||
import javax.swing.text.BadLocationException;
|
||||
|
||||
import org.fife.ui.rsyntaxtextarea.LinkGenerator;
|
||||
import org.fife.ui.rsyntaxtextarea.LinkGeneratorResult;
|
||||
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
|
||||
import org.fife.ui.rsyntaxtextarea.Token;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import jadx.gui.treemodel.JNode;
|
||||
import jadx.gui.ui.ContentPanel;
|
||||
import jadx.gui.utils.JumpPosition;
|
||||
|
||||
public class CodeLinkGenerator implements LinkGenerator, HyperlinkListener {
|
||||
public class CodeLinkGenerator implements LinkGenerator {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(CodeLinkGenerator.class);
|
||||
|
||||
private final ContentPanel contentPanel;
|
||||
private final CodeArea codeArea;
|
||||
private final JNode jNode;
|
||||
|
||||
public CodeLinkGenerator(CodeArea codeArea) {
|
||||
this.contentPanel = codeArea.getContentPanel();
|
||||
this.codeArea = codeArea;
|
||||
this.jNode = codeArea.getNode();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JumpPosition getJumpLinkAtOffset(RSyntaxTextArea textArea, int offset) {
|
||||
try {
|
||||
if (jNode.getCodeInfo() == null) {
|
||||
return null;
|
||||
}
|
||||
int sourceOffset = getLinkSourceOffset(textArea, offset);
|
||||
if (sourceOffset == -1) {
|
||||
return null;
|
||||
}
|
||||
return getJumpBySourceOffset(textArea, sourceOffset);
|
||||
} catch (Exception e) {
|
||||
LOG.error("getJumpLinkAtOffset error", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public LinkGeneratorResult isLinkAtOffset(RSyntaxTextArea textArea, int offset) {
|
||||
try {
|
||||
if (jNode.getCodeInfo() == null) {
|
||||
return null;
|
||||
}
|
||||
Token token = textArea.modelToToken(offset);
|
||||
int sourceOffset = codeArea.adjustOffsetForToken(token);
|
||||
int sourceOffset = getLinkSourceOffset(textArea, offset);
|
||||
if (sourceOffset == -1) {
|
||||
return null;
|
||||
}
|
||||
final JumpPosition defPos = codeArea.getDefPosForNodeAtOffset(sourceOffset);
|
||||
JumpPosition defPos = getJumpBySourceOffset(textArea, sourceOffset);
|
||||
if (defPos == null) {
|
||||
return null;
|
||||
}
|
||||
if (Objects.equals(defPos.getNode().getRootClass(), jNode)
|
||||
&& defPos.getLine() == textArea.getLineOfOffset(sourceOffset) + 1) {
|
||||
// ignore self jump
|
||||
return null;
|
||||
}
|
||||
return new LinkGeneratorResult() {
|
||||
@Override
|
||||
public HyperlinkEvent execute() {
|
||||
@@ -67,11 +76,22 @@ public class CodeLinkGenerator implements LinkGenerator, HyperlinkListener {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hyperlinkUpdate(HyperlinkEvent e) {
|
||||
Object obj = e.getSource();
|
||||
if (obj instanceof JumpPosition) {
|
||||
contentPanel.getTabbedPane().codeJump((JumpPosition) obj);
|
||||
private int getLinkSourceOffset(RSyntaxTextArea textArea, int offset) {
|
||||
Token token = textArea.modelToToken(offset);
|
||||
return codeArea.adjustOffsetForToken(token);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private JumpPosition getJumpBySourceOffset(RSyntaxTextArea textArea, int sourceOffset) throws BadLocationException {
|
||||
final JumpPosition defPos = codeArea.getDefPosForNodeAtOffset(sourceOffset);
|
||||
if (defPos == null) {
|
||||
return null;
|
||||
}
|
||||
if (Objects.equals(defPos.getNode().getRootClass(), jNode)
|
||||
&& defPos.getLine() == textArea.getLineOfOffset(sourceOffset) + 1) {
|
||||
// ignore self jump
|
||||
return null;
|
||||
}
|
||||
return defPos;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user