/*
* Copyright (C) 2023-2025 JPEXS
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
package com.jpexs.decompiler.flash.gui.abc;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewFunctionIns;
import com.jpexs.decompiler.flash.abc.types.ABCException;
import com.jpexs.decompiler.flash.abc.types.ClassInfo;
import com.jpexs.decompiler.flash.abc.types.Float4;
import com.jpexs.decompiler.flash.abc.types.InstanceInfo;
import com.jpexs.decompiler.flash.abc.types.MetadataInfo;
import com.jpexs.decompiler.flash.abc.types.MethodBody;
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
import com.jpexs.decompiler.flash.abc.types.Multiname;
import com.jpexs.decompiler.flash.abc.types.Namespace;
import com.jpexs.decompiler.flash.abc.types.NamespaceSet;
import com.jpexs.decompiler.flash.abc.types.ScriptInfo;
import com.jpexs.decompiler.flash.abc.types.ValueKind;
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
import com.jpexs.decompiler.flash.abc.types.traits.TraitClass;
import com.jpexs.decompiler.flash.abc.types.traits.TraitFunction;
import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter;
import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst;
import com.jpexs.decompiler.flash.abc.types.traits.Traits;
import com.jpexs.decompiler.flash.abc.usages.simple.ABCCleaner;
import com.jpexs.decompiler.flash.abc.usages.simple.ABCSimpleUsageDetector;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.gui.AppDialog;
import com.jpexs.decompiler.flash.gui.AppStrings;
import com.jpexs.decompiler.flash.gui.FasterScrollPane;
import com.jpexs.decompiler.flash.gui.Main;
import com.jpexs.decompiler.flash.gui.MainPanel;
import com.jpexs.decompiler.flash.gui.View;
import com.jpexs.decompiler.flash.gui.ViewMessages;
import com.jpexs.decompiler.flash.helpers.CodeFormatting;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.flash.helpers.StringBuilderTextWriter;
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
import com.jpexs.decompiler.flash.tags.DoABC2Tag;
import com.jpexs.decompiler.flash.tags.ShowFrameTag;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.treeitems.Openable;
import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.helpers.Helper;
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Queue;
import java.util.Set;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.ImageIcon;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JRootPane;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTree;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.event.TreeModelListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.plaf.basic.BasicLabelUI;
import javax.swing.plaf.basic.BasicTreeUI;
import javax.swing.table.DefaultTableModel;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
/**
* @author JPEXS
*/
public class ABCExplorerDialog extends AppDialog {
private final List abcs = new ArrayList<>();
private JComboBox abcComboBox = null;
private final JLabel tagInfoLabel;
private final List abcFrames = new ArrayList<>();
private final JTabbedPane mainTabbedPane;
private final JTabbedPane cpTabbedPane;
private MainPanel mainPanel;
private Runnable packListener;
private ABCSimpleUsageDetector usageDetector = null;
private JButton cleanButton = new JButton(View.getIcon("clean16"));
private JTable usagesTable = new JTable(new DefaultTableModel()) {
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
};
public ABCExplorerDialog(Window owner, MainPanel mainPanel, Openable openable, ABC abc) {
super(owner);
this.mainPanel = mainPanel;
Container cnt = getContentPane();
cnt.setLayout(new BorderLayout());
JPanel topLeftPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
topLeftPanel.add(new JLabel(translate("abc")));
int selectedIndex = 0;
int frame = 1;
if (openable instanceof SWF) {
SWF swf = (SWF) openable;
List abcContainers = new ArrayList<>();
for (Tag t : swf.getTags()) {
if (t instanceof ShowFrameTag) {
frame++;
}
if (t instanceof ABCContainerTag) {
ABCContainerTag abcCnt = (ABCContainerTag) t;
if (abcCnt.getABC() == abc) {
selectedIndex = abcs.size();
}
abcContainers.add(abcCnt);
abcs.add(abcCnt.getABC());
abcFrames.add(frame);
}
}
String[] abcComboBoxData = new String[abcs.size()];
for (int i = 0; i < abcContainers.size(); i++) {
abcComboBoxData[i] = "tag" + (i + 1);
if (abcContainers.get(i) instanceof DoABC2Tag) {
DoABC2Tag doa2 = (DoABC2Tag) abcContainers.get(i);
if (doa2.name != null && !doa2.name.isEmpty()) {
abcComboBoxData[i] += " (\"" + Helper.escapePCodeString(doa2.name) + "\")";
}
}
}
abcComboBox = new JComboBox<>(abcComboBoxData);
Dimension abcComboBoxSize = new Dimension(500, abcComboBox.getPreferredSize().height);
abcComboBox.setMinimumSize(abcComboBoxSize);
abcComboBox.setPreferredSize(abcComboBoxSize);
topLeftPanel.add(abcComboBox);
abcComboBox.addActionListener(this::abcComboBoxActionPerformed);
} else if (openable instanceof ABC) {
abcs.add((ABC) openable);
abcFrames.add(-1);
}
this.packListener = new Runnable() {
@Override
public void run() {
int cpIndex = cpTabbedPane.getSelectedIndex();
int mainIndex = mainTabbedPane.getSelectedIndex();
abcComboBoxActionPerformed(null);
cpTabbedPane.setSelectedIndex(cpIndex);
mainTabbedPane.setSelectedIndex(mainIndex);
refreshUsages();
}
};
tagInfoLabel = new JLabel();
topLeftPanel.add(tagInfoLabel);
cleanButton.setToolTipText(translate("button.clean"));
cleanButton.addActionListener(this::cleanActionPerformed);
JPanel topRightPanel = new JPanel(new FlowLayout());
topRightPanel.add(cleanButton);
JPanel topPanel = new JPanel(new BorderLayout());
topPanel.add(topLeftPanel, BorderLayout.WEST);
topPanel.add(topRightPanel, BorderLayout.EAST);
mainTabbedPane = new JTabbedPane();
cpTabbedPane = new JTabbedPane();
DefaultTableModel model = new DefaultTableModel();
model.addColumn(translate("usages").replace("%item%", "-"));
usagesTable.setModel(model);
usagesTable.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2) {
int row = usagesTable.getSelectedRow();
if (row == -1) {
return;
}
String path = (String) usagesTable.getModel().getValueAt(row, 0);
selectPath(path);
}
}
});
usagesTable.addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {
if (e.isPopupTrigger()) {
int row = usagesTable.rowAtPoint(e.getPoint());
int column = usagesTable.columnAtPoint(e.getPoint());
if (!usagesTable.isRowSelected(row)) {
usagesTable.changeSelection(row, column, false, false);
}
JPopupMenu popupMenu = new JPopupMenu();
JMenuItem hilightMenuItem = new JMenuItem(translate("hilight.usage"), View.getIcon("jumpto16"));
hilightMenuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int row = usagesTable.getSelectedRow();
if (row == -1) {
return;
}
selectPath((String) usagesTable.getModel().getValueAt(row, 0));
}
});
JMenuItem copyMenuItem = new JMenuItem(translate("copy.paths"), View.getIcon("copy16"));
copyMenuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int[] rows = usagesTable.getSelectedRows();
List values = new ArrayList<>();
for (int row : rows) {
values.add((String) usagesTable.getModel().getValueAt(row, 0));
}
copyToClipboard(String.join("\r\n", values));
}
});
JMenuItem copyAllMenuItem = new JMenuItem(translate("copy.paths.all"), View.getIcon("copy16"));
copyAllMenuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
List values = new ArrayList<>();
for (int row = 0; row < usagesTable.getModel().getRowCount(); row++) {
values.add((String) usagesTable.getModel().getValueAt(row, 0));
}
copyToClipboard(String.join("\r\n", values));
}
});
popupMenu.add(hilightMenuItem);
popupMenu.add(copyMenuItem);
popupMenu.add(copyAllMenuItem);
popupMenu.show(e.getComponent(), e.getX(), e.getY());
}
}
});
JPanel centralPanel = new JPanel(new BorderLayout());
JPanel rightPanel = new JPanel(new BorderLayout());
rightPanel.add(new FasterScrollPane(usagesTable, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER);
//rightPanel.add(calculateUsagesButton, BorderLayout.SOUTH);
JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, mainTabbedPane, rightPanel);
splitPane.setDividerLocation(800);
centralPanel.add(splitPane);
cnt.add(topPanel, BorderLayout.NORTH);
cnt.add(centralPanel, BorderLayout.CENTER);
if (!abcs.isEmpty()) {
if (abcComboBox != null) {
abcComboBox.setSelectedIndex(selectedIndex);
} else {
abcComboBoxActionPerformed(null);
}
}
JRootPane rootPane = getRootPane();
KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_G, KeyEvent.CTRL_DOWN_MASK);
InputMap inputMap = rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
ActionMap actionMap = rootPane.getActionMap();
inputMap.put(keyStroke, "ctrlGAction");
actionMap.put("ctrlGAction", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
String path = ViewMessages.showInputDialog(ABCExplorerDialog.this, translate("goto.path.label"), translate("goto.path"), "");
if (path == null || path.isEmpty()) {
return;
}
selectPath(path);
}
});
setSize(1024, 600);
setTitle(translate("title") + " - " + openable.getTitleOrShortFileName());
List images = new ArrayList<>();
images.add(View.loadImage("abcexplorer16"));
images.add(View.loadImage("abcexplorer32"));
setIconImages(images);
View.centerScreen(this);
}
public void selectAbc(ABC abc) {
if (abcComboBox == null) {
return;
}
if (abc == null && !abcs.isEmpty()) {
abcComboBox.setSelectedIndex(0);
return;
}
for (int i = 0; i < abcs.size(); i++) {
if (abcs.get(i) == abc) {
abcComboBox.setSelectedIndex(i);
break;
}
}
}
private ABC getSelectedAbc() {
if (abcs.isEmpty()) {
return null;
}
if (abcComboBox == null) {
return abcs.get(0);
}
return abcs.get(abcComboBox.getSelectedIndex());
}
private void abcComboBoxActionPerformed(ActionEvent e) {
usageDetector = null;
DefaultTableModel model = new DefaultTableModel();
model.addColumn(translate("usages").replace("%item%", "-"));
usagesTable.setModel(model);
int index = abcComboBox == null ? 0 : abcComboBox.getSelectedIndex();
if (index == -1) {
return;
}
if (abcs.isEmpty()) {
return;
}
ABC abc = abcs.get(index);
if (abcComboBox == null) {
tagInfoLabel.setText(translate("abc.info.standalone")
.replace("%major%", "" + abc.version.major)
.replace("%minor%", "" + abc.version.minor)
.replace("%size%", Helper.formatFileSize(abc.getDataSize()))
);
} else {
tagInfoLabel.setText(
translate("abc.info")
.replace("%index%", "" + (index + 1))
.replace("%count%", "" + abcComboBox.getItemCount())
.replace("%major%", "" + abc.version.major)
.replace("%minor%", "" + abc.version.minor)
.replace("%size%", Helper.formatFileSize(abc.getDataSize()))
.replace("%frame%", "" + abcFrames.get(index))
);
}
cpTabbedPane.removeAll();
cpTabbedPane.addTab("int (" + Math.max(0, abc.constants.getIntCount() - 1) + ")", View.getIcon(TreeType.CONSTANT_INT.getIcon().getFile()), makeTreePanel(abc, TreeType.CONSTANT_INT));
cpTabbedPane.addTab("uint (" + Math.max(0, abc.constants.getUIntCount() - 1) + ")", View.getIcon(TreeType.CONSTANT_UINT.getIcon().getFile()), makeTreePanel(abc, TreeType.CONSTANT_UINT));
cpTabbedPane.addTab("dbl (" + Math.max(0, abc.constants.getDoubleCount() - 1) + ")", View.getIcon(TreeType.CONSTANT_DOUBLE.getIcon().getFile()), makeTreePanel(abc, TreeType.CONSTANT_DOUBLE));
if (abc.hasDecimalSupport()) {
cpTabbedPane.addTab("dc (" + Math.max(0, abc.constants.getDecimalCount() - 1) + ")", View.getIcon(TreeType.CONSTANT_DECIMAL.getIcon().getFile()), makeTreePanel(abc, TreeType.CONSTANT_DECIMAL));
}
if (abc.hasFloatSupport()) {
cpTabbedPane.addTab("fl (" + Math.max(0, abc.constants.getFloatCount() - 1) + ")", View.getIcon(TreeType.CONSTANT_FLOAT.getIcon().getFile()), makeTreePanel(abc, TreeType.CONSTANT_FLOAT));
}
if (abc.hasFloat4Support()) {
cpTabbedPane.addTab("fl4 (" + Math.max(0, abc.constants.getFloat4Count() - 1) + ")", View.getIcon(TreeType.CONSTANT_FLOAT_4.getIcon().getFile()), makeTreePanel(abc, TreeType.CONSTANT_FLOAT_4));
}
cpTabbedPane.addTab("str (" + Math.max(0, abc.constants.getStringCount() - 1) + ")", View.getIcon(TreeType.CONSTANT_STRING.getIcon().getFile()), makeTreePanel(abc, TreeType.CONSTANT_STRING));
cpTabbedPane.addTab("ns (" + Math.max(0, abc.constants.getNamespaceCount() - 1) + ")", View.getIcon(TreeType.CONSTANT_NAMESPACE.getIcon().getFile()), makeTreePanel(abc, TreeType.CONSTANT_NAMESPACE));
cpTabbedPane.addTab("nss (" + Math.max(0, abc.constants.getNamespaceSetCount() - 1) + ")", View.getIcon(TreeType.CONSTANT_NAMESPACE_SET.getIcon().getFile()), makeTreePanel(abc, TreeType.CONSTANT_NAMESPACE_SET));
cpTabbedPane.addTab("mn (" + Math.max(0, abc.constants.getMultinameCount() - 1) + ")", View.getIcon(TreeType.CONSTANT_MULTINAME.getIcon().getFile()), makeTreePanel(abc, TreeType.CONSTANT_MULTINAME));
mainTabbedPane.removeAll();
JPanel cpPanel = new JPanel(new BorderLayout());
cpPanel.add(cpTabbedPane, BorderLayout.CENTER);
int cpCount = Math.max(0, abc.constants.getIntCount() - 1)
+ Math.max(0, abc.constants.getUIntCount() - 1)
+ Math.max(0, abc.constants.getDoubleCount() - 1)
+ Math.max(0, abc.constants.getStringCount() - 1)
+ Math.max(0, abc.constants.getNamespaceCount() - 1)
+ Math.max(0, abc.constants.getNamespaceSetCount() - 1)
+ Math.max(0, abc.constants.getMultinameCount() - 1)
+ (abc.hasDecimalSupport() ? Math.max(0, abc.constants.getDecimalCount() - 1) : 0)
+ (abc.hasFloatSupport() ? Math.max(0, abc.constants.getFloatCount() - 1) : 0)
+ (abc.hasFloat4Support() ? Math.max(0, abc.constants.getFloat4Count() - 1) : 0);
mainTabbedPane.addTab("cp (" + cpCount + ")", View.getIcon("abcconstantpool16"), cpPanel);
mainTabbedPane.addTab("mi (" + abc.method_info.size() + ")", View.getIcon(TreeType.METHOD_INFO.getIcon().getFile()), makeTreePanel(abc, TreeType.METHOD_INFO));
mainTabbedPane.addTab("md (" + abc.metadata_info.size() + ")", View.getIcon(TreeType.METADATA_INFO.getIcon().getFile()), makeTreePanel(abc, TreeType.METADATA_INFO));
mainTabbedPane.addTab("ii (" + abc.instance_info.size() + ")", View.getIcon(TreeType.INSTANCE_INFO.getIcon().getFile()), makeTreePanel(abc, TreeType.INSTANCE_INFO));
mainTabbedPane.addTab("ci (" + abc.class_info.size() + ")", View.getIcon(TreeType.CLASS_INFO.getIcon().getFile()), makeTreePanel(abc, TreeType.CLASS_INFO));
mainTabbedPane.addTab("si (" + abc.script_info.size() + ")", View.getIcon(TreeType.SCRIPT_INFO.getIcon().getFile()), makeTreePanel(abc, TreeType.SCRIPT_INFO));
mainTabbedPane.addTab("mb (" + abc.bodies.size() + ")", View.getIcon(TreeType.METHOD_BODY.getIcon().getFile()), makeTreePanel(abc, TreeType.METHOD_BODY));
abc.removeChangeListener(packListener);
abc.addChangeListener(packListener);
refreshUsages();
repaint();
}
private void refreshUsages() {
ABCSimpleUsageDetector newUsageDetector = new ABCSimpleUsageDetector(getSelectedAbc());
newUsageDetector.detect();
usageDetector = newUsageDetector;
int zeroUsages = newUsageDetector.getZeroUsagesCount();
cleanButton.setText("(" + zeroUsages + ")");
cleanButton.setEnabled(zeroUsages > 0);
}
private JTree getCurrentTree() {
JPanel pan;
if (mainTabbedPane.getSelectedIndex() == 0) { //cp
pan = (JPanel) cpTabbedPane.getSelectedComponent();
} else {
pan = (JPanel) mainTabbedPane.getSelectedComponent();
}
FasterScrollPane fasterScrollPane = (FasterScrollPane) pan.getComponent(0);
JTree tree = (JTree) fasterScrollPane.getViewport().getView();
return tree;
}
private String getCurrentPath() {
JTree tree = getCurrentTree();
TreePath tp = tree.getSelectionPath();
if (tp == null) {
return "";
}
List pathParts = new ArrayList<>();
Object[] path = tp.getPath();
for (int i = 1; i < path.length; i++) {
Object child = path[i];
String key;
if (child instanceof ValueWithIndex) {
ValueWithIndex vwi = (ValueWithIndex) child;
if (!vwi.getTitle().isEmpty()) {
key = vwi.getTitle();
} else {
key = vwi.getType().getAbbreviation() + vwi.getIndex();
}
} else if (child instanceof SubValue) {
SubValue sv = (SubValue) child;
key = sv.getTitle();
} else if (child instanceof SimpleValue) {
SimpleValue sv = (SimpleValue) child;
key = sv.getTitle();
} else {
break;
}
pathParts.add(key);
}
return String.join("/", pathParts);
}
public void selectTrait(int scriptIndex, int classIndex, int traitIndex, int traitType) {
selectScriptInfo(scriptIndex);
JTree tree = getCurrentTree();
Object selection = tree.getLastSelectedPathComponent();
if (selection == null) {
return;
}
int classTraitIndexInScript = -1;
if (classIndex != -1) {
classTraitIndexInScript = findClassTraitIndexInScript(scriptIndex, classIndex);
if (classTraitIndexInScript == -1) {
return;
}
}
if (traitIndex == GraphTextWriter.TRAIT_SCRIPT_INITIALIZER) {
selectPath(tree, "si" + scriptIndex + "/init");
} else if (traitIndex == GraphTextWriter.TRAIT_CLASS_INITIALIZER) {
selectPath(tree, "si" + scriptIndex + "/traits/t" + classTraitIndexInScript + "/class_info/cinit");
} else if (traitIndex == GraphTextWriter.TRAIT_INSTANCE_INITIALIZER) {
selectPath(tree, "si" + scriptIndex + "/traits/t" + classTraitIndexInScript + "/instance_info/iinit");
} else if (traitType == GraphTextWriter.TRAIT_SCRIPT_INITIALIZER) {
selectPath(tree, "si" + scriptIndex + "/traits/t" + traitIndex);
} else if (traitType == GraphTextWriter.TRAIT_CLASS_INITIALIZER) {
selectPath(tree, "si" + scriptIndex + "/traits/t" + classTraitIndexInScript + "/class_info/traits/t" + traitIndex);
} else if (traitType == GraphTextWriter.TRAIT_INSTANCE_INITIALIZER) {
selectPath(tree, "si" + scriptIndex + "/traits/t" + classTraitIndexInScript + "/instance_info/traits/t" + traitIndex);
}
}
private int findClassTraitIndexInScript(int scriptIndex, int classIndex) {
ABC abc = getSelectedAbc();
for (int i = 0; i < abc.script_info.get(scriptIndex).traits.traits.size(); i++) {
Trait t = abc.script_info.get(scriptIndex).traits.traits.get(i);
if (t instanceof TraitClass) {
TraitClass tc = (TraitClass) t;
if (tc.class_info == classIndex) {
return i;
}
}
}
return -1;
}
private void selectPath(String path) {
String[] parts = path.split("/");
String mainItem = parts[0];
TreeType selectedType = null;
for (TreeType type : TreeType.values()) {
if (mainItem.startsWith(type.getAbbreviation())) {
selectedType = type;
}
}
if (selectedType == null) {
return;
}
if (mainTabbedPane.getTabCount() == 0) {
return;
}
int stringOffset = 0;
if (getSelectedAbc().hasDecimalSupport()) {
stringOffset = 1;
}
if (getSelectedAbc().hasFloatSupport()) {
stringOffset++;
}
if (getSelectedAbc().hasFloat4Support()) {
stringOffset++;
}
switch (selectedType) {
case CONSTANT_INT:
mainTabbedPane.setSelectedIndex(0);
cpTabbedPane.setSelectedIndex(0);
break;
case CONSTANT_UINT:
mainTabbedPane.setSelectedIndex(0);
cpTabbedPane.setSelectedIndex(1);
break;
case CONSTANT_DOUBLE:
mainTabbedPane.setSelectedIndex(0);
cpTabbedPane.setSelectedIndex(2);
break;
case CONSTANT_DECIMAL:
if (!getSelectedAbc().hasDecimalSupport()) {
return;
}
mainTabbedPane.setSelectedIndex(0);
cpTabbedPane.setSelectedIndex(3);
break;
case CONSTANT_FLOAT:
if (!getSelectedAbc().hasFloatSupport()) {
return;
}
mainTabbedPane.setSelectedIndex(0);
cpTabbedPane.setSelectedIndex(3);
break;
case CONSTANT_FLOAT_4:
if (!getSelectedAbc().hasFloat4Support()) {
return;
}
mainTabbedPane.setSelectedIndex(0);
cpTabbedPane.setSelectedIndex(4);
break;
case CONSTANT_STRING:
mainTabbedPane.setSelectedIndex(0);
cpTabbedPane.setSelectedIndex(3 + stringOffset);
break;
case CONSTANT_NAMESPACE:
mainTabbedPane.setSelectedIndex(0);
cpTabbedPane.setSelectedIndex(4 + stringOffset);
break;
case CONSTANT_NAMESPACE_SET:
mainTabbedPane.setSelectedIndex(0);
cpTabbedPane.setSelectedIndex(5 + stringOffset);
break;
case CONSTANT_MULTINAME:
mainTabbedPane.setSelectedIndex(0);
cpTabbedPane.setSelectedIndex(6 + stringOffset);
break;
case METHOD_INFO:
mainTabbedPane.setSelectedIndex(1);
break;
case METADATA_INFO:
mainTabbedPane.setSelectedIndex(2);
break;
case INSTANCE_INFO:
mainTabbedPane.setSelectedIndex(3);
break;
case CLASS_INFO:
mainTabbedPane.setSelectedIndex(4);
break;
case SCRIPT_INFO:
mainTabbedPane.setSelectedIndex(5);
break;
case METHOD_BODY:
mainTabbedPane.setSelectedIndex(6);
break;
}
selectPath(getCurrentTree(), path);
}
private void selectPath(JTree tree, String path) {
String[] parts = path.split("/");
TreeModel model = tree.getModel();
Object root = model.getRoot();
Object parent = root;
List