diff --git a/CHANGELOG.md b/CHANGELOG.md index b22501a40..9bccd101a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ All notable changes to this project will be documented in this file. - AS1/2/3 - highlight variables and errors on panel next to vertical scrollbar - AS1/2 direct editation - hide P-code panel when editing - Disable AS1/2/3 direct editation when editing P-code +- AS3 - navigation to definition in other SWF file and also player/airglobal ### Changed - AS1/2 - Single DoAction tag inside frame is now displayed directly as frame node diff --git a/lib/jsyntaxpane-0.9.5.jar b/lib/jsyntaxpane-0.9.5.jar index 9841945df..f390b1cc9 100644 Binary files a/lib/jsyntaxpane-0.9.5.jar and b/lib/jsyntaxpane-0.9.5.jar differ diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java index 33275ffab..ca5c88572 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java @@ -797,7 +797,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { if (Configuration.getPlayerSWC() != null) { SWC swc = new SWC(Configuration.getPlayerSWC()); //set allowRenameIdentifiers parameter to FALSE otherwise there will be an infinite loop - SWF swf = new SWF(swc.getOpenable("library.swf"), null, null, null, true, false, true, null, "WINDOWS-1252", false); + SWF swf = new SWF(swc.getOpenable("library.swf"), null, "__playerglobal", null, true, false, true, null, "WINDOWS-1252", false); playerGlobalAbcIndex = new AbcIndexing(swf); } } @@ -805,12 +805,12 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { if (Configuration.getAirSWC() != null) { SWC swc = new SWC(Configuration.getAirSWC()); //set allowRenameIdentifiers to FALSE - SWF swf = new SWF(swc.getOpenable("library.swf"), null, null, null, true, false, true, null, "WINDOWS-1252", false); + SWF swf = new SWF(swc.getOpenable("library.swf"), null, "__airglobal", null, true, false, true, null, "WINDOWS-1252", false); airGlobalAbcIndex = new AbcIndexing(swf); } } } - + /** * Gets SWF charset. SWF version 5 or lower were non-unicode. SWF object has * assigned charset. diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AbcIndexing.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AbcIndexing.java index f1553a623..a0821bb5f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AbcIndexing.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AbcIndexing.java @@ -384,6 +384,11 @@ public final class AbcIndexing { * Object type */ public GraphTargetItem objType; + + /** + * Script index + */ + public int scriptIndex; /** * Constructs trait index @@ -393,14 +398,16 @@ public final class AbcIndexing { * @param callType Call type * @param value Value * @param objType Object type + * @param scriptIndex Script index */ - public TraitIndex(Trait trait, ABC abc, GraphTargetItem type, GraphTargetItem callType, ValueKind value, GraphTargetItem objType) { + public TraitIndex(Trait trait, ABC abc, GraphTargetItem type, GraphTargetItem callType, ValueKind value, GraphTargetItem objType, int scriptIndex) { this.trait = trait; this.abc = abc; this.returnType = type; this.callReturnType = callType; this.value = value; this.objType = objType; + this.scriptIndex = scriptIndex; } } @@ -775,7 +782,7 @@ public final class AbcIndexing { */ //search all static first if (findStatic && classProperties.containsKey(prop)) { - TraitIndex ti = classProperties.get(prop); + TraitIndex ti = classProperties.get(prop); if (ti != null) { foundStatic.setVal(true); return ti; @@ -933,7 +940,7 @@ public final class AbcIndexing { * @param map Map to index * @param mapNs Map to index */ - protected void indexTraits(ABC abc, int name_index, Traits ts, Map map, Map mapNs) { + protected void indexTraits(ABC abc, int name_index, Traits ts, Map map, Map mapNs, int scriptIndex) { for (Trait t : ts.traits) { ValueKind propValue = null; if (t instanceof TraitSlotConst) { @@ -942,12 +949,12 @@ public final class AbcIndexing { } if (map != null) { PropertyDef dp = new PropertyDef(t.getName(abc).getName(abc.constants, new ArrayList<>() /*?*/, true, false), multinameToType(name_index, abc.constants), abc, abc.constants.getMultiname(t.name_index).namespace_index); - map.put(dp, new TraitIndex(t, abc, getTraitReturnType(abc, t), getTraitCallReturnType(abc, t), propValue, multinameToType(name_index, abc.constants))); + map.put(dp, new TraitIndex(t, abc, getTraitReturnType(abc, t), getTraitCallReturnType(abc, t), propValue, multinameToType(name_index, abc.constants), scriptIndex)); } if (mapNs != null) { Multiname m = abc.constants.getMultiname(t.name_index); PropertyNsDef ndp = new PropertyNsDef(t.getName(abc).getName(abc.constants, new ArrayList<>() /*?*/, true, true/*FIXME ???*/), m == null || m.namespace_index == 0 ? DottedChain.EMPTY : m.getNamespace(abc.constants).getName(abc.constants), abc, m == null ? 0 : m.namespace_index); - TraitIndex ti = new TraitIndex(t, abc, getTraitReturnType(abc, t), getTraitCallReturnType(abc, t), propValue, multinameToType(name_index, abc.constants)); + TraitIndex ti = new TraitIndex(t, abc, getTraitReturnType(abc, t), getTraitCallReturnType(abc, t), propValue, multinameToType(name_index, abc.constants), scriptIndex); if (!mapNs.containsKey(ndp)) { mapNs.put(ndp, ti); } @@ -1038,7 +1045,7 @@ public final class AbcIndexing { List addedClasses = new ArrayList<>(); for (int i = 0; i < abc.script_info.size(); i++) { - indexTraits(abc, 0, abc.script_info.get(i).traits, null, scriptProperties); + indexTraits(abc, 0, abc.script_info.get(i).traits, null, scriptProperties, i); for (int t = 0; t < abc.script_info.get(i).traits.traits.size(); t++) { Trait tr = abc.script_info.get(i).traits.traits.get(t); if (tr instanceof TraitClass) { @@ -1055,8 +1062,8 @@ public final class AbcIndexing { GraphTargetItem cname = multinameToType(ii.name_index, abc.constants); classes.put(new ClassDef(cname, abc, classScriptIndex), cindex); - indexTraits(abc, ii.name_index, ii.instance_traits, instanceProperties, instanceNsProperties); - indexTraits(abc, ii.name_index, ci.static_traits, classProperties, classNsProperties); + indexTraits(abc, ii.name_index, ii.instance_traits, instanceProperties, instanceNsProperties, i); + indexTraits(abc, ii.name_index, ci.static_traits, classProperties, classNsProperties, i); } } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3SimpleParser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3SimpleParser.java index 584fe9239..8e1b36bbe 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3SimpleParser.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3SimpleParser.java @@ -811,7 +811,8 @@ public class ActionScript3SimpleParser implements SimpleParser { List> allOpenedNamespaces, ABC abc, Reference sinitNeedsActivation, - List sinitVariables + List sinitVariables, + List externalTypes ) throws AVM2ParseException, SimpleParseException, IOException, CompilationException, InterruptedException { Stack sinitLoops = new Stack<>(); @@ -828,7 +829,8 @@ public class ActionScript3SimpleParser implements SimpleParser { sinitLoops, sinitLoopLabels, sinitRegisterVars, - sinitVariables + sinitVariables, + externalTypes )) { //empty } @@ -844,7 +846,8 @@ public class ActionScript3SimpleParser implements SimpleParser { Stack sinitLoops, Map sinitLoopLabels, HashMap sinitRegisterVars, - List sinitVariables + List sinitVariables, + List externalTypes ) throws AVM2ParseException, SimpleParseException, SimpleParseException, IOException, CompilationException, InterruptedException { ParsedSymbol s; boolean inPackage = false; @@ -872,7 +875,13 @@ public class ActionScript3SimpleParser implements SimpleParser { allOpenedNamespaces.add(openedNamespaces); - parseImportsUsages(errors, sinitVariables, importedClasses, openedNamespaces, abc); + for (String name : abc.getSwf().getAbcIndex().getPackageObjects(pkgName)) { + externalTypes.add(pkgName.add(name, "").toRawString()); + } + + + + parseImportsUsages(errors, sinitVariables, importedClasses, openedNamespaces, abc, externalTypes); boolean isEmpty = true; @@ -1061,7 +1070,7 @@ public class ActionScript3SimpleParser implements SimpleParser { lexer.pushback(preSymbols.get(i)); } - if (parseImportsUsages(errors, sinitVariables, importedClasses, openedNamespaces, abc)) { + if (parseImportsUsages(errors, sinitVariables, importedClasses, openedNamespaces, abc, externalTypes)) { break; } boolean cmd = command(errors, null, sinitNeedsActivation, importedClasses, openedNamespaces, sinitLoops, sinitLoopLabels, sinitRegisterVars, true, false, true, 0, false, sinitVariables, abc); @@ -2006,7 +2015,7 @@ public class ActionScript3SimpleParser implements SimpleParser { private ActionScriptLexer lexer = null; - private boolean parseImportsUsages(List errors, List variables, List importedClasses, List openedNamespaces, ABC abc) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException { + private boolean parseImportsUsages(List errors, List variables, List importedClasses, List openedNamespaces, ABC abc, List externalTypes) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException { boolean isEmpty = true; ParsedSymbol s; @@ -2023,6 +2032,8 @@ public class ActionScript3SimpleParser implements SimpleParser { s = lex(); boolean isStar = false; int varPos = -1; + List nameParts = new ArrayList<>(); + nameParts.add(lastName); while (s.type == SymbolType.DOT) { s = lex(); if (s.type == SymbolType.MULTIPLY) { @@ -2034,13 +2045,16 @@ public class ActionScript3SimpleParser implements SimpleParser { fullName = fullName + "." + s.value.toString(); lastName = s.value.toString(); varPos = s.position; + nameParts.add(lastName); s = lex(); } if (isStar) { - //openedNamespaces.add(new NamespaceItem(fullName, Namespace.KIND_PACKAGE)); + for (String n : abc.getSwf().getAbcIndex().getPackageObjects(new DottedChain(nameParts))) { + externalTypes.add(fullName + "." + n); + } } else { - //importedClasses.add(fullName); + externalTypes.add(fullName); variables.add(new Import(fullName, lastName, varPos)); } expected(errors, s, lexer.yyline(), SymbolType.SEMICOLON); @@ -2128,9 +2142,10 @@ public class ActionScript3SimpleParser implements SimpleParser { List> allOpenedNamespaces, ABC abc, Reference sinitNeedsActivation, - List sinitVariables + List sinitVariables, + List externalTypes ) throws IOException, AVM2ParseException, SimpleParseException, CompilationException, InterruptedException { - scriptTraits(errors, importedClasses, openedNamespaces, allOpenedNamespaces, abc, sinitNeedsActivation, sinitVariables); + scriptTraits(errors, importedClasses, openedNamespaces, allOpenedNamespaces, abc, sinitNeedsActivation, sinitVariables, externalTypes); } /** @@ -2157,11 +2172,12 @@ public class ActionScript3SimpleParser implements SimpleParser { String str, ABC abc, Reference sinitNeedsActivation, - List sinitVariables + List sinitVariables, + List externalTypes ) throws AVM2ParseException, SimpleParseException, IOException, CompilationException, InterruptedException { lexer = new ActionScriptLexer(str); - parseScript(errors, importedClasses, openedNamespaces, allOpenedNamespaces, abc, sinitNeedsActivation, sinitVariables); + parseScript(errors, importedClasses, openedNamespaces, allOpenedNamespaces, abc, sinitNeedsActivation, sinitVariables, externalTypes); ParsedSymbol s = lexer.lex(); if (s.type != SymbolType.EOF) { errors.add(new SimpleParseException("Parsing finished before end of the file", lexer.yyline(), s.position)); @@ -2173,15 +2189,22 @@ public class ActionScript3SimpleParser implements SimpleParser { String str, Map> definitionPosToReferences, Map referenceToDefinition, - List errors + List errors, + List externalTypes, + Map referenceToExternalTypeIndex, + Map> externalTypeIndexToReference ) throws SimpleParseException, IOException, InterruptedException { List> allOpenedNamespaces = new ArrayList<>(); Reference sinitNeedsActivation = new Reference<>(false); List vars = new ArrayList<>(); List importedClasses = new ArrayList<>(); List openedNamespaces = new ArrayList<>(); + for (String name : abc.getSwf().getAbcIndex().getPackageObjects(DottedChain.TOPLEVEL)) { + externalTypes.add(name); + } + externalTypes.add("__AS3__.vec.Vector"); try { - scriptTraitsFromString(errors, importedClasses, openedNamespaces, allOpenedNamespaces, str, abc, sinitNeedsActivation, vars); + scriptTraitsFromString(errors, importedClasses, openedNamespaces, allOpenedNamespaces, str, abc, sinitNeedsActivation, vars, externalTypes); } catch (AVM2ParseException ex) { //Logger.getLogger(ActionScript3SimpleParser.class.getName()).log(Level.SEVERE, null, ex); throw new SimpleParseException(str, ex.line, ex.position); @@ -2189,7 +2212,7 @@ public class ActionScript3SimpleParser implements SimpleParser { //Logger.getLogger(ActionScript3SimpleParser.class.getName()).log(Level.SEVERE, null, ex); throw new SimpleParseException(str, ex.line); } - SimpleParser.parseVariablesList(new ArrayList<>(), vars, definitionPosToReferences, referenceToDefinition, errors, true); + SimpleParser.parseVariablesList(new ArrayList<>(), vars, definitionPosToReferences, referenceToDefinition, errors, true, externalTypes, referenceToExternalTypeIndex, externalTypeIndexToReference); } /** diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionScript2SimpleParser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionScript2SimpleParser.java index 8d04f0d94..8d7f8ec5b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionScript2SimpleParser.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionScript2SimpleParser.java @@ -1570,9 +1570,12 @@ public class ActionScript2SimpleParser implements SimpleParser { String str, Map> definitionPosToReferences, Map referenceToDefinition, - List errors + List errors, + List externalTypes, + Map referenceToExternalTypeIndex, + Map> externalTypeIndexToReference ) throws SimpleParseException, IOException, InterruptedException { - + List vars = new ArrayList<>(); try { lexer = new ActionScriptLexer(new StringReader(str)); @@ -1661,7 +1664,7 @@ public class ActionScript2SimpleParser implements SimpleParser { } catch (ActionParseException ex) { errors.add(new SimpleParseException(ex.getMessage(), ex.line, ex.position)); } - SimpleParser.parseVariablesList(new ArrayList<>(), vars, definitionPosToReferences, referenceToDefinition, errors, false); + SimpleParser.parseVariablesList(new ArrayList<>(), vars, definitionPosToReferences, referenceToDefinition, errors, false, externalTypes, referenceToExternalTypeIndex, externalTypeIndexToReference); } private void versionRequired(List errors, ParsedSymbol s, int min) throws SimpleParseException { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java index 1289b0ba4..452868f6a 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java @@ -27,14 +27,9 @@ import com.jpexs.helpers.Helper; import com.jpexs.helpers.Path; import java.awt.Color; import java.awt.Font; -import java.io.BufferedOutputStream; import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.FilenameFilter; import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; import java.lang.reflect.Field; import java.net.URISyntaxException; import java.util.ArrayList; @@ -1145,6 +1140,11 @@ public final class Configuration { @ConfigurationDefaultBoolean(false) @ConfigurationCategory("display") public static ConfigurationItem snapAlignCenterAlignmentVertical = null; + + @ConfigurationDefaultBoolean(true) + @ConfigurationName("warning.linkTypes") + @ConfigurationCategory("script") + public static ConfigurationItem warningLinkTypes = null; private static Map configurationDescriptions = new LinkedHashMap<>(); private static Map configurationTitles = new LinkedHashMap<>(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/SimpleParser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/SimpleParser.java index 44b209fa9..6f03cf193 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/SimpleParser.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/SimpleParser.java @@ -45,7 +45,10 @@ public interface SimpleParser { String str, Map> definitionPosToReferences, Map referenceToDefinition, - List errors + List errors, + List externalTypes, + Map referenceToExternalTypeIndex, + Map> externalTypeIndexToReference ) throws SimpleParseException, IOException, InterruptedException; public static void parseVariablesList( @@ -54,9 +57,22 @@ public interface SimpleParser { Map> definitionPosToReferences, Map referenceToDefinition, List errors, - boolean innerFunctionCanUseTraits + boolean innerFunctionCanUseTraits, + List externalTypes, + Map referenceToExternalTypeIndex, + Map> externalTypeIndexToReference ) { - parseVariablesList(privateVariables, sharedVariables, definitionPosToReferences, referenceToDefinition, new LinkedHashMap<>(), new LinkedHashMap<>(), new LinkedHashMap<>(), true, errors, null, innerFunctionCanUseTraits); + List externalSimpleTypes = new ArrayList<>(); + for (String type : externalTypes) { + externalSimpleTypes.add(type.contains(".") ? type.substring(type.lastIndexOf(".") + 1) : type); + } + parseVariablesList(privateVariables, sharedVariables, definitionPosToReferences, referenceToDefinition, new LinkedHashMap<>(), new LinkedHashMap<>(), new LinkedHashMap<>(), true, errors, null, innerFunctionCanUseTraits, externalSimpleTypes, referenceToExternalTypeIndex); + for (Map.Entry entry : referenceToExternalTypeIndex.entrySet()) { + if (!externalTypeIndexToReference.containsKey(entry.getValue())) { + externalTypeIndexToReference.put(entry.getValue(), new ArrayList<>()); + } + externalTypeIndexToReference.get(entry.getValue()).add(entry.getKey()); + } } public static void parseVariablesList( @@ -70,7 +86,9 @@ public interface SimpleParser { boolean isStatic, List errors, Scope scope, - boolean innerFunctionCanUseTraits + boolean innerFunctionCanUseTraits, + List externalSimpleTypes, + Map referenceToExternalTypeIndex ) { Map privateVarNameToDefinitionPosition = new LinkedHashMap<>(); privateVarNameToDefinitionPosition.putAll(parentVarNameToDefinitionPosition); @@ -89,13 +107,18 @@ public interface SimpleParser { } else { if (!privateVarFullNameToDefinitionPosition.containsKey(v.name) && !privateVarNameToDefinitionPosition.containsKey(v.name)) { - parentVarFullNameToDefinitionPosition.put(v.name, -v.position - 1); - parentVarNameToDefinitionPosition.put(v.getLastName(), -v.position - 1); - privateVarFullNameToDefinitionPosition.put(v.name, -v.position - 1); - privateVarNameToDefinitionPosition.put(v.getLastName(), -v.position - 1); - definitionPosToReferences.put(-v.position - 1, new ArrayList<>()); - definitionPosToReferences.get(-v.position - 1).add(v.position); - referenceToDefinition.put(v.position, -v.position - 1); + + if (externalSimpleTypes.contains(v.name)) { + referenceToExternalTypeIndex.put(v.position, externalSimpleTypes.indexOf(v.name)); + } else { + parentVarFullNameToDefinitionPosition.put(v.name, -v.position - 1); + parentVarNameToDefinitionPosition.put(v.getLastName(), -v.position - 1); + privateVarFullNameToDefinitionPosition.put(v.name, -v.position - 1); + privateVarNameToDefinitionPosition.put(v.getLastName(), -v.position - 1); + definitionPosToReferences.put(-v.position - 1, new ArrayList<>()); + definitionPosToReferences.get(-v.position - 1).add(v.position); + referenceToDefinition.put(v.position, -v.position - 1); + } } else { if ("this".equals(v.name) && isStatic) { @@ -149,7 +172,7 @@ public interface SimpleParser { } } - parseVariablesList(vs.getPrivateItems(), vs.getSharedItems(), definitionPosToReferences, referenceToDefinition, subPrivateVarFullNameToDefinitionPosition, subPrivateVarNameToDefinitionPosition, positionToStatic, subStatic, errors, vs, innerFunctionCanUseTraits); + parseVariablesList(vs.getPrivateItems(), vs.getSharedItems(), definitionPosToReferences, referenceToDefinition, subPrivateVarFullNameToDefinitionPosition, subPrivateVarNameToDefinitionPosition, positionToStatic, subStatic, errors, vs, innerFunctionCanUseTraits, externalSimpleTypes, referenceToExternalTypeIndex); } } for (VariableOrScope vt : sharedVariables) { @@ -165,13 +188,18 @@ public interface SimpleParser { } else { if (!privateVarFullNameToDefinitionPosition.containsKey(v.name) && !privateVarNameToDefinitionPosition.containsKey(v.name)) { - parentVarFullNameToDefinitionPosition.put(v.name, -v.position - 1); - parentVarNameToDefinitionPosition.put(v.getFirstName(), -v.position - 1); - privateVarFullNameToDefinitionPosition.put(v.name, -v.position - 1); - privateVarNameToDefinitionPosition.put(v.getFirstName(), -v.position - 1); - definitionPosToReferences.put(-v.position - 1, new ArrayList<>()); - definitionPosToReferences.get(-v.position - 1).add(v.position); - referenceToDefinition.put(v.position, -v.position - 1); + + if (externalSimpleTypes.contains(v.name)) { + referenceToExternalTypeIndex.put(v.position, externalSimpleTypes.indexOf(v.name)); + } else { + parentVarFullNameToDefinitionPosition.put(v.name, -v.position - 1); + parentVarNameToDefinitionPosition.put(v.getFirstName(), -v.position - 1); + privateVarFullNameToDefinitionPosition.put(v.name, -v.position - 1); + privateVarNameToDefinitionPosition.put(v.getFirstName(), -v.position - 1); + definitionPosToReferences.put(-v.position - 1, new ArrayList<>()); + definitionPosToReferences.get(-v.position - 1).add(v.position); + referenceToDefinition.put(v.position, -v.position - 1); + } } else { if ("this".equals(v.name) && isStatic) { @@ -225,7 +253,7 @@ public interface SimpleParser { } } - parseVariablesList(vs.getPrivateItems(), vs.getSharedItems(), definitionPosToReferences, referenceToDefinition, privateVarFullNameToDefinitionPosition, privateVarNameToDefinitionPosition, positionToStatic, subStatic, errors, vs, innerFunctionCanUseTraits); + parseVariablesList(vs.getPrivateItems(), vs.getSharedItems(), definitionPosToReferences, referenceToDefinition, privateVarFullNameToDefinitionPosition, privateVarNameToDefinitionPosition, positionToStatic, subStatic, errors, vs, innerFunctionCanUseTraits, externalSimpleTypes, referenceToExternalTypeIndex); } } } diff --git a/src/com/jpexs/decompiler/flash/gui/Main.java b/src/com/jpexs/decompiler/flash/gui/Main.java index 4773d8426..e0d21ae5d 100644 --- a/src/com/jpexs/decompiler/flash/gui/Main.java +++ b/src/com/jpexs/decompiler/flash/gui/Main.java @@ -1998,7 +1998,13 @@ public class Main { } swfFile = file.getCanonicalPath(); OpenableSourceInfo sourceInfo = new OpenableSourceInfo(null, swfFile, fileTitle); - OpenFileResult openResult = openFile(sourceInfo); + OpenFileResult openResult = openFile(sourceInfo, new OpenableOpened() { + @Override + public void opened(Openable openable) { + executeAfterOpen.run(); + } + } + ); return openResult; } catch (IOException ex) { ViewMessages.showMessageDialog(getDefaultMessagesComponent(), AppStrings.translate("open.error.cannotOpen"), AppStrings.translate("open.error"), JOptionPane.ERROR_MESSAGE); diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java index c2bbf2413..c5bda142c 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -238,6 +238,7 @@ import java.awt.event.KeyEvent; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; @@ -322,7 +323,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se private ClipboardPanel resourcesClipboardPanel; private ClipboardPanel tagListClipboardPanel; - + private final JPanel contentPanel; private final JPanel displayPanel; @@ -435,13 +436,13 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se private Map abcExplorerDialogs = new WeakHashMap<>(); private Map breakpointsListDialogs = new WeakHashMap<>(); - + private boolean loadingScrollPosEnabled = true; public synchronized void setLoadingScrollPosEnabled(boolean loadingScrollPosEnabled) { this.loadingScrollPosEnabled = loadingScrollPosEnabled; - } - + } + public void savePins() { pinsPanel.save(); } @@ -1489,7 +1490,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se easyPanel.setSwfs(new ArrayList<>(getAllSwfs())); hideWelcomeScreen(); - + gcClipboard(); reload(false); @@ -1556,7 +1557,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se break; } } - + private void hideWelcomeScreen() { if (isWelcomeScreen) { if (currentView == VIEW_EASY) { @@ -1567,9 +1568,9 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se isWelcomeScreen = false; } } - + private void updateUi(final Openable openable) { - View.checkAccess(); + View.checkAccess(); SWF swf = null; if (openable instanceof SWF) { swf = (SWF) openable; @@ -1602,7 +1603,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se Thread t = new Thread() { @Override public void run() { - while (!Thread.currentThread().isInterrupted()) { + while (!Thread.currentThread().isInterrupted()) { DecompilerPool d = fSwf.getDecompilerPool(); statusPanel.setStatus(fSwf.getFileTitle() + " " + d.getStat()); try { @@ -1627,14 +1628,14 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se isWelcomeScreen = true; quickTagListFindPanel.setVisible(false); quickTreeFindPanel.setVisible(false); - doFilter(); + doFilter(); } mainFrame.setTitle(ApplicationInfo.applicationVerName); mainMenu.updateComponents(null); showView(getCurrentView()); - + if (taskThread != null) { taskThread.interrupt(); taskThread = null; @@ -1736,7 +1737,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se mainMenu.updateComponents(null); folderPreviewPanel.clear(); folderListPanel.clear(); - previewPanel.clear(); + previewPanel.clear(); tagInfoPanel.clear(); dumpPreviewPanel.clear(); @@ -1808,45 +1809,44 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se if (breakpointsListDialog != null) { breakpointsListDialog.setVisible(false); breakpointsListDialogs.remove(swf); - } + } int index = easyPanel.indexOf(swf); if (index < minEasyIndex) { minEasyIndex = index; } - } - + } + minEasyIndex--; if (minEasyIndex < 0) { minEasyIndex = 0; SWF s = easyPanel.getSwfAtIndex(minEasyIndex); while (s != null && swfsToClose.contains(s)) { minEasyIndex++; - s = easyPanel.getSwfAtIndex(minEasyIndex); + s = easyPanel.getSwfAtIndex(minEasyIndex); } } - + openables.remove(openableList); oldItem = null; clear(); - + Set newSwfs = getAllSwfs(); - + SWF newEasySwf = null; if (minEasyIndex < newSwfs.size()) { easyPanel.setSwfIndex(minEasyIndex); newEasySwf = easyPanel.getSwf(); } - + easyPanel.setSwfs(new ArrayList<>(newSwfs)); easyPanel.setSwf(newEasySwf); - - if (currentView == VIEW_EASY) { + + if (currentView == VIEW_EASY) { updateUi(newEasySwf); - } else { + } else { updateUi(); } - - + for (SWF swf : swfsToClose) { swf.clearTagSwfs(); } @@ -1863,21 +1863,21 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se folderPreviewPanel.clear(); folderListPanel.clear(); - previewPanel.clear(); + previewPanel.clear(); tagInfoPanel.clear(); dumpPreviewPanel.clear(); - + List> nodes; - + //To properly clear cached TreePaths nodes = View.getExpandedNodes(tagTree); tagTree.setModel(tagTree.getFullModel()); View.expandTreeNodes(tagTree, nodes); - + nodes = View.getExpandedNodes(tagListTree); tagListTree.setModel(tagListTree.getFullModel()); View.expandTreeNodes(tagListTree, nodes); - + doFilter(); return true; } @@ -2699,6 +2699,25 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se gotoScriptName(swf, scriptName); } + public void findOrLoadOpanableListByFilePath(String filePath, OpenableListLoaded executeAfterOpen) { + for (OpenableList ol : openables) { + String existingFilePath = ol.sourceInfo.getFile(); + if (existingFilePath == null) { + continue; + } + if (new File(filePath).getAbsolutePath().equals(new File(existingFilePath).getAbsolutePath())) { + executeAfterOpen.openableListLoaded(ol); + return; + } + } + Main.openFile(filePath, null, new Runnable() { + @Override + public void run() { + findOrLoadOpanableListByFilePath(filePath, executeAfterOpen); + } + }); + } + public void gotoScriptLine(SWF swf, String scriptName, int line, int classIndex, int traitIndex, int methodIndex, boolean pcode) { View.checkAccess(); @@ -5508,9 +5527,8 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se } else { /*if (openable == null && openables.get(0) != null) { openable = openables.get(0).get(0); - }*/ - - /*if (openable != null) { + } + if (openable != null) { updateUi(openable); }*/ updateUi(openable); @@ -5545,7 +5563,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se @Override public void valueChanged(TreeSelectionEvent e) { - JTree source = (JTree) e.getSource(); + JTree source = (JTree) e.getSource(); valueChanged(source, source.getSelectionPath()); } @@ -5601,7 +5619,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se } } return null; - } + } public void clearDebuggerColors() { if (abcPanel != null) { @@ -5612,7 +5630,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se actionPanel.decompiledEditor.removeColorMarkerOnAllLines(DecompiledEditorPane.IP_MARKER); actionPanel.editor.removeColorMarkerOnAllLines(DecompiledEditorPane.IP_MARKER); } - } + } public static final int VIEW_RESOURCES = 0; @@ -5869,7 +5887,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se if (treeItem instanceof SWF) { SWF swf = (SWF) treeItem; - previewPanel.showImagePanel(swf, swf, -1, true, Configuration.autoPlaySwfs.get() && Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), false, !Configuration.playFrameSounds.get(), true, false, true, false, true); + previewPanel.showImagePanel(swf, swf, -1, true, Configuration.autoPlaySwfs.get() && Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), false, !Configuration.playFrameSounds.get(), true, false, true, false, true); } else if ((treeItem instanceof PlaceObjectTypeTag)) { previewPanel.showDisplayEditTagPanel((PlaceObjectTypeTag) treeItem, frame); } else if (treeItem instanceof ShapeTag) { @@ -6164,7 +6182,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se treeItem = ((TagScript) treeItem).getTag(); preferScript = true; } - + if (treeItem instanceof FrameScript) { FrameScript fs = (FrameScript) treeItem; DoActionTag doAction = fs.getSingleDoActionTag(); @@ -6175,7 +6193,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se folderPreviewPanel.clear(); folderListPanel.clear(); - previewPanel.clear(); + previewPanel.clear(); tagInfoPanel.clear(); previewPanel.setImageReplaceButtonVisible(false, false, false, false, false, false, false); @@ -6367,7 +6385,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se folderPreviewPanel.setSelectedItems(folderItems); folderPreviewScrollBar.setValue(scrollValue); } - + if (loadingScrollPosEnabled) { View.execInEventDispatchLater(new Runnable() { @Override @@ -6378,8 +6396,6 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se } } - - public void repaintTree() { tagTree.repaint(); tagListTree.repaint(); diff --git a/src/com/jpexs/decompiler/flash/gui/OpenableListLoaded.java b/src/com/jpexs/decompiler/flash/gui/OpenableListLoaded.java new file mode 100644 index 000000000..69748ce63 --- /dev/null +++ b/src/com/jpexs/decompiler/flash/gui/OpenableListLoaded.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 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; + +import com.jpexs.decompiler.flash.treeitems.OpenableList; + +/** + * + * @author JPEXS + */ +public interface OpenableListLoaded { + public void openableListLoaded(OpenableList openableList); +} diff --git a/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java b/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java index 9068e849e..7e2975acc 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java @@ -20,6 +20,7 @@ import com.jpexs.debugger.flash.Variable; import com.jpexs.debugger.flash.VariableFlags; import com.jpexs.debugger.flash.VariableType; import com.jpexs.debugger.flash.messages.in.InGetVariable; +import com.jpexs.decompiler.flash.SWC; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.abc.ABC; import com.jpexs.decompiler.flash.abc.ClassPath; @@ -27,6 +28,7 @@ import com.jpexs.decompiler.flash.abc.ScriptPack; import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions; +import com.jpexs.decompiler.flash.abc.avm2.parser.script.AbcIndexing; import com.jpexs.decompiler.flash.abc.avm2.parser.script.ActionScript3SimpleParser; import com.jpexs.decompiler.flash.abc.types.ABCException; import com.jpexs.decompiler.flash.abc.types.MethodBody; @@ -58,6 +60,8 @@ import com.jpexs.decompiler.flash.gui.FasterScrollPane; import com.jpexs.decompiler.flash.gui.HeaderLabel; import com.jpexs.decompiler.flash.gui.Main; import com.jpexs.decompiler.flash.gui.MainPanel; +import com.jpexs.decompiler.flash.gui.OpenableListLoaded; +import com.jpexs.decompiler.flash.gui.OpenableOpened; import com.jpexs.decompiler.flash.gui.PopupButton; import com.jpexs.decompiler.flash.gui.SearchListener; import com.jpexs.decompiler.flash.gui.SearchPanel; @@ -71,6 +75,7 @@ import com.jpexs.decompiler.flash.gui.editor.VariableMarker; import com.jpexs.decompiler.flash.gui.tagtree.AbstractTagTree; import com.jpexs.decompiler.flash.gui.tagtree.AbstractTagTreeModel; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; +import com.jpexs.decompiler.flash.helpers.hilight.Highlighting; import com.jpexs.decompiler.flash.importers.As3ScriptReplaceException; import com.jpexs.decompiler.flash.importers.As3ScriptReplaceExceptionItem; import com.jpexs.decompiler.flash.importers.As3ScriptReplacerInterface; @@ -86,6 +91,7 @@ import com.jpexs.decompiler.flash.treeitems.AS3ClassTreeItem; import com.jpexs.decompiler.flash.treeitems.Openable; import com.jpexs.decompiler.flash.treeitems.OpenableList; import com.jpexs.decompiler.flash.treeitems.TreeItem; +import com.jpexs.decompiler.graph.TypeItem; import com.jpexs.helpers.CancellableWorker; import com.jpexs.helpers.Helper; import com.jpexs.helpers.Reference; @@ -207,7 +213,7 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener swfRef = new Reference<>(null); + Runnable gotoScriptRunnable = new Runnable() { + @Override + public void run() { + hilightScript(swfRef.getVal(), scriptName); + } + }; + + OpenableListLoaded afterOpen = new OpenableListLoaded() { + @Override + public void openableListLoaded(OpenableList openableList) { + for (Openable op : openableList.items) { + if (op instanceof SWF) { + SWF swf = (SWF) op; + if ("library.swf".equals(swf.getFileTitle())) { + swfRef.setVal(swf); + gotoScriptRunnable.run(); + return; + } + } + } + } + }; + + SWF swf = ci.abc.getSwf(); + if (swf.getFile() == null && "__playerglobal".equals(swf.getFileTitle())) { + mainPanel.findOrLoadOpanableListByFilePath(Configuration.getPlayerSWC().getAbsolutePath(), afterOpen); + } else if (swf.getFile() == null && "__airglobal".equals(swf.getFileTitle())) { + mainPanel.findOrLoadOpanableListByFilePath(Configuration.getAirSWC().getAbsolutePath(), afterOpen); + } else { + swfRef.setVal(swf); + gotoScriptRunnable.run(); + } + + //other file + } }); decompiledTextArea.addScriptListener(new Runnable() { @Override @@ -1180,7 +1252,7 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener multinameIndexRef = new Reference<>(0); Reference classTrait = new Reference<>(false); Reference usedAbcRef = new Reference<>(null); + Reference scriptIndexRef = new Reference<>(-1); if (getSwf() == null) { return LinkType.NO_LINK; } - LinkType propLinkType = decompiledTextArea.getPropertyTypeAtPos(getSwf().getAbcIndex(), pos, abcIndex, classIndex, traitIndex, classTrait, multinameIndexRef, usedAbcRef, false); + LinkType propLinkType = decompiledTextArea.getPropertyTypeAtPos(getSwf().getAbcIndex(), pos, abcIndex, classIndex, traitIndex, classTrait, multinameIndexRef, usedAbcRef, false, scriptIndexRef); if (propLinkType != LinkType.NO_LINK) { - return propLinkType; - } + if (usedAbcRef.getVal() == abc && scriptIndexRef.getVal() == decompiledTextArea.getScriptIndex()) { + return LinkType.LINK_THIS_SCRIPT; + } + return propLinkType; + } ABC usedAbc = usedAbcRef.getVal(); int multinameIndex = decompiledTextArea.getMultinameAtPos(pos, usedAbcRef); if (multinameIndex > -1) { @@ -1294,7 +1370,10 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener(null)) != -1 ? LinkType.LINK_OTHER_SCRIPT : LinkType.NO_LINK; + Reference linkTypeRef = new Reference<>(null); + decompiledTextArea.getLocalDeclarationOfPos(pos, new Reference<>(null), linkTypeRef); + + return linkTypeRef.getVal(); } private void gotoDeclaration(int pos) { @@ -1305,8 +1384,9 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener traitIndex = new Reference<>(0); Reference classTrait = new Reference<>(false); Reference multinameIndexRef = new Reference<>(0); + Reference scriptIndexRef = new Reference<>(-1); Reference usedAbcRef = new Reference<>(null); - if (decompiledTextArea.getPropertyTypeAtPos(getSwf().getAbcIndex(), pos, abcIndex, classIndex, traitIndex, classTrait, multinameIndexRef, usedAbcRef, false) != LinkType.NO_LINK) { + if (decompiledTextArea.getPropertyTypeAtPos(getSwf().getAbcIndex(), pos, abcIndex, classIndex, traitIndex, classTrait, multinameIndexRef, usedAbcRef, false, scriptIndexRef) != LinkType.NO_LINK) { UsageFrame.gotoUsage(ABCPanel.this, new TraitMultinameUsage(getAbcList().get(abcIndex.getVal()).getABC(), multinameIndexRef.getVal(), decompiledTextArea.getScriptLeaf().scriptIndex, classIndex.getVal(), traitIndex.getVal(), classTrait.getVal() ? TraitMultinameUsage.TRAITS_TYPE_CLASS : TraitMultinameUsage.TRAITS_TYPE_INSTANCE, null, -1) { }); return; @@ -1348,7 +1428,7 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener(null)); + int dpos = decompiledTextArea.getLocalDeclarationOfPos(pos, new Reference<>(null), new Reference<>(null)); if (dpos > -1) { decompiledTextArea.setCaretPosition(dpos); } diff --git a/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java b/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java index 1cd3c45c7..143c65ad9 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java @@ -285,16 +285,18 @@ public class DecompiledEditorPane extends DebuggableEditorPane implements CaretL return getMultinameAtPos(getCaretPosition(), abcUsed); } - public int getLocalDeclarationOfPos(int pos, Reference type) { + public int getLocalDeclarationOfPos(int pos, Reference type, Reference linkTypeRef) { Highlighting sh = Highlighting.searchPos(highlightedText.getSpecialHighlights(), pos); Highlighting h = Highlighting.searchPos(highlightedText.getInstructionHighlights(), pos); if (h == null) { + linkTypeRef.setVal(LinkType.NO_LINK); return -1; } List tms = Highlighting.searchAllPos(highlightedText.getMethodHighlights(), pos); if (tms.isEmpty()) { + linkTypeRef.setVal(LinkType.NO_LINK); return -1; } for (Highlighting tm : tms) { @@ -302,6 +304,7 @@ public class DecompiledEditorPane extends DebuggableEditorPane implements CaretL List tm_tms = Highlighting.searchAllIndexes(highlightedText.getMethodHighlights(), tm.getProperties().index); //is it already declaration? if (h.getProperties().declaration || (sh != null && sh.getProperties().declaration)) { + linkTypeRef.setVal(LinkType.NO_LINK); return -1; //no jump } @@ -311,6 +314,7 @@ public class DecompiledEditorPane extends DebuggableEditorPane implements CaretL int cindex = (int) ch.getProperties().index; ABC abc = getABC(); type.setVal(abc.instance_info.get(cindex).getName(abc.constants).getNameWithNamespace(abc.constants, true)); + linkTypeRef.setVal(LinkType.LINK_THIS_SCRIPT); return ch.startPos; } @@ -321,6 +325,7 @@ public class DecompiledEditorPane extends DebuggableEditorPane implements CaretL search.localName = hData.localName; search.specialValue = hData.specialValue; if (search.isEmpty()) { + linkTypeRef.setVal(LinkType.NO_LINK); return -1; } search.declaration = true; @@ -332,15 +337,17 @@ public class DecompiledEditorPane extends DebuggableEditorPane implements CaretL } if (rh != null) { type.setVal(rh.getProperties().declaredType); + linkTypeRef.setVal(LinkType.LINK_OTHER_SCRIPT); return rh.startPos; } } } + linkTypeRef.setVal(LinkType.NO_LINK); return -1; } - public LinkType getPropertyTypeAtPos(AbcIndexing indexing, int pos, Reference abcIndex, Reference classIndex, Reference traitIndex, Reference classTrait, Reference multinameIndex, Reference abcUsed, boolean currentSwfOnly) { + public LinkType getPropertyTypeAtPos(AbcIndexing indexing, int pos, Reference abcIndex, Reference classIndex, Reference traitIndex, Reference classTrait, Reference multinameIndex, Reference abcUsed, boolean currentSwfOnly, Reference scriptIndexRef) { int m = getMultinameAtPos(pos, true, abcUsed); @@ -353,7 +360,7 @@ public class DecompiledEditorPane extends DebuggableEditorPane implements CaretL }*/ SyntaxDocument sd = (SyntaxDocument) getDocument(); Token t = sd.getTokenAt(pos + 1); - Token lastToken = t; + Token lastToken = t; Token prev; String propName = t.getString(sd); if (!(t.type == TokenType.IDENTIFIER || t.type == TokenType.KEYWORD || t.type == TokenType.REGEX)) { @@ -382,7 +389,8 @@ public class DecompiledEditorPane extends DebuggableEditorPane implements CaretL if (propertyTraitIndex == null) { return LinkType.NO_LINK; } - + scriptIndexRef.setVal(propertyTraitIndex.scriptIndex); + List abcs = getABC().getSwf().getAbcList(); int index = 0; boolean isCurrentSwf = false; diff --git a/src/com/jpexs/decompiler/flash/gui/editor/LineMarkedEditorPane.java b/src/com/jpexs/decompiler/flash/gui/editor/LineMarkedEditorPane.java index cc836204f..504de7bab 100644 --- a/src/com/jpexs/decompiler/flash/gui/editor/LineMarkedEditorPane.java +++ b/src/com/jpexs/decompiler/flash/gui/editor/LineMarkedEditorPane.java @@ -67,13 +67,20 @@ public class LineMarkedEditorPane extends UndoFixedEditorPane implements LinkHan private boolean error = false; - private Token lastUnderlined = null; - private LinkHandler linkHandler = this; - private Point lastCursorPos = new Point(0, 0); private SimpleParser parser; + + @Override + public LinkType getExternalTypeLinkType(String className) { + return LinkType.NO_LINK; + } + + @Override + public void handleExternalTypeLink(String className) { + + } public static class LineMarker implements Comparable { @@ -383,7 +390,7 @@ public class LineMarkedEditorPane extends UndoFixedEditorPane implements LinkHan } @Override - public LinkType isLink(Token token) { + public LinkType getLinkType(Token token) { return LinkType.NO_LINK; } diff --git a/src/com/jpexs/decompiler/flash/gui/editor/LinkHandler.java b/src/com/jpexs/decompiler/flash/gui/editor/LinkHandler.java index 100f8ddf4..72d78c3f6 100644 --- a/src/com/jpexs/decompiler/flash/gui/editor/LinkHandler.java +++ b/src/com/jpexs/decompiler/flash/gui/editor/LinkHandler.java @@ -24,9 +24,13 @@ import jsyntaxpane.Token; */ public interface LinkHandler { - public LinkType isLink(Token token); + public LinkType getLinkType(Token token); + + public LinkType getExternalTypeLinkType(String className); public void handleLink(Token token); + public void handleExternalTypeLink(String className); + public Highlighter.HighlightPainter linkPainter(); } diff --git a/src/com/jpexs/decompiler/flash/gui/editor/VariableMarker.java b/src/com/jpexs/decompiler/flash/gui/editor/VariableMarker.java index c524d5839..f1b57685f 100644 --- a/src/com/jpexs/decompiler/flash/gui/editor/VariableMarker.java +++ b/src/com/jpexs/decompiler/flash/gui/editor/VariableMarker.java @@ -17,12 +17,21 @@ package com.jpexs.decompiler.flash.gui.editor; import com.jpexs.decompiler.flash.gui.AppStrings; +import com.jpexs.decompiler.flash.gui.Main; import com.jpexs.decompiler.flash.gui.View; +import com.jpexs.decompiler.flash.gui.ViewMessages; import com.jpexs.decompiler.flash.simpleparser.SimpleParseException; import com.jpexs.decompiler.flash.simpleparser.SimpleParser; +import com.sun.java.swing.action.ViewMenu; import java.awt.BorderLayout; import java.awt.Color; +import java.awt.Component; import java.awt.Cursor; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; import java.awt.KeyEventPostProcessor; import java.awt.KeyboardFocusManager; import java.awt.Point; @@ -46,7 +55,12 @@ import java.util.Timer; import java.util.TimerTask; import java.util.logging.Logger; import javax.swing.AbstractAction; +import javax.swing.BorderFactory; +import javax.swing.BoxLayout; +import javax.swing.JCheckBox; import javax.swing.JEditorPane; +import javax.swing.JLabel; +import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollBar; import javax.swing.JScrollPane; @@ -60,6 +74,7 @@ import javax.swing.plaf.ScrollPaneUI; import javax.swing.plaf.basic.BasicScrollPaneUI; import javax.swing.text.BadLocationException; import javax.swing.text.Highlighter; +import javax.swing.text.Segment; import jsyntaxpane.SyntaxDocument; import jsyntaxpane.Token; import jsyntaxpane.TokenType; @@ -81,8 +96,6 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC private static final Color DEFAULT_COLOR = new Color(0xffeedd); private static final Color DEFAULT_ERRORCOLOR = new Color(0xff0000); - private static final Color SCROLLBAR_VARIABLE_COLOR = new Color(0xb59070); - private static final Color SCROLLBAR_ERROR_COLOR = new Color(0xff0000); private JEditorPane pane; private final Set tokenTypes = new HashSet<>(); private OccurencesMarker marker; @@ -94,6 +107,9 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC private Map> definitionPosToReferences = new LinkedHashMap<>(); private Map referenceToDefinition = new LinkedHashMap<>(); + private List externalTypes = new ArrayList<>(); + private Map referenceToExternalTypeIndex = new LinkedHashMap<>(); + private Map> externalTypeIndexToReference = new LinkedHashMap<>(); private MouseMotionAdapter mouseMotionAdapter; @@ -109,13 +125,23 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC private Set occurencesPositions = new HashSet<>(); - private UnderlinePainter underLinePainter = new UnderlinePainter(new Color(0, 0, 255), null); - private UnderlinePainter underLineMarkOccurencesPainter = new UnderlinePainter(new Color(0, 0, 255), DEFAULT_COLOR); - private UnderlinePainter underLineExternalPainter = new UnderlinePainter(new Color(0, 255, 0), null); - private UnderlinePainter underLineExternalMarkOccurencesPainter = new UnderlinePainter(new Color(0, 255, 0), DEFAULT_COLOR); + private Color basicUnderlineColor = new Color(0, 0, 255); + private Color otherScriptUnderlineColor = new Color(0, 255, 0); + private Color otherFileUnderlineColor = new Color(255, 0, 255); + + private UnderlinePainter underLinePainter = new UnderlinePainter(basicUnderlineColor, null); + private UnderlinePainter underLineMarkOccurencesPainter = new UnderlinePainter(basicUnderlineColor, DEFAULT_COLOR); + + private UnderlinePainter underLineOtherScriptPainter = new UnderlinePainter(otherScriptUnderlineColor, null); + private UnderlinePainter underLineOtherScriptMarkOccurencesPainter = new UnderlinePainter(otherScriptUnderlineColor, DEFAULT_COLOR); + + private UnderlinePainter underLineOtherFilePainter = new UnderlinePainter(otherFileUnderlineColor, null); + private UnderlinePainter underLineOtherFileMarkOccurencesPainter = new UnderlinePainter(otherFileUnderlineColor, DEFAULT_COLOR); private Token lastUnderlined; - private LinkType lastUnderlinedLinkType = LinkType.NO_LINK; + private LinkType lastUnderlinedLinkType = LinkType.NO_LINK; + + private boolean goingOut = false; /** * Constructs a new Token highlighter @@ -131,12 +157,6 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC public void markTokenAt(int pos) { SyntaxDocument doc = ActionUtils.getSyntaxDocument(pane); if (doc != null) { - Token everyToken = getNearestTokenAt(doc, pos); - if (everyToken != null) { - if (errors.containsKey(everyToken.start)) { - //System.err.println(errors.get(everyToken.start)); - } - } Token token = getIdentifierTokenAt(doc, pos); removeMarkers(); if (token != null && tokenTypes.contains(token.type)) { @@ -153,8 +173,10 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC Markers.removeMarkers(pane, marker); Markers.removeMarkers(pane, underLinePainter); Markers.removeMarkers(pane, underLineMarkOccurencesPainter); - Markers.removeMarkers(pane, underLineExternalPainter); - Markers.removeMarkers(pane, underLineExternalMarkOccurencesPainter); + Markers.removeMarkers(pane, underLineOtherScriptPainter); + Markers.removeMarkers(pane, underLineOtherScriptMarkOccurencesPainter); + Markers.removeMarkers(pane, underLineOtherFilePainter); + Markers.removeMarkers(pane, underLineOtherFileMarkOccurencesPainter); occurencesPositions.clear(); } @@ -241,15 +263,38 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC int definitionPos = tok.start; if (referenceToDefinition.containsKey(tok.start)) { definitionPos = referenceToDefinition.get(tok.start); + } else { + if (referenceToExternalTypeIndex.containsKey(tok.start)) { + int typeIndex = referenceToExternalTypeIndex.get(tok.start); + for (int i : externalTypeIndexToReference.get(typeIndex)) { + Token referenceToken = getIdentifierTokenAt(sDoc, i); + if (referenceToken != null) { + Markers.SimpleMarker markerKind = marker; + if (lastUnderlined == referenceToken) { + if (lastUnderlinedLinkType == LinkType.LINK_OTHER_SCRIPT) { + markerKind = underLineOtherScriptMarkOccurencesPainter; + } else if (lastUnderlinedLinkType == LinkType.LINK_OTHER_FILE) { + markerKind = underLineOtherFileMarkOccurencesPainter; + } else { + markerKind = underLineMarkOccurencesPainter; + } + } + Markers.markToken(pane, referenceToken, markerKind); + occurencesPositions.add(referenceToken.start); + } + } + sDoc.readUnlock(); + return; + } } Token definitionToken = getIdentifierTokenAt(sDoc, definitionPos < 0 ? -(definitionPos + 1) : definitionPos); if (definitionToken != null) { if (definitionPosToReferences.containsKey(definitionPos)) { - + Markers.SimpleMarker markerKind = marker; if (lastUnderlined == definitionToken) { if (lastUnderlinedLinkType == LinkType.LINK_OTHER_SCRIPT) { - markerKind = underLineExternalMarkOccurencesPainter; + markerKind = underLineOtherScriptMarkOccurencesPainter; } else { markerKind = underLineMarkOccurencesPainter; } @@ -264,7 +309,9 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC markerKind = marker; if (lastUnderlined == referenceToken) { if (lastUnderlinedLinkType == LinkType.LINK_OTHER_SCRIPT) { - markerKind = underLineExternalMarkOccurencesPainter; + markerKind = underLineOtherScriptMarkOccurencesPainter; + } else if (lastUnderlinedLinkType == LinkType.LINK_OTHER_FILE) { + markerKind = underLineOtherFileMarkOccurencesPainter; } else { markerKind = underLineMarkOccurencesPainter; } @@ -364,8 +411,7 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC handleLink(token); } }, "find-declaration", AppStrings.translate("abc.action.find-declaration"), "control B"); - - + documentUpdated(); markTokenAt(editor.getCaretPosition()); status = Status.INSTALLING; @@ -399,6 +445,9 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC } private void update() { + if (goingOut) { + return; + } if (lastCursorPos == null) { return; } @@ -409,9 +458,11 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC if (t == null || lastUnderlined == null || !t.equals(lastUnderlined)) { MyMarkers.removeMarkers(pane, underLinePainter); MyMarkers.removeMarkers(pane, underLineMarkOccurencesPainter); - MyMarkers.removeMarkers(pane, underLineExternalPainter); - MyMarkers.removeMarkers(pane, underLineExternalMarkOccurencesPainter); - + MyMarkers.removeMarkers(pane, underLineOtherScriptPainter); + MyMarkers.removeMarkers(pane, underLineOtherScriptMarkOccurencesPainter); + MyMarkers.removeMarkers(pane, underLineOtherFilePainter); + MyMarkers.removeMarkers(pane, underLineOtherFileMarkOccurencesPainter); + lastUnderlinedLinkType = t == null ? LinkType.NO_LINK : getLinkType(t); if (t != null && lastUnderlinedLinkType != LinkType.NO_LINK) { lastUnderlined = t; @@ -432,7 +483,9 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC Highlighter.HighlightPainter painter = underLinePainter; if (occurencesPositions.contains(lastUnderlined.start)) { if (lastUnderlinedLinkType == LinkType.LINK_OTHER_SCRIPT) { - painter = underLineExternalMarkOccurencesPainter; + painter = underLineOtherScriptMarkOccurencesPainter; + } else if (lastUnderlinedLinkType == LinkType.LINK_OTHER_FILE) { + painter = underLineOtherFileMarkOccurencesPainter; } else { painter = underLineMarkOccurencesPainter; } @@ -440,9 +493,11 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC markTokenAt(pane.getCaretPosition()); } else { if (lastUnderlinedLinkType == LinkType.LINK_OTHER_SCRIPT) { - painter = underLineExternalPainter; - } - MyMarkers.markToken(pane, lastUnderlined, painter); + painter = underLineOtherScriptPainter; + } else if (lastUnderlinedLinkType == LinkType.LINK_OTHER_FILE) { + painter = underLineOtherFilePainter; + } + MyMarkers.markToken(pane, lastUnderlined, painter); } } else { pane.setCursor(Cursor.getDefaultCursor()); @@ -452,10 +507,11 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC lastUnderlined = null; MyMarkers.removeMarkers(pane, underLinePainter); MyMarkers.removeMarkers(pane, underLineMarkOccurencesPainter); - MyMarkers.removeMarkers(pane, underLineExternalPainter); - MyMarkers.removeMarkers(pane, underLineExternalMarkOccurencesPainter); - - + MyMarkers.removeMarkers(pane, underLineOtherScriptPainter); + MyMarkers.removeMarkers(pane, underLineOtherScriptMarkOccurencesPainter); + MyMarkers.removeMarkers(pane, underLineOtherFilePainter); + MyMarkers.removeMarkers(pane, underLineOtherFileMarkOccurencesPainter); + removeMarkers(); markTokenAt(pane.getCaretPosition()); } @@ -465,6 +521,9 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC @Override public void mouseClicked(MouseEvent e) { + if (lastCursorPos == null) { + return; + } if (ctrlDown) { Token t = ((LineMarkedEditorPane) pane).tokenAtPos(lastCursorPos); if (t != null && getLinkType(t) != LinkType.NO_LINK) { @@ -476,7 +535,6 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC @Override public void mouseMoved(MouseEvent e) { - ctrlDown = (e.getModifiersEx() & InputEvent.CTRL_DOWN_MASK) != 0; lastCursorPos = e.getPoint(); update(); @@ -533,6 +591,7 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC @Override public void propertyChange(PropertyChangeEvent evt) { if (evt.getPropertyName().equals("document")) { + goingOut = false; pane.removeCaretListener(this); pane.getDocument().removeDocumentListener(this); if (status.equals(Status.INSTALLING)) { @@ -564,9 +623,15 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC Map> newDefinitionPosToReferences = new LinkedHashMap<>(); Map newReferenceToDefinition = new LinkedHashMap<>(); List newErrors = new ArrayList<>(); - parser.parse(fullText, newDefinitionPosToReferences, newReferenceToDefinition, newErrors); + List newExternalTypes = new ArrayList<>(); + Map newReferenceToExternalTypeIndex = new LinkedHashMap<>(); + Map> newExternalTypeIndexToReference = new LinkedHashMap<>(); + parser.parse(fullText, newDefinitionPosToReferences, newReferenceToDefinition, newErrors, newExternalTypes, newReferenceToExternalTypeIndex, newExternalTypeIndexToReference); definitionPosToReferences = newDefinitionPosToReferences; referenceToDefinition = newReferenceToDefinition; + externalTypes = newExternalTypes; + referenceToExternalTypeIndex = newReferenceToExternalTypeIndex; + externalTypeIndexToReference = newExternalTypeIndexToReference; for (SimpleParseException ex : newErrors) { errors.put((int) ex.position, ex.getMessage()); } @@ -619,10 +684,41 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC if (linkThisScript) { return LinkType.LINK_THIS_SCRIPT; } + if (pane.isEditable()) { return LinkType.NO_LINK; } - return ((LineMarkedEditorPane) pane).getLinkHandler().isLink(token); + if (referenceToExternalTypeIndex.containsKey(token.start)) { + String externalType = externalTypes.get(referenceToExternalTypeIndex.get(token.start)); + return ((LineMarkedEditorPane) pane).getLinkHandler().getExternalTypeLinkType(externalType); + } + return ((LineMarkedEditorPane) pane).getLinkHandler().getLinkType(token); + } + + private class UnderlinedLabel extends JLabel { + + private final Color underlineColor; + + public UnderlinedLabel(String text, Color underlineColor) { + super(text); + this.underlineColor = underlineColor; + } + + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + FontMetrics fm = g.getFontMetrics(); + g.setColor(underlineColor); + g.drawLine(0, fm.getHeight() - 3, fm.stringWidth(getText()), fm.getHeight() - 3); + } + } + + private class CommentLabel extends JLabel { + + public CommentLabel(String text) { + super(text); + setForeground(new Color(0x339933)); + } } public void handleLink(Token token) { @@ -630,10 +726,94 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC if (definition != null && definition >= 0) { pane.setCaretPosition(definition); } else if (!pane.isEditable()) { + + if (referenceToExternalTypeIndex.containsKey(token.start) + && com.jpexs.decompiler.flash.configuration.Configuration.warningLinkTypes.get()) { + + String externalType = externalTypes.get(referenceToExternalTypeIndex.get(token.start)); + LinkType lt = ((LineMarkedEditorPane) pane).getLinkHandler().getExternalTypeLinkType(externalType); + + if (lt == LinkType.LINK_OTHER_FILE) { + JPanel msgPanel = new JPanel(); + msgPanel.setLayout(new BoxLayout(msgPanel, BoxLayout.Y_AXIS)); + JLabel bewareLabel = new JLabel(AppStrings.translate("message.link.clicked")); + bewareLabel.setAlignmentX(Component.CENTER_ALIGNMENT); + msgPanel.add(bewareLabel); + + JLabel beware2Label = new JLabel(AppStrings.translate("message.link.bewareTypes")); + beware2Label.setAlignmentX(Component.CENTER_ALIGNMENT); + msgPanel.add(beware2Label); + + JPanel linksPanel = new JPanel(new GridBagLayout()); + linksPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK)); + linksPanel.setBackground(Color.white); + GridBagConstraints gbc = new GridBagConstraints(); + gbc.anchor = GridBagConstraints.FIRST_LINE_START; + gbc.insets = new Insets(2, 2, 2, 2); + gbc.gridx = 0; + gbc.gridy = 0; + + linksPanel.add(new UnderlinedLabel(AppStrings.translate("message.link.type.currentScript.sample"), basicUnderlineColor), gbc); + gbc.gridx++; + linksPanel.add(new CommentLabel("//" + AppStrings.translate("message.link.type.currentScript")), gbc); + gbc.gridx = 0; + gbc.gridy++; + linksPanel.add(new UnderlinedLabel(AppStrings.translate("message.link.type.otherScript.sample"), otherScriptUnderlineColor), gbc); + gbc.gridx++; + linksPanel.add(new CommentLabel("//" + AppStrings.translate("message.link.type.otherScript")), gbc); + gbc.gridx = 0; + gbc.gridy++; + linksPanel.add(new UnderlinedLabel(AppStrings.translate("message.link.type.otherFile.sample"), otherFileUnderlineColor), gbc); + gbc.gridx++; + linksPanel.add(new CommentLabel("//" + AppStrings.translate("message.link.type.otherFile")), gbc); + + gbc.gridx = 2; + gbc.gridy = 0; + gbc.gridheight = 3; + gbc.weightx = 1; + gbc.weighty = 1; + JPanel finalPanel = new JPanel(); + finalPanel.setOpaque(false); + linksPanel.add(finalPanel); + + linksPanel.setAlignmentX(Component.CENTER_ALIGNMENT); + + msgPanel.add(linksPanel); + JLabel reallyLabel = new JLabel(AppStrings.translate("message.link.reallyGo")); + reallyLabel.setAlignmentX(Component.CENTER_ALIGNMENT); + msgPanel.add(reallyLabel); + JCheckBox doNotShowAgainCheckbox = new JCheckBox(AppStrings.translate("message.confirm.donotshowagain")); + doNotShowAgainCheckbox.setAlignmentX(Component.CENTER_ALIGNMENT); + msgPanel.add(doNotShowAgainCheckbox); + + int result = ViewMessages.showOptionDialog(Main.getDefaultMessagesComponent(), + msgPanel, + AppStrings.translate("message.warning"), + JOptionPane.OK_CANCEL_OPTION, + JOptionPane.WARNING_MESSAGE, + null, null, null); + if (doNotShowAgainCheckbox.isSelected()) { + com.jpexs.decompiler.flash.configuration.Configuration.warningLinkTypes.set(false); + } + if (result != JOptionPane.OK_OPTION) { + return; + } + } + + } lastUnderlined = null; removeErrorMarkers(); removeMarkers(); pane.repaint(); + + if (referenceToExternalTypeIndex.containsKey(token.start)) { + goingOut = true; + pane.setCursor(Cursor.getDefaultCursor()); + String externalType = externalTypes.get(referenceToExternalTypeIndex.get(token.start)); + ((LineMarkedEditorPane) pane).getLinkHandler().handleExternalTypeLink(externalType); + return; + } + ((LineMarkedEditorPane) pane).getLinkHandler().handleLink(token); } } diff --git a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties index b9cc5767b..2b1f6cbcd 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties @@ -619,3 +619,7 @@ config.description.snapAlignCenterAlignmentHorizontal = Enables snap align of ob config.name.snapAlignCenterAlignmentVertical = Snap align vertical center alignment config.description.snapAlignCenterAlignmentVertical = Enables snap align of object center vertically. + +#after 23.0.1 +config.name.warning.linkTypes = Show warning when clicking external file link +config.name.warning.linkTypes = Warn on clicking a link in the script editor which leads to another SWF file. \ No newline at end of file diff --git a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog_cs.properties b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog_cs.properties index b48f80a78..d09d90bb4 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog_cs.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog_cs.properties @@ -619,3 +619,8 @@ config.description.snapAlignCenterAlignmentHorizontal = Povol\u00ed p\u0159ichyc config.name.snapAlignCenterAlignmentVertical = Vertik\u00e1ln\u00ed zarovn\u00e1n\u00ed st\u0159edu v p\u0159ichycen\u00ed k zarovn\u00e1n\u00ed config.description.snapAlignCenterAlignmentVertical = Povol\u00ed p\u0159ichycen\u00ed k zarovn\u00e1n\u00ed st\u0159edu objektu vertik\u00e1ln\u011b. + +#after 23.0.1 +config.name.warning.linkTypes = Varovat p\u0159i kliknut\u00ed na link na extern\u00ed soubor +config.description.warning.linkTypes = Zobrazovat varov\u00e1n\u00ed p\u0159i kliknut\u00ed na odkaz v editoru skript\u016f, kter\u00fd vede do jin\u00e9ho SWF souboru. + diff --git a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties index c31c20f83..7bbe3c418 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties @@ -1061,4 +1061,14 @@ contextmenu.showDetail = Show detail highlighter.occurences = Mark occurences highlighter.currentLine = Current line -highlighter.error = Error: %error% \ No newline at end of file +highlighter.error = Error: %error% + +message.link.clicked = You clicked a link to other SWF file. +message.link.bewareTypes = Beware that there are multiple link types: +message.link.type.currentScript = Link to current script +message.link.type.currentScript.sample = myVar +message.link.type.otherScript = Link to other script in this SWF +message.link.type.otherScript.sample = OtherClass +message.link.type.otherFile = Link to other SWF file (usually playerglobal.swc) +message.link.type.otherFile.sample = String +message.link.reallyGo = Do you really want to go to another SWF? \ No newline at end of file diff --git a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_cs.properties b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_cs.properties index c3c77dfaa..1f0f59a62 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_cs.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_cs.properties @@ -1056,4 +1056,18 @@ contextmenu.showInEasy = Zobrazit v Jednoduch\u00e9m editoru work.debugging.start = Spou\u0161t\u00ed se Flash content debugger menu.file.view.alwaysOnTop = V\u017edy navrchu -contextmenu.showDetail = Zobrazit detail \ No newline at end of file +contextmenu.showDetail = Zobrazit detail + +highlighter.occurences = Ozna\u010dit v\u00fdskyty +highlighter.currentLine = Aktu\u00e1ln\u00ed \u0159\u00e1dek +highlighter.error = Chyba: %error% + +message.link.clicked = Kliknul(a) jste na odkaz do jin\u00e9ho SWF souboru. +message.link.bewareTypes = D\u00e1vejte pozor na to, \u017ee existuje v\u00edce druh\u016f odkaz\u016f: +message.link.type.currentScript = Odkaz do aktu\u00e1ln\u00edho skriptu +message.link.type.currentScript.sample = mojePromenna +message.link.type.otherScript = Odkaz na jin\u00fd skript v tomto SWF +message.link.type.otherScript.sample = JinaTrida +message.link.type.otherFile = Odkaz do jin\u00e9ho SWF souboru (obvykle playerglobal.swc) +message.link.type.otherFile.sample = String +message.link.reallyGo = Opravdu chcete p\u0159ej\u00edt do jin\u00e9ho SWF? \ No newline at end of file