mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-05-22 18:15:50 +00:00
Added #2260 GFX - Configure path resolving dialog for file paths that use prefixes like data:
This commit is contained in:
@@ -30,6 +30,7 @@ All notable changes to this project will be documented in this file.
|
||||
- [PR194] Support for XDG base directory specification (env variable `XDG_CONFIG_HOME`)
|
||||
- FLA export - ImportAssets/2 tag support
|
||||
- FLA export - export in frame 1 flag support
|
||||
- [#2260] GFX - Configure path resolving dialog for file paths that use prefixes like `data:`
|
||||
|
||||
### Fixed
|
||||
- Debugger - getting children of top level variables
|
||||
|
||||
@@ -29,4 +29,5 @@ public class CustomConfigurationKeys {
|
||||
public static final String KEY_LOADED_IMPORT_ASSETS = "loadedImportAssets";
|
||||
public static final String KEY_ABC_DEPENDENCIES = "abcDependencies";
|
||||
public static final String KEY_BREAKPOINTS = "breakpoints";
|
||||
public static final String KEY_PATH_RESOLVING = "pathResolving";
|
||||
}
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
package com.jpexs.decompiler.flash.tags.gfx;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.configuration.CustomConfigurationKeys;
|
||||
import com.jpexs.decompiler.flash.configuration.SwfSpecificCustomConfiguration;
|
||||
import com.jpexs.decompiler.flash.gfx.TgaSupport;
|
||||
import com.jpexs.decompiler.flash.tags.base.ImageTag;
|
||||
import com.jpexs.decompiler.flash.tags.gfx.enums.FileFormatType;
|
||||
@@ -24,6 +27,7 @@ import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.InvalidPathException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import javax.imageio.ImageIO;
|
||||
@@ -47,9 +51,50 @@ public abstract class AbstractGfxImageTag extends ImageTag {
|
||||
}
|
||||
|
||||
protected BufferedImage getExternalBufferedImage(String fileName, int bitmapFormat) {
|
||||
Path imagePath = getSwf().getFile() == null ? null : Paths.get(getSwf().getFile()).getParent().resolve(Paths.get(fileName));
|
||||
Path imagePath = null;
|
||||
|
||||
try {
|
||||
imagePath = getSwf().getFile() == null ? null : Paths.get(getSwf().getFile()).getParent().resolve(Paths.get(fileName));
|
||||
} catch (InvalidPathException ip) {
|
||||
//ignore
|
||||
}
|
||||
if (imagePath == null || !imagePath.toFile().exists()) {
|
||||
return null;
|
||||
|
||||
SwfSpecificCustomConfiguration cc = Configuration.getSwfSpecificCustomConfiguration(getSwf().getShortPathTitle());
|
||||
if (cc == null) {
|
||||
return null;
|
||||
}
|
||||
String paths = cc.getCustomData(CustomConfigurationKeys.KEY_PATH_RESOLVING, "");
|
||||
if (paths.trim().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
String[] rows = paths.trim().split("\r\n");
|
||||
boolean found = false;
|
||||
for (String row : rows) {
|
||||
String prefix = "";
|
||||
String searchPath;
|
||||
if (row.contains("|")) {
|
||||
prefix = row.substring(0, row.indexOf("|"));
|
||||
searchPath = row.substring(row.indexOf("|") + 1);
|
||||
} else {
|
||||
searchPath = row;
|
||||
}
|
||||
String fileNameNoPrefix = fileName;
|
||||
if (!prefix.isEmpty() && fileName.startsWith(prefix)) {
|
||||
fileNameNoPrefix = fileName.substring(prefix.length());
|
||||
}
|
||||
if (!searchPath.isEmpty()) {
|
||||
Path newImagePath = Paths.get(searchPath).resolve(fileNameNoPrefix);
|
||||
if (newImagePath.toFile().exists()) {
|
||||
found = true;
|
||||
imagePath = newImagePath;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
byte[] imageData;
|
||||
|
||||
@@ -172,7 +172,7 @@ public class DefineExternalImage extends AbstractGfxImageTag {
|
||||
if (shortFormat) {
|
||||
//Just guessing how this may work...
|
||||
return exportName + "." + FileFormatType.fileFormatExtension(bitmapFormat);
|
||||
}
|
||||
}
|
||||
return fileName;
|
||||
}
|
||||
|
||||
|
||||
99
src/com/jpexs/decompiler/flash/gui/PathResolvingDialog.java
Normal file
99
src/com/jpexs/decompiler/flash/gui/PathResolvingDialog.java
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2024 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.gui;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.configuration.CustomConfigurationKeys;
|
||||
import com.jpexs.decompiler.flash.configuration.SwfSpecificCustomConfiguration;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Container;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.ActionEvent;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JEditorPane;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class PathResolvingDialog extends AppDialog {
|
||||
private final JEditorPane editor;
|
||||
private final JButton okButton = new JButton(translate("button.ok"));
|
||||
private final JButton cancelButton = new JButton(translate("button.cancel"));
|
||||
|
||||
private int result = ERROR_OPTION;
|
||||
private final SWF swf;
|
||||
|
||||
public PathResolvingDialog(SWF swf, Window owner) {
|
||||
super(owner);
|
||||
setTitle(translate("dialog.title"));
|
||||
setDefaultCloseOperation(HIDE_ON_CLOSE);
|
||||
Container cnt = getContentPane();
|
||||
cnt.setLayout(new BorderLayout());
|
||||
cnt.add(new JLabel("<html>" + translate("info") + "</html>"), BorderLayout.NORTH);
|
||||
editor = new JEditorPane();
|
||||
cnt.add(new JScrollPane(editor), BorderLayout.CENTER);
|
||||
editor.setContentType("text/plain");
|
||||
|
||||
okButton.addActionListener(this::okButtonActionPerformed);
|
||||
cancelButton.addActionListener(this::cancelButtonActionPerformed);
|
||||
|
||||
JPanel buttonsPanel = new JPanel(new FlowLayout());
|
||||
buttonsPanel.add(okButton);
|
||||
buttonsPanel.add(cancelButton);
|
||||
cnt.add(buttonsPanel, BorderLayout.SOUTH);
|
||||
|
||||
SwfSpecificCustomConfiguration cc = Configuration.getSwfSpecificCustomConfiguration(swf.getShortPathTitle());
|
||||
String pathResolving = "";
|
||||
if (cc != null) {
|
||||
pathResolving = cc.getCustomData(CustomConfigurationKeys.KEY_PATH_RESOLVING, "");
|
||||
}
|
||||
editor.setText(pathResolving);
|
||||
|
||||
setSize(800, 600);
|
||||
View.centerScreen(this);
|
||||
View.setWindowIcon(this);
|
||||
getRootPane().setDefaultButton(okButton);
|
||||
setModal(true);
|
||||
this.swf = swf;
|
||||
}
|
||||
|
||||
private void okButtonActionPerformed(ActionEvent evt) {
|
||||
result = OK_OPTION;
|
||||
SwfSpecificCustomConfiguration cc = Configuration.getOrCreateSwfSpecificCustomConfiguration(swf.getShortPathTitle());
|
||||
String txt = editor.getText();
|
||||
txt = txt.replace("\r\n", "\n");
|
||||
txt = txt.replace("\n", "\r\n");
|
||||
cc.setCustomData(CustomConfigurationKeys.KEY_PATH_RESOLVING, txt);
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
private void cancelButtonActionPerformed(ActionEvent evt) {
|
||||
result = CANCEL_OPTION;
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
public int showDialog() {
|
||||
setVisible(true);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1269,4 +1269,6 @@ warning.cleanAbc = This action will remove items from ABC which have zero usages
|
||||
Some kinds of obfuscated SWFs could be damaged this way.\r\n\
|
||||
Use it at your own risk. Do you want to continue?
|
||||
|
||||
tagInfo.idType = Type of the id
|
||||
tagInfo.idType = Type of the id
|
||||
|
||||
contextmenu.configurePathResolving = Configure path resolving...
|
||||
@@ -1244,4 +1244,6 @@ warning.cleanAbc = Tato akce odstran\u00ed z ABC polo\u017eky, kter\u00e9 maj\u0
|
||||
N\u011bkter\u00e9 druhy obfuskovan\u00fdch SWF to m\u016f\u017ee po\u0161kodit.\r\n\
|
||||
Pou\u017e\u00edvejte ji na vlastn\u00ed riziko. Chcete pokra\u010dovat?
|
||||
|
||||
tagInfo.idType = Typ id
|
||||
tagInfo.idType = Typ id
|
||||
|
||||
contextmenu.configurePathResolving = Nastavit resolvov\u00e1n\u00ed cest...
|
||||
@@ -0,0 +1,22 @@
|
||||
# Copyright (C) 2024 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
dialog.title = Path resolving
|
||||
info = Set directories where assets will be searched when not found in SWFs path.\r\n\
|
||||
You can use pipe "|" to separate prefix that the path must have, like "data:|C:\\MyData\\Dir"\
|
||||
when you have paths starting with "data:" prefix.\r\nOne path per line. This is currently used only in GFX tags.
|
||||
|
||||
button.ok = OK
|
||||
button.cancel = Cancel
|
||||
@@ -0,0 +1,22 @@
|
||||
# Copyright (C) 2024 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
dialog.title = Resolvov\u00e1n\u00ed cest
|
||||
info = Nastav\u00ed slo\u017eky kde budou hled\u00e1ny assety, kter\u00e9 se nepoda\u0159\u00ed nal\u00e9zt v cest\u011b SWF.\r\n\
|
||||
M\u016f\u017eete pou\u017e\u00edt rouru "|" pro odd\u011blen\u00ed p\u0159edpony, kterou cesta mus\u00ed m\u00edt jako "data:|C:\\MyData\\Dir"\
|
||||
pokud chcete m\u00edt cesty za\u010d\u00ednaj\u00edc\u00ed p\u0159edponou "data:". Co cesta to jeden \u0159\u00e1dek. Toto se moment\u00e1ln\u011b pou\u017e\u00edv\u00e1 jen v GFX taz\u00edch.
|
||||
|
||||
button.ok = OK
|
||||
button.cancel = Storno
|
||||
@@ -40,6 +40,7 @@ import com.jpexs.decompiler.flash.gui.ClipboardType;
|
||||
import com.jpexs.decompiler.flash.gui.CollectDepthAsSpritesDialog;
|
||||
import com.jpexs.decompiler.flash.gui.Main;
|
||||
import com.jpexs.decompiler.flash.gui.MainPanel;
|
||||
import com.jpexs.decompiler.flash.gui.PathResolvingDialog;
|
||||
import com.jpexs.decompiler.flash.gui.ReplaceCharacterDialog;
|
||||
import com.jpexs.decompiler.flash.gui.SelectFramePositionDialog;
|
||||
import com.jpexs.decompiler.flash.gui.SelectTagPositionDialog;
|
||||
@@ -171,6 +172,8 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
|
||||
private final MainPanel mainPanel;
|
||||
|
||||
private JMenuItem configurePathResolvingMenuItem;
|
||||
|
||||
private JMenuItem setClassToCharacterMappingMenuItem;
|
||||
|
||||
private JMenuItem expandRecursiveMenuItem;
|
||||
@@ -368,6 +371,12 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
}
|
||||
add(changeCharsetMenu);
|
||||
|
||||
configurePathResolvingMenuItem = new JMenuItem(mainPanel.translate("contextmenu.configurePathResolving"));
|
||||
configurePathResolvingMenuItem.addActionListener(this::configurePathResolvingActionPerformed);
|
||||
configurePathResolvingMenuItem.setIcon(View.getIcon("settings16"));
|
||||
add(configurePathResolvingMenuItem);
|
||||
|
||||
|
||||
removeMenuItem = new JMenuItem(mainPanel.translate("contextmenu.remove") + " (DEL)");
|
||||
removeMenuItem.addActionListener((ActionEvent e) -> {
|
||||
removeItemActionPerformed(e, false);
|
||||
@@ -1125,6 +1134,7 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
unpinAllMenuItem.setVisible(false);
|
||||
unpinOthersMenuItem.setVisible(false);
|
||||
|
||||
configurePathResolvingMenuItem.setVisible(false);
|
||||
removeMenuItem.setVisible(canRemove);
|
||||
removeWithDependenciesMenuItem.setVisible(canRemove && !allDoNotHaveDependencies);
|
||||
cloneMenuItem.setVisible(allSelectedIsTagOrFrame && allSelectedSameParent);
|
||||
@@ -1404,6 +1414,9 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
abcExplorerMenuItem.setVisible(true);
|
||||
cleanAbcMenuItem.setVisible(true);
|
||||
}
|
||||
if (swf.gfx) {
|
||||
configurePathResolvingMenuItem.setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (firstItem instanceof Tag) {
|
||||
@@ -5315,6 +5328,13 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
mainPanel.repaintTree();
|
||||
}
|
||||
|
||||
|
||||
public void configurePathResolvingActionPerformed(ActionEvent evt) {
|
||||
SWF item = (SWF) getCurrentItem();
|
||||
PathResolvingDialog dialog = new PathResolvingDialog(item, Main.getDefaultDialogsOwner());
|
||||
dialog.showDialog();
|
||||
}
|
||||
|
||||
public void changeCharsetActionPerformed(ActionEvent evt) {
|
||||
SWF item = (SWF) getCurrentItem();
|
||||
String newCharset = ((JMenuItem) evt.getSource()).getText();
|
||||
|
||||
Reference in New Issue
Block a user