gui: support images view/unpack
This commit is contained in:
@@ -81,7 +81,7 @@ public class JResource extends JNode implements Comparable<JResource> {
|
||||
if (!loaded && resFile != null && type == JResType.FILE) {
|
||||
loaded = true;
|
||||
if (isSupportedForView(resFile.getType())) {
|
||||
ResContainer rc = resFile.getContent();
|
||||
ResContainer rc = resFile.loadContent();
|
||||
if (rc != null) {
|
||||
addSubFiles(rc, this, 0);
|
||||
}
|
||||
@@ -149,9 +149,13 @@ public class JResource extends JNode implements Comparable<JResource> {
|
||||
|
||||
@Override
|
||||
public String getSyntaxName() {
|
||||
if (resFile == null) {
|
||||
return null;
|
||||
}
|
||||
switch (resFile.getType()) {
|
||||
case CODE:
|
||||
return super.getSyntaxName();
|
||||
|
||||
case MANIFEST:
|
||||
case XML:
|
||||
return SyntaxConstants.SYNTAX_STYLE_XML;
|
||||
@@ -205,23 +209,27 @@ public class JResource extends JNode implements Comparable<JResource> {
|
||||
return FILE_ICON;
|
||||
}
|
||||
|
||||
private boolean isSupportedForView(ResourceType type) {
|
||||
public static boolean isSupportedForView(ResourceType type) {
|
||||
switch (type) {
|
||||
case CODE:
|
||||
case FONT:
|
||||
case IMG:
|
||||
case LIB:
|
||||
return false;
|
||||
|
||||
case MANIFEST:
|
||||
case XML:
|
||||
case ARSC:
|
||||
case IMG:
|
||||
case UNKNOWN:
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public ResourceFile getResFile() {
|
||||
return resFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JClass getJParent() {
|
||||
return null;
|
||||
|
||||
@@ -52,7 +52,11 @@ public class JRoot extends JNode {
|
||||
String name = parts[i];
|
||||
JResource subRF = getResourceByName(curRf, name);
|
||||
if (subRF == null) {
|
||||
subRF = new JResource(rf, name, i != count - 1 ? JResType.DIR : JResType.FILE);
|
||||
if (i != count - 1) {
|
||||
subRF = new JResource(null, name, JResType.DIR);
|
||||
} else {
|
||||
subRF = new JResource(rf, name, JResType.FILE);
|
||||
}
|
||||
curRf.getFiles().add(subRF);
|
||||
}
|
||||
curRf = subRF;
|
||||
|
||||
+12
-12
@@ -34,18 +34,18 @@ import org.fife.ui.rsyntaxtextarea.TokenTypes;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
class ContentArea extends RSyntaxTextArea {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ContentArea.class);
|
||||
class CodeArea extends RSyntaxTextArea {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(CodeArea.class);
|
||||
|
||||
private static final long serialVersionUID = 6312736869579635796L;
|
||||
|
||||
public static final Color BACKGROUND = new Color(0xFAFAFA);
|
||||
public static final Color JUMP_TOKEN_FGD = new Color(0x491BA1);
|
||||
|
||||
private final ContentPanel contentPanel;
|
||||
private final CodePanel contentPanel;
|
||||
private final JNode node;
|
||||
|
||||
ContentArea(ContentPanel panel) {
|
||||
CodeArea(CodePanel panel) {
|
||||
this.contentPanel = panel;
|
||||
this.node = panel.getNode();
|
||||
|
||||
@@ -76,8 +76,8 @@ class ContentArea extends RSyntaxTextArea {
|
||||
setText(node.getContent());
|
||||
}
|
||||
|
||||
private void addMenuItems(ContentArea contentArea, JClass jCls) {
|
||||
Action findUsage = new FindUsageAction(contentArea, jCls);
|
||||
private void addMenuItems(CodeArea codeArea, JClass jCls) {
|
||||
Action findUsage = new FindUsageAction(codeArea, jCls);
|
||||
// TODO: hotkey works only when popup menu is shown
|
||||
// findUsage.putValue(Action.ACCELERATOR_KEY, getKeyStroke(KeyEvent.VK_F7, KeyEvent.ALT_DOWN_MASK));
|
||||
|
||||
@@ -197,14 +197,14 @@ class ContentArea extends RSyntaxTextArea {
|
||||
private class FindUsageAction extends AbstractAction implements PopupMenuListener {
|
||||
private static final long serialVersionUID = 4692546569977976384L;
|
||||
|
||||
private final ContentArea contentArea;
|
||||
private final CodeArea codeArea;
|
||||
private final JClass jCls;
|
||||
|
||||
private JavaNode node;
|
||||
|
||||
public FindUsageAction(ContentArea contentArea, JClass jCls) {
|
||||
public FindUsageAction(CodeArea codeArea, JClass jCls) {
|
||||
super("Find Usage");
|
||||
this.contentArea = contentArea;
|
||||
this.codeArea = codeArea;
|
||||
this.jCls = jCls;
|
||||
}
|
||||
|
||||
@@ -222,11 +222,11 @@ class ContentArea extends RSyntaxTextArea {
|
||||
@Override
|
||||
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
|
||||
node = null;
|
||||
Point pos = contentArea.getMousePosition();
|
||||
Point pos = codeArea.getMousePosition();
|
||||
if (pos != null) {
|
||||
Token token = contentArea.viewToToken(pos);
|
||||
Token token = codeArea.viewToToken(pos);
|
||||
if (token != null) {
|
||||
node = getJavaNodeAtOffset(jCls, contentArea, token.getOffset());
|
||||
node = getJavaNodeAtOffset(jCls, codeArea, token.getOffset());
|
||||
}
|
||||
}
|
||||
setEnabled(node != null);
|
||||
@@ -0,0 +1,72 @@
|
||||
package jadx.gui.ui;
|
||||
|
||||
import jadx.gui.treemodel.JNode;
|
||||
import jadx.gui.utils.Utils;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.KeyStroke;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
class CodePanel extends ContentPanel {
|
||||
|
||||
private static final long serialVersionUID = 5310536092010045565L;
|
||||
|
||||
private final SearchBar searchBar;
|
||||
private final CodeArea codeArea;
|
||||
private final JScrollPane scrollPane;
|
||||
|
||||
CodePanel(TabbedPane panel, JNode jnode) {
|
||||
super(panel, jnode);
|
||||
|
||||
codeArea = new CodeArea(this);
|
||||
searchBar = new SearchBar(codeArea);
|
||||
|
||||
scrollPane = new JScrollPane(codeArea);
|
||||
scrollPane.setRowHeaderView(new LineNumbers(codeArea));
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
add(searchBar, BorderLayout.NORTH);
|
||||
add(scrollPane);
|
||||
|
||||
KeyStroke key = KeyStroke.getKeyStroke(KeyEvent.VK_F, InputEvent.CTRL_MASK);
|
||||
Utils.addKeyBinding(codeArea, key, "SearchAction", new SearchAction());
|
||||
}
|
||||
|
||||
private class SearchAction extends AbstractAction {
|
||||
private static final long serialVersionUID = 8650568214755387093L;
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
searchBar.toggle();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings() {
|
||||
codeArea.loadSettings();
|
||||
}
|
||||
|
||||
TabbedPane getTabbedPane() {
|
||||
return tabbedPane;
|
||||
}
|
||||
|
||||
JNode getNode() {
|
||||
return node;
|
||||
}
|
||||
|
||||
SearchBar getSearchBar() {
|
||||
return searchBar;
|
||||
}
|
||||
|
||||
CodeArea getCodeArea() {
|
||||
return codeArea;
|
||||
}
|
||||
|
||||
JScrollPane getScrollPane() {
|
||||
return scrollPane;
|
||||
}
|
||||
}
|
||||
@@ -162,7 +162,7 @@ public abstract class CommonSearchDialog extends JDialog {
|
||||
resultsTable.setShowHorizontalLines(false);
|
||||
resultsTable.setDragEnabled(false);
|
||||
resultsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
resultsTable.setBackground(ContentArea.BACKGROUND);
|
||||
resultsTable.setBackground(CodeArea.BACKGROUND);
|
||||
resultsTable.setColumnSelectionAllowed(false);
|
||||
resultsTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
|
||||
resultsTable.setAutoscrolls(false);
|
||||
@@ -352,7 +352,7 @@ public abstract class CommonSearchDialog extends JDialog {
|
||||
comp.setBackground(selectedBackground);
|
||||
comp.setForeground(selectedForeground);
|
||||
} else {
|
||||
comp.setBackground(ContentArea.BACKGROUND);
|
||||
comp.setBackground(CodeArea.BACKGROUND);
|
||||
comp.setForeground(foreground);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,52 +1,20 @@
|
||||
package jadx.gui.ui;
|
||||
|
||||
import jadx.gui.treemodel.JNode;
|
||||
import jadx.gui.utils.Utils;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.KeyStroke;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
class ContentPanel extends JPanel {
|
||||
abstract class ContentPanel extends JPanel {
|
||||
|
||||
private static final long serialVersionUID = 5310536092010045565L;
|
||||
protected final TabbedPane tabbedPane;
|
||||
protected final JNode node;
|
||||
|
||||
private final TabbedPane tabbedPane;
|
||||
private final JNode node;
|
||||
private final SearchBar searchBar;
|
||||
private final ContentArea contentArea;
|
||||
private final JScrollPane scrollPane;
|
||||
|
||||
ContentPanel(TabbedPane panel, JNode node) {
|
||||
ContentPanel(TabbedPane panel, JNode jnode) {
|
||||
tabbedPane = panel;
|
||||
this.node = node;
|
||||
contentArea = new ContentArea(this);
|
||||
searchBar = new SearchBar(contentArea);
|
||||
|
||||
scrollPane = new JScrollPane(contentArea);
|
||||
scrollPane.setRowHeaderView(new LineNumbers(contentArea));
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
add(searchBar, BorderLayout.NORTH);
|
||||
add(scrollPane);
|
||||
|
||||
KeyStroke key = KeyStroke.getKeyStroke(KeyEvent.VK_F, InputEvent.CTRL_MASK);
|
||||
Utils.addKeyBinding(contentArea, key, "SearchAction", new SearchAction());
|
||||
node = jnode;
|
||||
}
|
||||
|
||||
private class SearchAction extends AbstractAction {
|
||||
private static final long serialVersionUID = 8650568214755387093L;
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
searchBar.toggle();
|
||||
}
|
||||
}
|
||||
public abstract void loadSettings();
|
||||
|
||||
TabbedPane getTabbedPane() {
|
||||
return tabbedPane;
|
||||
@@ -55,16 +23,4 @@ class ContentPanel extends JPanel {
|
||||
JNode getNode() {
|
||||
return node;
|
||||
}
|
||||
|
||||
SearchBar getSearchBar() {
|
||||
return searchBar;
|
||||
}
|
||||
|
||||
ContentArea getContentArea() {
|
||||
return contentArea;
|
||||
}
|
||||
|
||||
JScrollPane getScrollPane() {
|
||||
return scrollPane;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package jadx.gui.ui;
|
||||
|
||||
import hu.kazocsaba.imageviewer.ImageViewer;
|
||||
import jadx.api.ResourceFile;
|
||||
import jadx.gui.treemodel.JResource;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
public class ImagePanel extends ContentPanel {
|
||||
|
||||
ImagePanel(TabbedPane panel, JResource res) {
|
||||
super(panel, res);
|
||||
|
||||
ResourceFile resFile = res.getResFile();
|
||||
BufferedImage img = resFile.loadContent().getImage();
|
||||
ImageViewer imageViewer = new ImageViewer(img);
|
||||
imageViewer.setZoomFactor(2.);
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
add(imageViewer.getComponent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings() {
|
||||
}
|
||||
}
|
||||
@@ -32,18 +32,18 @@ public class LineNumbers extends JPanel implements CaretListener {
|
||||
|
||||
private static final int HEIGHT = Integer.MAX_VALUE - 1000000;
|
||||
private static final Color FOREGROUND = Color.GRAY;
|
||||
private static final Color BACKGROUND = ContentArea.BACKGROUND;
|
||||
private static final Color BACKGROUND = CodeArea.BACKGROUND;
|
||||
private static final Color CURRENT_LINE_FOREGROUND = new Color(227, 0, 0);
|
||||
|
||||
private ContentArea contentArea;
|
||||
private CodeArea codeArea;
|
||||
private boolean useSourceLines = true;
|
||||
|
||||
private int lastDigits;
|
||||
private int lastLine;
|
||||
private Map<String, FontMetrics> fonts;
|
||||
|
||||
public LineNumbers(ContentArea component) {
|
||||
this.contentArea = component;
|
||||
public LineNumbers(CodeArea component) {
|
||||
this.codeArea = component;
|
||||
setFont(component.getFont());
|
||||
setBackground(BACKGROUND);
|
||||
setForeground(FOREGROUND);
|
||||
@@ -70,7 +70,7 @@ public class LineNumbers extends JPanel implements CaretListener {
|
||||
}
|
||||
|
||||
private void setPreferredWidth() {
|
||||
Element root = contentArea.getDocument().getDefaultRootElement();
|
||||
Element root = codeArea.getDocument().getDefaultRootElement();
|
||||
int lines = root.getElementCount();
|
||||
int digits = Math.max(String.valueOf(lines).length(), 3);
|
||||
if (lastDigits != digits) {
|
||||
@@ -92,12 +92,12 @@ public class LineNumbers extends JPanel implements CaretListener {
|
||||
@Override
|
||||
public void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
FontMetrics fontMetrics = contentArea.getFontMetrics(contentArea.getFont());
|
||||
FontMetrics fontMetrics = codeArea.getFontMetrics(codeArea.getFont());
|
||||
Insets insets = getInsets();
|
||||
int availableWidth = getSize().width - insets.left - insets.right;
|
||||
Rectangle clip = g.getClipBounds();
|
||||
int rowStartOffset = contentArea.viewToModel(new Point(0, clip.y));
|
||||
int endOffset = contentArea.viewToModel(new Point(0, clip.y + clip.height));
|
||||
int rowStartOffset = codeArea.viewToModel(new Point(0, clip.y));
|
||||
int endOffset = codeArea.viewToModel(new Point(0, clip.y + clip.height));
|
||||
|
||||
while (rowStartOffset <= endOffset) {
|
||||
try {
|
||||
@@ -111,7 +111,7 @@ public class LineNumbers extends JPanel implements CaretListener {
|
||||
int x = availableWidth - stringWidth + insets.left;
|
||||
int y = getOffsetY(rowStartOffset, fontMetrics);
|
||||
g.drawString(lineNumber, x, y);
|
||||
rowStartOffset = Utilities.getRowEnd(contentArea, rowStartOffset) + 1;
|
||||
rowStartOffset = Utilities.getRowEnd(codeArea, rowStartOffset) + 1;
|
||||
} catch (Exception e) {
|
||||
break;
|
||||
}
|
||||
@@ -119,19 +119,19 @@ public class LineNumbers extends JPanel implements CaretListener {
|
||||
}
|
||||
|
||||
private boolean isCurrentLine(int rowStartOffset) {
|
||||
int caretPosition = contentArea.getCaretPosition();
|
||||
Element root = contentArea.getDocument().getDefaultRootElement();
|
||||
int caretPosition = codeArea.getCaretPosition();
|
||||
Element root = codeArea.getDocument().getDefaultRootElement();
|
||||
return root.getElementIndex(rowStartOffset) == root.getElementIndex(caretPosition);
|
||||
}
|
||||
|
||||
protected String getTextLineNumber(int rowStartOffset) {
|
||||
Element root = contentArea.getDocument().getDefaultRootElement();
|
||||
Element root = codeArea.getDocument().getDefaultRootElement();
|
||||
int index = root.getElementIndex(rowStartOffset);
|
||||
Element line = root.getElement(index);
|
||||
if (line.getStartOffset() == rowStartOffset) {
|
||||
int lineNumber = index + 1;
|
||||
if (useSourceLines) {
|
||||
Integer sourceLine = contentArea.getSourceLine(lineNumber);
|
||||
Integer sourceLine = codeArea.getSourceLine(lineNumber);
|
||||
if (sourceLine != null) {
|
||||
return String.valueOf(sourceLine);
|
||||
}
|
||||
@@ -143,7 +143,7 @@ public class LineNumbers extends JPanel implements CaretListener {
|
||||
}
|
||||
|
||||
private int getOffsetY(int rowStartOffset, FontMetrics fontMetrics) throws BadLocationException {
|
||||
Rectangle r = contentArea.modelToView(rowStartOffset);
|
||||
Rectangle r = codeArea.modelToView(rowStartOffset);
|
||||
if (r == null) {
|
||||
throw new BadLocationException("Can't get Y offset", rowStartOffset);
|
||||
}
|
||||
@@ -156,7 +156,7 @@ public class LineNumbers extends JPanel implements CaretListener {
|
||||
if (fonts == null) {
|
||||
fonts = new HashMap<String, FontMetrics>();
|
||||
}
|
||||
Element root = contentArea.getDocument().getDefaultRootElement();
|
||||
Element root = codeArea.getDocument().getDefaultRootElement();
|
||||
int index = root.getElementIndex(rowStartOffset);
|
||||
Element line = root.getElement(index);
|
||||
for (int i = 0; i < line.getElementCount(); i++) {
|
||||
@@ -168,7 +168,7 @@ public class LineNumbers extends JPanel implements CaretListener {
|
||||
FontMetrics fm = fonts.get(key);
|
||||
if (fm == null) {
|
||||
Font font = new Font(fontFamily, Font.PLAIN, fontSize);
|
||||
fm = contentArea.getFontMetrics(font);
|
||||
fm = codeArea.getFontMetrics(font);
|
||||
fonts.put(key, fm);
|
||||
}
|
||||
descent = Math.max(descent, fm.getDescent());
|
||||
@@ -179,8 +179,8 @@ public class LineNumbers extends JPanel implements CaretListener {
|
||||
|
||||
@Override
|
||||
public void caretUpdate(CaretEvent e) {
|
||||
int caretPosition = contentArea.getCaretPosition();
|
||||
Element root = contentArea.getDocument().getDefaultRootElement();
|
||||
int caretPosition = codeArea.getCaretPosition();
|
||||
Element root = codeArea.getDocument().getDefaultRootElement();
|
||||
int currentLine = root.getElementIndex(caretPosition);
|
||||
if (lastLine != currentLine) {
|
||||
repaint();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package jadx.gui.ui;
|
||||
|
||||
import jadx.api.ResourceFile;
|
||||
import jadx.gui.JadxWrapper;
|
||||
import jadx.gui.jobs.BackgroundWorker;
|
||||
import jadx.gui.jobs.DecompileJob;
|
||||
@@ -139,7 +140,7 @@ public class MainWindow extends JFrame {
|
||||
setLocationAndPosition();
|
||||
setVisible(true);
|
||||
setLocationRelativeTo(null);
|
||||
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
|
||||
|
||||
if (settings.getInput().isEmpty()) {
|
||||
openFile();
|
||||
@@ -169,7 +170,7 @@ public class MainWindow extends JFrame {
|
||||
public void openFile() {
|
||||
JFileChooser fileChooser = new JFileChooser();
|
||||
fileChooser.setAcceptAllFileFilterUsed(true);
|
||||
String[] exts = {"apk", "dex", "jar", "class", "zip"};
|
||||
String[] exts = {"apk", "dex", "jar", "class", "zip", "aar"};
|
||||
String description = "supported files: " + Arrays.toString(exts).replace('[', '(').replace(']', ')');
|
||||
fileChooser.setFileFilter(new FileNameExtensionFilter(description, exts));
|
||||
fileChooser.setToolTipText(NLS.str("file.open"));
|
||||
@@ -245,7 +246,7 @@ public class MainWindow extends JFrame {
|
||||
if (ret == JFileChooser.APPROVE_OPTION) {
|
||||
settings.setLastSaveFilePath(fileChooser.getCurrentDirectory().getPath());
|
||||
ProgressMonitor progressMonitor = new ProgressMonitor(mainPanel, NLS.str("msg.saving_sources"), "", 0, 100);
|
||||
progressMonitor.setMillisToPopup(500);
|
||||
progressMonitor.setMillisToPopup(0);
|
||||
wrapper.saveAll(fileChooser.getSelectedFile(), progressMonitor);
|
||||
}
|
||||
}
|
||||
@@ -296,11 +297,11 @@ public class MainWindow extends JFrame {
|
||||
Object obj = tree.getLastSelectedPathComponent();
|
||||
if (obj instanceof JResource) {
|
||||
JResource res = (JResource) obj;
|
||||
if (res.getContent() != null) {
|
||||
tabbedPane.codeJump(new Position(res, res.getLine()));
|
||||
ResourceFile resFile = res.getResFile();
|
||||
if (resFile != null && JResource.isSupportedForView(resFile.getType())) {
|
||||
tabbedPane.showResource(res);
|
||||
}
|
||||
}
|
||||
if (obj instanceof JNode) {
|
||||
} else if (obj instanceof JNode) {
|
||||
JNode node = (JNode) obj;
|
||||
JClass cls = node.getRootClass();
|
||||
if (cls != null) {
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package jadx.gui.ui;
|
||||
|
||||
import jadx.api.ResourceFile;
|
||||
import jadx.api.ResourceType;
|
||||
import jadx.gui.treemodel.JNode;
|
||||
import jadx.gui.treemodel.JResource;
|
||||
import jadx.gui.utils.JumpManager;
|
||||
import jadx.gui.utils.NLS;
|
||||
import jadx.gui.utils.Position;
|
||||
@@ -72,23 +75,39 @@ class TabbedPane extends JTabbedPane {
|
||||
}
|
||||
|
||||
private void showCode(final Position pos) {
|
||||
final ContentPanel contentPanel = getCodePanel(pos.getNode());
|
||||
final CodePanel contentPanel = (CodePanel) getContentPanel(pos.getNode());
|
||||
if (contentPanel == null) {
|
||||
return;
|
||||
}
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
setSelectedComponent(contentPanel);
|
||||
ContentArea contentArea = contentPanel.getContentArea();
|
||||
CodeArea codeArea = contentPanel.getCodeArea();
|
||||
int line = pos.getLine();
|
||||
if (line < 0) {
|
||||
try {
|
||||
line = 1 + contentArea.getLineOfOffset(-line);
|
||||
line = 1 + codeArea.getLineOfOffset(-line);
|
||||
} catch (BadLocationException e) {
|
||||
LOG.error("Can't get line for: {}", pos, e);
|
||||
line = pos.getNode().getLine();
|
||||
}
|
||||
}
|
||||
contentArea.scrollToLine(line);
|
||||
contentArea.requestFocus();
|
||||
codeArea.scrollToLine(line);
|
||||
codeArea.requestFocus();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void showResource(JResource res) {
|
||||
final ContentPanel contentPanel = getContentPanel(res);
|
||||
if (contentPanel == null) {
|
||||
return;
|
||||
}
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
setSelectedComponent(contentPanel);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -105,10 +124,10 @@ class TabbedPane extends JTabbedPane {
|
||||
@Nullable
|
||||
private Position getCurrentPosition() {
|
||||
ContentPanel selectedCodePanel = getSelectedCodePanel();
|
||||
if (selectedCodePanel == null) {
|
||||
return null;
|
||||
if (selectedCodePanel instanceof CodePanel) {
|
||||
return ((CodePanel) selectedCodePanel).getCodeArea().getCurrentPosition();
|
||||
}
|
||||
return selectedCodePanel.getContentArea().getCurrentPosition();
|
||||
return null;
|
||||
}
|
||||
|
||||
public void navBack() {
|
||||
@@ -125,11 +144,7 @@ class TabbedPane extends JTabbedPane {
|
||||
}
|
||||
}
|
||||
|
||||
public JumpManager getJumpManager() {
|
||||
return jumps;
|
||||
}
|
||||
|
||||
private void addCodePanel(ContentPanel contentPanel) {
|
||||
private void addContentPanel(ContentPanel contentPanel) {
|
||||
openTabs.put(contentPanel.getNode(), contentPanel);
|
||||
add(contentPanel);
|
||||
}
|
||||
@@ -139,16 +154,36 @@ class TabbedPane extends JTabbedPane {
|
||||
remove(contentPanel);
|
||||
}
|
||||
|
||||
private ContentPanel getCodePanel(JNode cls) {
|
||||
ContentPanel panel = openTabs.get(cls);
|
||||
@Nullable
|
||||
private ContentPanel getContentPanel(JNode node) {
|
||||
ContentPanel panel = openTabs.get(node);
|
||||
if (panel == null) {
|
||||
panel = new ContentPanel(this, cls);
|
||||
addCodePanel(panel);
|
||||
panel = makeContentPanel(node);
|
||||
if (panel == null) {
|
||||
return null;
|
||||
}
|
||||
addContentPanel(panel);
|
||||
setTabComponentAt(indexOfComponent(panel), makeTabComponent(panel));
|
||||
}
|
||||
return panel;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ContentPanel makeContentPanel(JNode node) {
|
||||
if (node instanceof JResource) {
|
||||
JResource res = (JResource) node;
|
||||
ResourceFile resFile = res.getResFile();
|
||||
if (resFile != null) {
|
||||
if (resFile.getType() == ResourceType.IMG) {
|
||||
return new ImagePanel(this, res);
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return new CodePanel(this, node);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
ContentPanel getSelectedCodePanel() {
|
||||
return (ContentPanel) getSelectedComponent();
|
||||
@@ -271,7 +306,7 @@ class TabbedPane extends JTabbedPane {
|
||||
|
||||
public void loadSettings() {
|
||||
for (ContentPanel panel : openTabs.values()) {
|
||||
panel.getContentArea().loadSettings();
|
||||
panel.loadSettings();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user