private void saveDecompiledButtonActionPerformed(ActionEvent evt) { ScriptPack pack = decompiledTextArea.getScriptLeaf(); int oldIndex = pack.scriptIndex; SWF.uncache(pack); try { String oldSp = null; List<ScriptPack> packs = abc.script_info.get(oldIndex).getPacks(abc, oldIndex, null); if (!packs.isEmpty()) { oldSp = packs.get(0).getClassPath().toString(); } String as = decompiledTextArea.getText(); abc.replaceScriptPack(pack, as); lastDecompiled = as; mainPanel.updateClassesList(); if (oldSp != null) { hilightScript(getSwf(), oldSp); } setDecompiledEditMode(false); reload(); View.showMessageDialog( this, AppStrings.translate("message.action.saved"), AppStrings.translate("dialog.message.title"), JOptionPane.INFORMATION_MESSAGE, Configuration.showCodeSavedMessage); } catch (AVM2ParseException ex) { abc.script_info.get(oldIndex).delete(abc, false); decompiledTextArea.gotoLine((int) ex.line); decompiledTextArea.markError(); View.showMessageDialog( this, AppStrings.translate("error.action.save") .replace("%error%", ex.text) .replace("%line%", Long.toString(ex.line)), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE); } catch (CompilationException ex) { abc.script_info.get(oldIndex).delete(abc, false); decompiledTextArea.gotoLine((int) ex.line); decompiledTextArea.markError(); View.showMessageDialog( this, AppStrings.translate("error.action.save") .replace("%error%", ex.text) .replace("%line%", Long.toString(ex.line)), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE); } catch (Throwable ex) { Logger.getLogger(ABCPanel.class.getName()).log(Level.SEVERE, null, ex); } }
public void updateConstList() { switch (constantTypeList.getSelectedIndex()) { case 0: View.autoResizeColWidth(constantTable, new UIntTableModel(abc)); break; case 1: View.autoResizeColWidth(constantTable, new IntTableModel(abc)); break; case 2: View.autoResizeColWidth(constantTable, new DoubleTableModel(abc)); break; case 3: View.autoResizeColWidth(constantTable, new DecimalTableModel(abc)); break; case 4: View.autoResizeColWidth(constantTable, new StringTableModel(abc)); break; case 5: View.autoResizeColWidth(constantTable, new NamespaceTableModel(abc)); break; case 6: View.autoResizeColWidth(constantTable, new NamespaceSetTableModel(abc)); break; case 7: View.autoResizeColWidth(constantTable, new MultinameTableModel(abc)); break; } // DefaultTableColumnModel colModel = (DefaultTableColumnModel) constantTable.getColumnModel(); // colModel.getColumn(0).setMaxWidth(50); }
public void setEditMode(boolean val) { slotConstTraitPanel.setEditMode(val); methodTraitPanel.setEditMode(val); saveButton.setVisible(val); saveButton.setEnabled(false); editButton.setVisible(!val); cancelButton.setVisible(val); selectedLabel.setIcon(val ? View.getIcon("editing16") : null); }
public void hilightScript(ScriptPack pack) { TagTreeModel ttm = (TagTreeModel) mainPanel.tagTree.getModel(); final TreePath tp = ttm.getTreePath(pack); View.execInEventDispatchLater( () -> { mainPanel.tagTree.setSelectionPath(tp); mainPanel.tagTree.scrollPathToVisible(tp); }); }
private void editDecompiledButtonActionPerformed(ActionEvent evt) { File swc = Configuration.getPlayerSWC(); final String adobePage = "http://www.adobe.com/support/flashplayer/downloads.html"; if (swc == null) { if (View.showConfirmDialog( this, AppStrings.translate("message.action.playerglobal.needed") .replace("%adobehomepage%", adobePage), AppStrings.translate("message.action.playerglobal.title"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE) == JOptionPane.OK_OPTION) { View.navigateUrl(adobePage); int ret; do { ret = View.showConfirmDialog( this, AppStrings.translate("message.action.playerglobal.place") .replace("%libpath%", Configuration.getFlashLibPath().getAbsolutePath()), AppStrings.translate("message.action.playerglobal.title"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE); swc = Configuration.getPlayerSWC(); } while (ret == JOptionPane.OK_OPTION && swc == null); } } if (swc != null) { if (View.showConfirmDialog( null, AppStrings.translate("message.confirm.experimental.function"), AppStrings.translate("message.warning"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, Configuration.warningExperimentalAS3Edit, JOptionPane.OK_OPTION) == JOptionPane.OK_OPTION) { setDecompiledEditMode(true); } } }
@Override public void updateSearchPos(ABCPanelSearchResult item) { ScriptPack pack = item.scriptPack; setAbc(pack.abc); decompiledTextArea.setScript(pack); hilightScript(pack); decompiledTextArea.setCaretPosition(0); View.execInEventDispatchLater( () -> { searchPanel.showQuickFindDialog(decompiledTextArea); }); }
public void setDecompiledEditMode(boolean val) { if (val) { lastDecompiled = decompiledTextArea.getText(); } else { decompiledTextArea.setText(lastDecompiled); } decompiledTextArea.setEditable(val); saveDecompiledButton.setVisible(val); saveDecompiledButton.setEnabled(false); editDecompiledButton.setVisible(!val); experimentalLabel.setVisible(!val); cancelDecompiledButton.setVisible(val); decompiledTextArea.getCaret().setVisible(true); decLabel.setIcon(val ? View.getIcon("editing16") : null); detailPanel.setVisible(!val); decompiledTextArea.ignoreCarret = val; decompiledTextArea.requestFocusInWindow(); }
public void showCard(final String name, final Trait trait) { View.execInEventDispatch( () -> { CardLayout layout = (CardLayout) innerPanel.getLayout(); layout.show(innerPanel, name); boolean b = cardMap.get(name) instanceof TraitDetail; boolean drun; synchronized (this) { buttonsShouldBeShown = b; drun = debugRunning; } buttonsPanel.setVisible(b && !drun); TraitDetail newDetail = null; if (b) { newDetail = (TraitDetail) cardMap.get(name); } for (JComponent v : cardMap.values()) { if (v instanceof TraitDetail) { if (v != newDetail) { TraitDetail oldDetail = (TraitDetail) v; oldDetail.setActive(false); } } } if (newDetail != null) { newDetail.setActive(true); } selectedCard = name; selectedLabel.setText(selectedCard); if (trait == null) { traitNameLabel.setText("-"); } else { if (abcPanel != null) { traitNameLabel.setText( trait.getName(abcPanel.abc).getName(abcPanel.abc.constants, null, false)); } } }); }
@Override public void actionPerformed(ActionEvent e) { switch (e.getActionCommand()) { case ACTION_OK: if (nameField.getText().trim().isEmpty()) { View.showMessageDialog( null, translate("error.name"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE); return; } result = true; setVisible(false); break; case ACTION_CANCEL: result = false; setVisible(false); break; } }
public NewTraitDialog() { setSize(500, 300); setTitle(translate("dialog.title")); View.centerScreen(this); View.setWindowIcon(this); Container cnt = getContentPane(); cnt.setLayout(new BorderLayout()); JPanel optionsPanel = new JPanel(new FlowLayout()); // optionsPanel.add(new JLabel(translate("label.type"))); typeComboBox = new JComboBox<>( new String[] { translate("type.method"), translate("type.getter"), translate("type.setter"), translate("type.const"), translate("type.slot"), }); staticCheckbox = new JCheckBox(translate("checkbox.static")); optionsPanel.add(staticCheckbox); String accessStrings[] = new String[modifiers.length]; for (int i = 0; i < accessStrings.length; i++) { String pref = Namespace.kindToPrefix(modifiers[i]); String name = Namespace.kindToStr(modifiers[i]); accessStrings[i] = (pref.isEmpty() ? "" : pref + " ") + "(" + name + ")"; } // optionsPanel.add(new JLabel(translate("label.access"))); accessComboBox = new JComboBox<>(accessStrings); optionsPanel.add(accessComboBox); optionsPanel.add(typeComboBox); // optionsPanel.add(new JLabel(translate("label.name"))); nameField = new JTextField(); nameField.setPreferredSize(new Dimension(300, nameField.getPreferredSize().height)); optionsPanel.add(nameField); cnt.add(optionsPanel, BorderLayout.CENTER); JPanel buttonsPanel = new JPanel(new FlowLayout()); JButton buttonOk = new JButton(AppStrings.translate("button.ok")); buttonOk.setActionCommand(ACTION_OK); buttonOk.addActionListener(this); JButton buttonCancel = new JButton(AppStrings.translate("button.cancel")); buttonCancel.setActionCommand(ACTION_CANCEL); buttonCancel.addActionListener(this); buttonsPanel.add(buttonOk); buttonsPanel.add(buttonCancel); cnt.add(buttonsPanel, BorderLayout.SOUTH); pack(); setDefaultCloseOperation(HIDE_ON_CLOSE); setModalityType(ModalityType.APPLICATION_MODAL); nameField.addAncestorListener( new AncestorListener() { @Override public void ancestorAdded(AncestorEvent event) { JComponent component = event.getComponent(); component.requestFocusInWindow(); } @Override public void ancestorRemoved(AncestorEvent event) {} @Override public void ancestorMoved(AncestorEvent event) {} }); getRootPane().setDefaultButton(buttonOk); }
/** @author JPEXS */ public class DetailPanel extends JPanel implements TagEditorPanel { public MethodTraitDetailPanel methodTraitPanel; public JPanel unsupportedTraitPanel; public SlotConstTraitDetailPanel slotConstTraitPanel; public static final String METHOD_TRAIT_CARD = AppStrings.translate("abc.detail.methodtrait"); public static final String UNSUPPORTED_TRAIT_CARD = AppStrings.translate("abc.detail.unsupported"); public static final String SLOT_CONST_TRAIT_CARD = AppStrings.translate("abc.detail.slotconsttrait"); private final JPanel innerPanel; public JButton saveButton = new JButton(AppStrings.translate("button.save"), View.getIcon("save16")); public JButton editButton = new JButton(AppStrings.translate("button.edit"), View.getIcon("edit16")); public JButton cancelButton = new JButton(AppStrings.translate("button.cancel"), View.getIcon("cancel16")); private final HashMap<String, JComponent> cardMap = new HashMap<>(); private String selectedCard; private final JLabel selectedLabel; private final JPanel buttonsPanel; private final ABCPanel abcPanel; private final JLabel traitNameLabel; public DetailPanel(ABCPanel abcPanel) { this.abcPanel = abcPanel; innerPanel = new JPanel(); CardLayout layout = new CardLayout(); innerPanel.setLayout(layout); methodTraitPanel = new MethodTraitDetailPanel(abcPanel); cardMap.put(METHOD_TRAIT_CARD, methodTraitPanel); unsupportedTraitPanel = new JPanel(new BorderLayout()); JLabel unsup = new JLabel( "<html>" + AppStrings.translate("info.selecttrait") + "</html>", SwingConstants.CENTER); unsupportedTraitPanel.add(unsup, BorderLayout.CENTER); cardMap.put(UNSUPPORTED_TRAIT_CARD, unsupportedTraitPanel); slotConstTraitPanel = new SlotConstTraitDetailPanel(abcPanel.decompiledTextArea); cardMap.put(SLOT_CONST_TRAIT_CARD, slotConstTraitPanel); for (String key : cardMap.keySet()) { innerPanel.add(cardMap.get(key), key); } setLayout(new BorderLayout()); add(innerPanel, BorderLayout.CENTER); editButton.setMargin(new Insets(3, 3, 3, 10)); saveButton.setMargin(new Insets(3, 3, 3, 10)); cancelButton.setMargin(new Insets(3, 3, 3, 10)); buttonsPanel = new JPanel(); buttonsPanel.setLayout(new FlowLayout()); saveButton.addActionListener(this::saveButtonActionPerformed); editButton.addActionListener(this::editButtonActionPerformed); cancelButton.addActionListener(this::cancelButtonActionPerformed); saveButton.setVisible(false); cancelButton.setVisible(false); buttonsPanel.setBorder(new BevelBorder(BevelBorder.RAISED)); buttonsPanel.add(editButton); buttonsPanel.add(saveButton); buttonsPanel.add(cancelButton); add(buttonsPanel, BorderLayout.SOUTH); selectedCard = UNSUPPORTED_TRAIT_CARD; layout.show(innerPanel, UNSUPPORTED_TRAIT_CARD); buttonsPanel.setVisible(false); selectedLabel = new HeaderLabel(""); selectedLabel.setText(selectedCard); // selectedLabel.setBorder(new BevelBorder(BevelBorder.RAISED)); selectedLabel.setHorizontalAlignment(SwingConstants.CENTER); JPanel topPanel = new JPanel(new BorderLayout()); topPanel.add(selectedLabel, BorderLayout.NORTH); traitNameLabel = new JLabel(""); JPanel traitInfoPanel = new JPanel(); traitInfoPanel.setLayout(new BoxLayout(traitInfoPanel, BoxLayout.LINE_AXIS)); // traitInfoPanel.add(new JLabel(" " + translate("abc.detail.traitname"))); traitInfoPanel.add(traitNameLabel); topPanel.add(traitInfoPanel, BorderLayout.CENTER); methodTraitPanel .methodCodePanel .getSourceTextArea() .addTextChangedListener(this::editorTextChanged); slotConstTraitPanel.slotConstEditor.addTextChangedListener(this::editorTextChanged); add(topPanel, BorderLayout.NORTH); } private void editorTextChanged() { setModified(true); } private boolean isModified() { return saveButton.isVisible() && saveButton.isEnabled(); } private void setModified(boolean value) { saveButton.setEnabled(value); cancelButton.setEnabled(value); } public void setEditMode(boolean val) { slotConstTraitPanel.setEditMode(val); methodTraitPanel.setEditMode(val); saveButton.setVisible(val); saveButton.setEnabled(false); editButton.setVisible(!val); cancelButton.setVisible(val); selectedLabel.setIcon(val ? View.getIcon("editing16") : null); } public void showCard(final String name, final Trait trait) { CardLayout layout = (CardLayout) innerPanel.getLayout(); layout.show(innerPanel, name); boolean b = cardMap.get(name) instanceof TraitDetail; buttonsPanel.setVisible(b); TraitDetail newDetail = null; if (b) { newDetail = (TraitDetail) cardMap.get(name); } for (JComponent v : cardMap.values()) { if (v instanceof TraitDetail) { if (v != newDetail) { TraitDetail oldDetail = (TraitDetail) v; oldDetail.setActive(false); } } } if (newDetail != null) { newDetail.setActive(true); } selectedCard = name; selectedLabel.setText(selectedCard); if (trait == null) { traitNameLabel.setText("-"); } else { if (abcPanel != null) { traitNameLabel.setText( trait.getName(abcPanel.abc).getName(abcPanel.abc.constants, null, false)); } } } private void editButtonActionPerformed(ActionEvent evt) { setEditMode(true); methodTraitPanel.methodCodePanel.focusEditor(); } private void cancelButtonActionPerformed(ActionEvent evt) { setEditMode(false); abcPanel.decompiledTextArea.resetEditing(); } private void saveButtonActionPerformed(ActionEvent evt) { if (cardMap.get(selectedCard) instanceof TraitDetail) { if (((TraitDetail) cardMap.get(selectedCard)).save()) { CancellableWorker worker = new CancellableWorker() { @Override public Void doInBackground() throws Exception { int lasttrait = abcPanel.decompiledTextArea.lastTraitIndex; abcPanel.decompiledTextArea.reloadClass(); abcPanel.decompiledTextArea.gotoTrait(lasttrait); return null; } @Override protected void done() { setEditMode(false); View.showMessageDialog( null, AppStrings.translate("message.trait.saved"), AppStrings.translate("dialog.message.title"), JOptionPane.INFORMATION_MESSAGE, Configuration.showTraitSavedMessage); } }; worker.execute(); } } } @Override public boolean tryAutoSave() { // todo: implement return false; } @Override public boolean isEditing() { return saveButton.isVisible() && saveButton.isEnabled(); } }
private void addTraitButtonActionPerformed(ActionEvent evt) { int class_index = decompiledTextArea.getClassIndex(); if (class_index < 0) { return; } if (newTraitDialog == null) { newTraitDialog = new NewTraitDialog(); } int void_type = abc.constants.getPublicQnameId( "void", true); // abc.constants.forceGetMultinameId(new Multiname(Multiname.QNAME, // abc.constants.forceGetStringId("void"), abc.constants.forceGetNamespaceId(new // Namespace(Namespace.KIND_PACKAGE, abc.constants.forceGetStringId("")), 0), -1, // -1, new ArrayList<Integer>())); int int_type = abc.constants.getPublicQnameId( "int", true); // abc.constants.forceGetMultinameId(new Multiname(Multiname.QNAME, // abc.constants.forceGetStringId("int"), abc.constants.forceGetNamespaceId(new // Namespace(Namespace.KIND_PACKAGE, abc.constants.forceGetStringId("")), 0), -1, // -1, new ArrayList<Integer>())); Trait t = null; int kind; int nskind; String name = null; boolean isStatic; Multiname m; boolean again = false; loopm: do { if (again) { View.showMessageDialog( null, AppStrings.translate("error.trait.exists").replace("%name%", name), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE); } again = false; if (newTraitDialog.showDialog() != AppDialog.OK_OPTION) { return; } kind = newTraitDialog.getTraitType(); nskind = newTraitDialog.getNamespaceKind(); name = newTraitDialog.getTraitName(); isStatic = newTraitDialog.getStatic(); m = new Multiname( Multiname.QNAME, abc.constants.getStringId(name, true), abc.constants.getNamespaceId( new Namespace(nskind, abc.constants.getStringId("", true)), 0, true), 0, 0, new ArrayList<>()); int mid = abc.constants.getMultinameId(m); if (mid == 0) { break; } for (Trait tr : abc.class_info.get(class_index).static_traits.traits) { if (tr.name_index == mid) { again = true; break; } } for (Trait tr : abc.instance_info.get(class_index).instance_traits.traits) { if (tr.name_index == mid) { again = true; break; } } } while (again); switch (kind) { case Trait.TRAIT_GETTER: case Trait.TRAIT_SETTER: case Trait.TRAIT_METHOD: TraitMethodGetterSetter tm = new TraitMethodGetterSetter(); MethodInfo mi = new MethodInfo( new int[0], void_type, abc.constants.getStringId(name, true), 0, new ValueKind[0], new int[0]); int method_info = abc.addMethodInfo(mi); tm.method_info = method_info; MethodBody body = new MethodBody(); body.method_info = method_info; body.init_scope_depth = 1; body.max_regs = 1; body.max_scope_depth = 1; body.max_stack = 1; body.exceptions = new ABCException[0]; AVM2Code code = new AVM2Code(); code.code.add(new AVM2Instruction(0, new GetLocal0Ins(), new int[0])); code.code.add(new AVM2Instruction(0, new PushScopeIns(), new int[0])); code.code.add(new AVM2Instruction(0, new ReturnVoidIns(), new int[0])); body.setCode(code); Traits traits = new Traits(); traits.traits = new ArrayList<>(); body.traits = traits; abc.addMethodBody(body); mi.setBody(body); t = tm; break; case Trait.TRAIT_SLOT: case Trait.TRAIT_CONST: TraitSlotConst ts = new TraitSlotConst(); ts.type_index = int_type; ts.value_kind = ValueKind.CONSTANT_Int; ts.value_index = abc.constants.getIntId(0, true); t = ts; break; } if (t != null) { t.kindType = kind; t.name_index = abc.constants.getMultinameId(m, true); int traitId; if (isStatic) { traitId = abc.class_info.get(class_index).static_traits.addTrait(t); } else { traitId = abc.class_info.get(class_index).static_traits.traits.size() + abc.instance_info.get(class_index).instance_traits.addTrait(t); } reload(); decompiledTextArea.gotoTrait(traitId); } }
public ABCPanel(MainPanel mainPanel) { this.mainPanel = mainPanel; setLayout(new BorderLayout()); decompiledTextArea = new DecompiledEditorPane(this); decompiledTextArea.addTextChangedListener(this::decompiledTextAreaTextChanged); decompiledTextArea.setLinkHandler( new LinkHandler() { @Override public boolean isLink(Token token) { return hasDeclaration(token.length == 1 ? token.start : token.start + 1); } @Override public void handleLink(Token token) { gotoDeclaration(token.length == 1 ? token.start : token.start + 1); } @Override public Highlighter.HighlightPainter linkPainter() { return decompiledTextArea.linkPainter(); } }); searchPanel = new SearchPanel<>(new FlowLayout(), this); decompiledScrollPane = new JScrollPane(decompiledTextArea); JPanel iconDecPanel = new JPanel(); iconDecPanel.setLayout(new BoxLayout(iconDecPanel, BoxLayout.Y_AXIS)); JPanel iconsPanel = new JPanel(); iconsPanel.setLayout(new BoxLayout(iconsPanel, BoxLayout.X_AXIS)); JButton newTraitButton = new JButton(View.getIcon("traitadd16")); newTraitButton.setMargin(new Insets(5, 5, 5, 5)); newTraitButton.addActionListener(this::addTraitButtonActionPerformed); newTraitButton.setToolTipText(AppStrings.translate("button.addtrait")); iconsPanel.add(newTraitButton); scriptNameLabel = new JLabel("-"); scriptNameLabel.setAlignmentX(0); iconsPanel.setAlignmentX(0); decompiledScrollPane.setAlignmentX(0); iconDecPanel.add(scriptNameLabel); iconDecPanel.add(iconsPanel); iconDecPanel.add(decompiledScrollPane); JPanel decButtonsPan = new JPanel(new FlowLayout()); decButtonsPan.setBorder(new BevelBorder(BevelBorder.RAISED)); decButtonsPan.add(editDecompiledButton); decButtonsPan.add(experimentalLabel); decButtonsPan.add(saveDecompiledButton); decButtonsPan.add(cancelDecompiledButton); editDecompiledButton.setMargin(new Insets(3, 3, 3, 10)); saveDecompiledButton.setMargin(new Insets(3, 3, 3, 10)); cancelDecompiledButton.setMargin(new Insets(3, 3, 3, 10)); saveDecompiledButton.addActionListener(this::saveDecompiledButtonActionPerformed); editDecompiledButton.addActionListener(this::editDecompiledButtonActionPerformed); cancelDecompiledButton.addActionListener(this::cancelDecompiledButtonActionPerformed); saveDecompiledButton.setVisible(false); cancelDecompiledButton.setVisible(false); decButtonsPan.setAlignmentX(0); JPanel decPanel = new JPanel(new BorderLayout()); decPanel.add(searchPanel, BorderLayout.NORTH); decPanel.add(iconDecPanel, BorderLayout.CENTER); decPanel.add(decButtonsPan, BorderLayout.SOUTH); detailPanel = new DetailPanel(this); JPanel panB = new JPanel(); panB.setLayout(new BorderLayout()); panB.add(decPanel, BorderLayout.CENTER); panB.add(decLabel, BorderLayout.NORTH); decLabel.setHorizontalAlignment(SwingConstants.CENTER); // decLabel.setBorder(new BevelBorder(BevelBorder.RAISED)); splitPane = new JPersistentSplitPane( JSplitPane.HORIZONTAL_SPLIT, panB, detailPanel, Configuration.guiAvm2SplitPaneDividerLocationPercent); splitPane.setContinuousLayout(true); decompiledTextArea.changeContentType("text/actionscript"); decompiledTextArea.setFont( new Font("Monospaced", Font.PLAIN, decompiledTextArea.getFont().getSize())); View.addEditorAction( decompiledTextArea, new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { int multinameIndex = decompiledTextArea.getMultinameUnderCaret(); if (multinameIndex > -1) { UsageFrame usageFrame = new UsageFrame(abc, multinameIndex, ABCPanel.this, false); usageFrame.setVisible(true); } } }, "find-usages", AppStrings.translate("abc.action.find-usages"), "control U"); View.addEditorAction( decompiledTextArea, new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { gotoDeclaration(decompiledTextArea.getCaretPosition()); } }, "find-declaration", AppStrings.translate("abc.action.find-declaration"), "control B"); CtrlClickHandler cch = new CtrlClickHandler(); decompiledTextArea.addKeyListener(cch); decompiledTextArea.addMouseListener(cch); decompiledTextArea.addMouseMotionListener(cch); navigator = new TraitsList(this); navPanel = new JPanel(new BorderLayout()); JPanel navIconsPanel = new JPanel(); navIconsPanel.setLayout(new BoxLayout(navIconsPanel, BoxLayout.X_AXIS)); final JToggleButton sortButton = new JToggleButton(View.getIcon("sort16")); sortButton.setMargin(new Insets(3, 3, 3, 3)); navIconsPanel.add(sortButton); navPanel.add(navIconsPanel, BorderLayout.SOUTH); navPanel.add(new JScrollPane(navigator), BorderLayout.CENTER); sortButton.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { navigator.setSorted(sortButton.isSelected()); navigator.updateUI(); } }); tabbedPane = new JTabbedPane(); tabbedPane.addTab(AppStrings.translate("traits"), navPanel); add(splitPane, BorderLayout.CENTER); JPanel panConstants = new JPanel(); panConstants.setLayout(new BorderLayout()); constantTypeList = new JComboBox<>( new String[] { "UINT", "INT", "DOUBLE", "DECIMAL", "STRING", "NAMESPACE", "NAMESPACESET", "MULTINAME" }); constantTable = new JTable(); if (abc != null) { View.autoResizeColWidth(constantTable, new UIntTableModel(abc)); } constantTable.setAutoCreateRowSorter(true); final ABCPanel t = this; constantTable.addMouseListener( new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 2) { if (constantTypeList.getSelectedIndex() == 7) { // MULTINAME int rowIndex = constantTable.getSelectedRow(); if (rowIndex == -1) { return; } int multinameIndex = constantTable.convertRowIndexToModel(rowIndex); if (multinameIndex > 0) { UsageFrame usageFrame = new UsageFrame(abc, multinameIndex, t, false); usageFrame.setVisible(true); } } } } }); constantTypeList.addItemListener(this); panConstants.add(constantTypeList, BorderLayout.NORTH); panConstants.add(new JScrollPane(constantTable), BorderLayout.CENTER); tabbedPane.addTab(AppStrings.translate("constants"), panConstants); }
public boolean search(final String txt, boolean ignoreCase, boolean regexp) { if ((txt != null) && (!txt.isEmpty())) { searchPanel.setOptions(ignoreCase, regexp); TagTreeModel ttm = (TagTreeModel) mainPanel.tagTree.getModel(); TreeItem scriptsNode = ttm.getScriptsNode(mainPanel.getCurrentSwf()); final List<ABCPanelSearchResult> found = new ArrayList<>(); if (scriptsNode instanceof ClassesListTreeModel) { ClassesListTreeModel clModel = (ClassesListTreeModel) scriptsNode; List<ScriptPack> allpacks = clModel.getList(); final Pattern pat = regexp ? Pattern.compile( txt, ignoreCase ? (Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE) : 0) : Pattern.compile( Pattern.quote(txt), ignoreCase ? (Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE) : 0); int pos = 0; for (final ScriptPack pack : allpacks) { pos++; String workText = AppStrings.translate("work.searching"); String decAdd = ""; if (!SWF.isCached(pack)) { decAdd = ", " + AppStrings.translate("work.decompiling"); } try { CancellableWorker worker = new CancellableWorker() { @Override public Void doInBackground() throws Exception { if (pat.matcher(SWF.getCached(pack).text).find()) { ABCPanelSearchResult searchResult = new ABCPanelSearchResult(); searchResult.scriptPack = pack; found.add(searchResult); } return null; } }; worker.execute(); Main.startWork( workText + " \"" + txt + "\"" + decAdd + " - (" + pos + "/" + allpacks.size() + ") " + pack.getClassPath().toString() + "... ", worker); worker.get(); } catch (InterruptedException ex) { break; } catch (ExecutionException ex) { Logger.getLogger(ABCPanel.class.getName()).log(Level.SEVERE, null, ex); } } } Main.stopWork(); searchPanel.setSearchText(txt); View.execInEventDispatch( () -> { SearchResultsDialog<ABCPanelSearchResult> sr = new SearchResultsDialog<>( ABCPanel.this.mainPanel.getMainFrame().getWindow(), txt, ABCPanel.this); sr.setResults(found); sr.setVisible(true); }); return true; // return searchPanel.setResults(found); } return false; }
/** @author JPEXS */ public class ABCPanel extends JPanel implements ItemListener, SearchListener<ABCPanelSearchResult>, Freed, TagEditorPanel { private MainPanel mainPanel; public TraitsList navigator; public ABC abc; public JComboBox<ABCContainerTag> abcComboBox; public DecompiledEditorPane decompiledTextArea; public JScrollPane decompiledScrollPane; public JPersistentSplitPane splitPane; private JTable constantTable; public JComboBox<String> constantTypeList; public JLabel asmLabel = new HeaderLabel(AppStrings.translate("panel.disassembled")); public JLabel decLabel = new HeaderLabel(AppStrings.translate("panel.decompiled")); public DetailPanel detailPanel; public JPanel navPanel; public JTabbedPane tabbedPane; public SearchPanel<ABCPanelSearchResult> searchPanel; private NewTraitDialog newTraitDialog; public JLabel scriptNameLabel; private JLabel experimentalLabel = new JLabel(AppStrings.translate("action.edit.experimental")); private JButton editDecompiledButton = new JButton(AppStrings.translate("button.edit"), View.getIcon("edit16")); private JButton saveDecompiledButton = new JButton(AppStrings.translate("button.save"), View.getIcon("save16")); private JButton cancelDecompiledButton = new JButton(AppStrings.translate("button.cancel"), View.getIcon("cancel16")); private String lastDecompiled = null; public MainPanel getMainPanel() { return mainPanel; } public boolean search(final String txt, boolean ignoreCase, boolean regexp) { if ((txt != null) && (!txt.isEmpty())) { searchPanel.setOptions(ignoreCase, regexp); TagTreeModel ttm = (TagTreeModel) mainPanel.tagTree.getModel(); TreeItem scriptsNode = ttm.getScriptsNode(mainPanel.getCurrentSwf()); final List<ABCPanelSearchResult> found = new ArrayList<>(); if (scriptsNode instanceof ClassesListTreeModel) { ClassesListTreeModel clModel = (ClassesListTreeModel) scriptsNode; List<ScriptPack> allpacks = clModel.getList(); final Pattern pat = regexp ? Pattern.compile( txt, ignoreCase ? (Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE) : 0) : Pattern.compile( Pattern.quote(txt), ignoreCase ? (Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE) : 0); int pos = 0; for (final ScriptPack pack : allpacks) { pos++; String workText = AppStrings.translate("work.searching"); String decAdd = ""; if (!SWF.isCached(pack)) { decAdd = ", " + AppStrings.translate("work.decompiling"); } try { CancellableWorker worker = new CancellableWorker() { @Override public Void doInBackground() throws Exception { if (pat.matcher(SWF.getCached(pack).text).find()) { ABCPanelSearchResult searchResult = new ABCPanelSearchResult(); searchResult.scriptPack = pack; found.add(searchResult); } return null; } }; worker.execute(); Main.startWork( workText + " \"" + txt + "\"" + decAdd + " - (" + pos + "/" + allpacks.size() + ") " + pack.getClassPath().toString() + "... ", worker); worker.get(); } catch (InterruptedException ex) { break; } catch (ExecutionException ex) { Logger.getLogger(ABCPanel.class.getName()).log(Level.SEVERE, null, ex); } } } Main.stopWork(); searchPanel.setSearchText(txt); View.execInEventDispatch( () -> { SearchResultsDialog<ABCPanelSearchResult> sr = new SearchResultsDialog<>( ABCPanel.this.mainPanel.getMainFrame().getWindow(), txt, ABCPanel.this); sr.setResults(found); sr.setVisible(true); }); return true; // return searchPanel.setResults(found); } return false; } public void setAbc(ABC abc) { this.abc = abc; navigator.setAbc(abc); updateConstList(); } public void updateConstList() { switch (constantTypeList.getSelectedIndex()) { case 0: View.autoResizeColWidth(constantTable, new UIntTableModel(abc)); break; case 1: View.autoResizeColWidth(constantTable, new IntTableModel(abc)); break; case 2: View.autoResizeColWidth(constantTable, new DoubleTableModel(abc)); break; case 3: View.autoResizeColWidth(constantTable, new DecimalTableModel(abc)); break; case 4: View.autoResizeColWidth(constantTable, new StringTableModel(abc)); break; case 5: View.autoResizeColWidth(constantTable, new NamespaceTableModel(abc)); break; case 6: View.autoResizeColWidth(constantTable, new NamespaceSetTableModel(abc)); break; case 7: View.autoResizeColWidth(constantTable, new MultinameTableModel(abc)); break; } // DefaultTableColumnModel colModel = (DefaultTableColumnModel) constantTable.getColumnModel(); // colModel.getColumn(0).setMaxWidth(50); } public SWF getSwf() { return abc == null ? null : abc.getSwf(); } public List<ABCContainerTag> getAbcList() { SWF swf = getSwf(); return swf == null ? null : swf.getAbcList(); } public void clearSwf() { this.abc = null; constantTable.setModel(new DefaultTableModel()); navigator.clearAbc(); decompiledTextArea.clearScript(); } private boolean isFreeing; @Override public boolean isFreeing() { return isFreeing; } @Override public void free() { isFreeing = true; Helper.emptyObject(this); } public ABCPanel(MainPanel mainPanel) { this.mainPanel = mainPanel; setLayout(new BorderLayout()); decompiledTextArea = new DecompiledEditorPane(this); decompiledTextArea.addTextChangedListener(this::decompiledTextAreaTextChanged); decompiledTextArea.setLinkHandler( new LinkHandler() { @Override public boolean isLink(Token token) { return hasDeclaration(token.length == 1 ? token.start : token.start + 1); } @Override public void handleLink(Token token) { gotoDeclaration(token.length == 1 ? token.start : token.start + 1); } @Override public Highlighter.HighlightPainter linkPainter() { return decompiledTextArea.linkPainter(); } }); searchPanel = new SearchPanel<>(new FlowLayout(), this); decompiledScrollPane = new JScrollPane(decompiledTextArea); JPanel iconDecPanel = new JPanel(); iconDecPanel.setLayout(new BoxLayout(iconDecPanel, BoxLayout.Y_AXIS)); JPanel iconsPanel = new JPanel(); iconsPanel.setLayout(new BoxLayout(iconsPanel, BoxLayout.X_AXIS)); JButton newTraitButton = new JButton(View.getIcon("traitadd16")); newTraitButton.setMargin(new Insets(5, 5, 5, 5)); newTraitButton.addActionListener(this::addTraitButtonActionPerformed); newTraitButton.setToolTipText(AppStrings.translate("button.addtrait")); iconsPanel.add(newTraitButton); scriptNameLabel = new JLabel("-"); scriptNameLabel.setAlignmentX(0); iconsPanel.setAlignmentX(0); decompiledScrollPane.setAlignmentX(0); iconDecPanel.add(scriptNameLabel); iconDecPanel.add(iconsPanel); iconDecPanel.add(decompiledScrollPane); JPanel decButtonsPan = new JPanel(new FlowLayout()); decButtonsPan.setBorder(new BevelBorder(BevelBorder.RAISED)); decButtonsPan.add(editDecompiledButton); decButtonsPan.add(experimentalLabel); decButtonsPan.add(saveDecompiledButton); decButtonsPan.add(cancelDecompiledButton); editDecompiledButton.setMargin(new Insets(3, 3, 3, 10)); saveDecompiledButton.setMargin(new Insets(3, 3, 3, 10)); cancelDecompiledButton.setMargin(new Insets(3, 3, 3, 10)); saveDecompiledButton.addActionListener(this::saveDecompiledButtonActionPerformed); editDecompiledButton.addActionListener(this::editDecompiledButtonActionPerformed); cancelDecompiledButton.addActionListener(this::cancelDecompiledButtonActionPerformed); saveDecompiledButton.setVisible(false); cancelDecompiledButton.setVisible(false); decButtonsPan.setAlignmentX(0); JPanel decPanel = new JPanel(new BorderLayout()); decPanel.add(searchPanel, BorderLayout.NORTH); decPanel.add(iconDecPanel, BorderLayout.CENTER); decPanel.add(decButtonsPan, BorderLayout.SOUTH); detailPanel = new DetailPanel(this); JPanel panB = new JPanel(); panB.setLayout(new BorderLayout()); panB.add(decPanel, BorderLayout.CENTER); panB.add(decLabel, BorderLayout.NORTH); decLabel.setHorizontalAlignment(SwingConstants.CENTER); // decLabel.setBorder(new BevelBorder(BevelBorder.RAISED)); splitPane = new JPersistentSplitPane( JSplitPane.HORIZONTAL_SPLIT, panB, detailPanel, Configuration.guiAvm2SplitPaneDividerLocationPercent); splitPane.setContinuousLayout(true); decompiledTextArea.changeContentType("text/actionscript"); decompiledTextArea.setFont( new Font("Monospaced", Font.PLAIN, decompiledTextArea.getFont().getSize())); View.addEditorAction( decompiledTextArea, new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { int multinameIndex = decompiledTextArea.getMultinameUnderCaret(); if (multinameIndex > -1) { UsageFrame usageFrame = new UsageFrame(abc, multinameIndex, ABCPanel.this, false); usageFrame.setVisible(true); } } }, "find-usages", AppStrings.translate("abc.action.find-usages"), "control U"); View.addEditorAction( decompiledTextArea, new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { gotoDeclaration(decompiledTextArea.getCaretPosition()); } }, "find-declaration", AppStrings.translate("abc.action.find-declaration"), "control B"); CtrlClickHandler cch = new CtrlClickHandler(); decompiledTextArea.addKeyListener(cch); decompiledTextArea.addMouseListener(cch); decompiledTextArea.addMouseMotionListener(cch); navigator = new TraitsList(this); navPanel = new JPanel(new BorderLayout()); JPanel navIconsPanel = new JPanel(); navIconsPanel.setLayout(new BoxLayout(navIconsPanel, BoxLayout.X_AXIS)); final JToggleButton sortButton = new JToggleButton(View.getIcon("sort16")); sortButton.setMargin(new Insets(3, 3, 3, 3)); navIconsPanel.add(sortButton); navPanel.add(navIconsPanel, BorderLayout.SOUTH); navPanel.add(new JScrollPane(navigator), BorderLayout.CENTER); sortButton.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { navigator.setSorted(sortButton.isSelected()); navigator.updateUI(); } }); tabbedPane = new JTabbedPane(); tabbedPane.addTab(AppStrings.translate("traits"), navPanel); add(splitPane, BorderLayout.CENTER); JPanel panConstants = new JPanel(); panConstants.setLayout(new BorderLayout()); constantTypeList = new JComboBox<>( new String[] { "UINT", "INT", "DOUBLE", "DECIMAL", "STRING", "NAMESPACE", "NAMESPACESET", "MULTINAME" }); constantTable = new JTable(); if (abc != null) { View.autoResizeColWidth(constantTable, new UIntTableModel(abc)); } constantTable.setAutoCreateRowSorter(true); final ABCPanel t = this; constantTable.addMouseListener( new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 2) { if (constantTypeList.getSelectedIndex() == 7) { // MULTINAME int rowIndex = constantTable.getSelectedRow(); if (rowIndex == -1) { return; } int multinameIndex = constantTable.convertRowIndexToModel(rowIndex); if (multinameIndex > 0) { UsageFrame usageFrame = new UsageFrame(abc, multinameIndex, t, false); usageFrame.setVisible(true); } } } } }); constantTypeList.addItemListener(this); panConstants.add(constantTypeList, BorderLayout.NORTH); panConstants.add(new JScrollPane(constantTable), BorderLayout.CENTER); tabbedPane.addTab(AppStrings.translate("constants"), panConstants); } private void decompiledTextAreaTextChanged() { setModified(true); } private boolean isModified() { return saveDecompiledButton.isVisible() && saveDecompiledButton.isEnabled(); } private void setModified(boolean value) { saveDecompiledButton.setEnabled(value); cancelDecompiledButton.setEnabled(value); } private boolean hasDeclaration(int pos) { SyntaxDocument sd = (SyntaxDocument) decompiledTextArea.getDocument(); Token t = sd.getTokenAt(pos); if (t == null || (t.type != TokenType.IDENTIFIER && t.type != TokenType.KEYWORD && t.type != TokenType.REGEX)) { return false; } Reference<Integer> abcIndex = new Reference<>(0); Reference<Integer> classIndex = new Reference<>(0); Reference<Integer> traitIndex = new Reference<>(0); Reference<Integer> multinameIndexRef = new Reference<>(0); Reference<Boolean> classTrait = new Reference<>(false); if (decompiledTextArea.getPropertyTypeAtPos( pos, abcIndex, classIndex, traitIndex, classTrait, multinameIndexRef)) { return true; } int multinameIndex = decompiledTextArea.getMultinameAtPos(pos); if (multinameIndex > -1) { if (multinameIndex == 0) { return false; } List<MultinameUsage> usages = abc.findMultinameDefinition(multinameIndex); Multiname m = abc.constants.constant_multiname.get(multinameIndex); // search other ABC tags if this is not private multiname if (m.namespace_index > 0 && abc.constants.constant_namespace.get(m.namespace_index).kind != Namespace.KIND_PRIVATE) { for (ABCContainerTag at : getAbcList()) { ABC a = at.getABC(); if (a == abc) { continue; } int mid = a.constants.getMultinameId(m, false); if (mid > 0) { usages.addAll(a.findMultinameDefinition(mid)); } } } // more than one? display list if (!usages.isEmpty()) { return true; } } return decompiledTextArea.getLocalDeclarationOfPos(pos, new Reference<>("")) != -1; } private void gotoDeclaration(int pos) { Reference<Integer> abcIndex = new Reference<>(0); Reference<Integer> classIndex = new Reference<>(0); Reference<Integer> traitIndex = new Reference<>(0); Reference<Boolean> classTrait = new Reference<>(false); Reference<Integer> multinameIndexRef = new Reference<>(0); if (decompiledTextArea.getPropertyTypeAtPos( pos, abcIndex, classIndex, traitIndex, classTrait, multinameIndexRef)) { UsageFrame.gotoUsage( ABCPanel.this, new TraitMultinameUsage( getAbcList().get(abcIndex.getVal()).getABC(), multinameIndexRef.getVal(), classIndex.getVal(), traitIndex.getVal(), classTrait.getVal(), null, -1) {}); return; } int multinameIndex = decompiledTextArea.getMultinameAtPos(pos); if (multinameIndex > -1) { List<MultinameUsage> usages = abc.findMultinameDefinition(multinameIndex); Multiname m = abc.constants.constant_multiname.get(multinameIndex); // search other ABC tags if this is not private multiname if (m.namespace_index > 0 && abc.constants.constant_namespace.get(m.namespace_index).kind != Namespace.KIND_PRIVATE) { for (ABCContainerTag at : getAbcList()) { ABC a = at.getABC(); if (a == abc) { continue; } int mid = a.constants.getMultinameId(m, false); if (mid > 0) { usages.addAll(a.findMultinameDefinition(mid)); } } } // more than one? display list if (usages.size() > 1) { UsageFrame usageFrame = new UsageFrame(abc, multinameIndex, ABCPanel.this, true); usageFrame.setVisible(true); return; } else if (!usages.isEmpty()) { // one UsageFrame.gotoUsage(ABCPanel.this, usages.get(0)); return; } } int dpos = decompiledTextArea.getLocalDeclarationOfPos(pos, new Reference<>("")); if (dpos > -1) { decompiledTextArea.setCaretPosition(dpos); } } private class CtrlClickHandler extends KeyAdapter implements MouseListener, MouseMotionListener { private boolean ctrlDown = false; @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == 17 && !decompiledTextArea.isEditable()) { ctrlDown = true; // decompiledTextArea.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); } } @Override public void keyReleased(KeyEvent e) { if (e.getKeyCode() == 17) { ctrlDown = false; // decompiledTextArea.setCursor(Cursor.getDefaultCursor()); } } @Override public void mouseClicked(MouseEvent e) { if (ctrlDown && e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 1 && !decompiledTextArea.isEditable()) { ctrlDown = false; // decompiledTextArea.setCursor(Cursor.getDefaultCursor()); // gotoDeclaration(); } } @Override public void mousePressed(MouseEvent e) {} @Override public void mouseReleased(MouseEvent e) {} @Override public void mouseEntered(MouseEvent e) {} @Override public void mouseExited(MouseEvent e) { ctrlDown = false; decompiledTextArea.setCursor(Cursor.getDefaultCursor()); } @Override public void mouseDragged(MouseEvent e) {} @Override public void mouseMoved(MouseEvent e) { if (ctrlDown && decompiledTextArea.isEditable()) { ctrlDown = false; decompiledTextArea.setCursor(Cursor.getDefaultCursor()); } } } public void reload() { lastDecompiled = ""; getSwf().clearScriptCache(); decompiledTextArea.reloadClass(); detailPanel.methodTraitPanel.methodCodePanel.clear(); } @Override public void itemStateChanged(ItemEvent e) { if (e.getSource() == constantTypeList) { int index = ((JComboBox) e.getSource()).getSelectedIndex(); if (index == -1) { return; } updateConstList(); } } public void display() { setVisible(true); } public void hilightScript(SWF swf, String name) { TagTreeModel ttm = (TagTreeModel) mainPanel.tagTree.getModel(); TreeItem scriptsNode = ttm.getScriptsNode(swf); if (scriptsNode instanceof ClassesListTreeModel) { ClassesListTreeModel clModel = (ClassesListTreeModel) scriptsNode; ScriptPack pack = null; for (ScriptPack item : clModel.getList()) { ClassPath classPath = item.getClassPath(); // first check the className to avoid calling unnecessary toString if (name.endsWith(classPath.className) && classPath.toString().equals(name)) { pack = item; break; } } if (pack != null) { hilightScript(pack); } } } public void hilightScript(ScriptPack pack) { TagTreeModel ttm = (TagTreeModel) mainPanel.tagTree.getModel(); final TreePath tp = ttm.getTreePath(pack); View.execInEventDispatchLater( () -> { mainPanel.tagTree.setSelectionPath(tp); mainPanel.tagTree.scrollPathToVisible(tp); }); } @Override public void updateSearchPos(ABCPanelSearchResult item) { ScriptPack pack = item.scriptPack; setAbc(pack.abc); decompiledTextArea.setScript(pack); hilightScript(pack); decompiledTextArea.setCaretPosition(0); View.execInEventDispatchLater( () -> { searchPanel.showQuickFindDialog(decompiledTextArea); }); } public boolean isDirectEditing() { return saveDecompiledButton.isVisible() && saveDecompiledButton.isEnabled(); } public void setDecompiledEditMode(boolean val) { if (val) { lastDecompiled = decompiledTextArea.getText(); } else { decompiledTextArea.setText(lastDecompiled); } decompiledTextArea.setEditable(val); saveDecompiledButton.setVisible(val); saveDecompiledButton.setEnabled(false); editDecompiledButton.setVisible(!val); experimentalLabel.setVisible(!val); cancelDecompiledButton.setVisible(val); decompiledTextArea.getCaret().setVisible(true); decLabel.setIcon(val ? View.getIcon("editing16") : null); detailPanel.setVisible(!val); decompiledTextArea.ignoreCarret = val; decompiledTextArea.requestFocusInWindow(); } private void editDecompiledButtonActionPerformed(ActionEvent evt) { File swc = Configuration.getPlayerSWC(); final String adobePage = "http://www.adobe.com/support/flashplayer/downloads.html"; if (swc == null) { if (View.showConfirmDialog( this, AppStrings.translate("message.action.playerglobal.needed") .replace("%adobehomepage%", adobePage), AppStrings.translate("message.action.playerglobal.title"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE) == JOptionPane.OK_OPTION) { View.navigateUrl(adobePage); int ret; do { ret = View.showConfirmDialog( this, AppStrings.translate("message.action.playerglobal.place") .replace("%libpath%", Configuration.getFlashLibPath().getAbsolutePath()), AppStrings.translate("message.action.playerglobal.title"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE); swc = Configuration.getPlayerSWC(); } while (ret == JOptionPane.OK_OPTION && swc == null); } } if (swc != null) { if (View.showConfirmDialog( null, AppStrings.translate("message.confirm.experimental.function"), AppStrings.translate("message.warning"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, Configuration.warningExperimentalAS3Edit, JOptionPane.OK_OPTION) == JOptionPane.OK_OPTION) { setDecompiledEditMode(true); } } } private void cancelDecompiledButtonActionPerformed(ActionEvent evt) { setDecompiledEditMode(false); } private void saveDecompiledButtonActionPerformed(ActionEvent evt) { ScriptPack pack = decompiledTextArea.getScriptLeaf(); int oldIndex = pack.scriptIndex; SWF.uncache(pack); try { String oldSp = null; List<ScriptPack> packs = abc.script_info.get(oldIndex).getPacks(abc, oldIndex, null); if (!packs.isEmpty()) { oldSp = packs.get(0).getClassPath().toString(); } String as = decompiledTextArea.getText(); abc.replaceScriptPack(pack, as); lastDecompiled = as; mainPanel.updateClassesList(); if (oldSp != null) { hilightScript(getSwf(), oldSp); } setDecompiledEditMode(false); reload(); View.showMessageDialog( this, AppStrings.translate("message.action.saved"), AppStrings.translate("dialog.message.title"), JOptionPane.INFORMATION_MESSAGE, Configuration.showCodeSavedMessage); } catch (AVM2ParseException ex) { abc.script_info.get(oldIndex).delete(abc, false); decompiledTextArea.gotoLine((int) ex.line); decompiledTextArea.markError(); View.showMessageDialog( this, AppStrings.translate("error.action.save") .replace("%error%", ex.text) .replace("%line%", Long.toString(ex.line)), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE); } catch (CompilationException ex) { abc.script_info.get(oldIndex).delete(abc, false); decompiledTextArea.gotoLine((int) ex.line); decompiledTextArea.markError(); View.showMessageDialog( this, AppStrings.translate("error.action.save") .replace("%error%", ex.text) .replace("%line%", Long.toString(ex.line)), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE); } catch (Throwable ex) { Logger.getLogger(ABCPanel.class.getName()).log(Level.SEVERE, null, ex); } } private void addTraitButtonActionPerformed(ActionEvent evt) { int class_index = decompiledTextArea.getClassIndex(); if (class_index < 0) { return; } if (newTraitDialog == null) { newTraitDialog = new NewTraitDialog(); } int void_type = abc.constants.getPublicQnameId( "void", true); // abc.constants.forceGetMultinameId(new Multiname(Multiname.QNAME, // abc.constants.forceGetStringId("void"), abc.constants.forceGetNamespaceId(new // Namespace(Namespace.KIND_PACKAGE, abc.constants.forceGetStringId("")), 0), -1, // -1, new ArrayList<Integer>())); int int_type = abc.constants.getPublicQnameId( "int", true); // abc.constants.forceGetMultinameId(new Multiname(Multiname.QNAME, // abc.constants.forceGetStringId("int"), abc.constants.forceGetNamespaceId(new // Namespace(Namespace.KIND_PACKAGE, abc.constants.forceGetStringId("")), 0), -1, // -1, new ArrayList<Integer>())); Trait t = null; int kind; int nskind; String name = null; boolean isStatic; Multiname m; boolean again = false; loopm: do { if (again) { View.showMessageDialog( null, AppStrings.translate("error.trait.exists").replace("%name%", name), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE); } again = false; if (newTraitDialog.showDialog() != AppDialog.OK_OPTION) { return; } kind = newTraitDialog.getTraitType(); nskind = newTraitDialog.getNamespaceKind(); name = newTraitDialog.getTraitName(); isStatic = newTraitDialog.getStatic(); m = new Multiname( Multiname.QNAME, abc.constants.getStringId(name, true), abc.constants.getNamespaceId( new Namespace(nskind, abc.constants.getStringId("", true)), 0, true), 0, 0, new ArrayList<>()); int mid = abc.constants.getMultinameId(m); if (mid == 0) { break; } for (Trait tr : abc.class_info.get(class_index).static_traits.traits) { if (tr.name_index == mid) { again = true; break; } } for (Trait tr : abc.instance_info.get(class_index).instance_traits.traits) { if (tr.name_index == mid) { again = true; break; } } } while (again); switch (kind) { case Trait.TRAIT_GETTER: case Trait.TRAIT_SETTER: case Trait.TRAIT_METHOD: TraitMethodGetterSetter tm = new TraitMethodGetterSetter(); MethodInfo mi = new MethodInfo( new int[0], void_type, abc.constants.getStringId(name, true), 0, new ValueKind[0], new int[0]); int method_info = abc.addMethodInfo(mi); tm.method_info = method_info; MethodBody body = new MethodBody(); body.method_info = method_info; body.init_scope_depth = 1; body.max_regs = 1; body.max_scope_depth = 1; body.max_stack = 1; body.exceptions = new ABCException[0]; AVM2Code code = new AVM2Code(); code.code.add(new AVM2Instruction(0, new GetLocal0Ins(), new int[0])); code.code.add(new AVM2Instruction(0, new PushScopeIns(), new int[0])); code.code.add(new AVM2Instruction(0, new ReturnVoidIns(), new int[0])); body.setCode(code); Traits traits = new Traits(); traits.traits = new ArrayList<>(); body.traits = traits; abc.addMethodBody(body); mi.setBody(body); t = tm; break; case Trait.TRAIT_SLOT: case Trait.TRAIT_CONST: TraitSlotConst ts = new TraitSlotConst(); ts.type_index = int_type; ts.value_kind = ValueKind.CONSTANT_Int; ts.value_index = abc.constants.getIntId(0, true); t = ts; break; } if (t != null) { t.kindType = kind; t.name_index = abc.constants.getMultinameId(m, true); int traitId; if (isStatic) { traitId = abc.class_info.get(class_index).static_traits.addTrait(t); } else { traitId = abc.class_info.get(class_index).static_traits.traits.size() + abc.instance_info.get(class_index).instance_traits.addTrait(t); } reload(); decompiledTextArea.gotoTrait(traitId); } } @Override public boolean tryAutoSave() { // todo: implement return false; } @Override public boolean isEditing() { return detailPanel.isEditing() || isModified(); } }