diff --git a/core/resources/datafiles/examples/Apocalypse with decals.ork b/core/resources/datafiles/examples/Apocalypse with decals.ork new file mode 100644 index 000000000..c206e3ed3 Binary files /dev/null and b/core/resources/datafiles/examples/Apocalypse with decals.ork differ diff --git a/core/src/net/sf/openrocket/document/DecalRegistry.java b/core/src/net/sf/openrocket/document/DecalRegistry.java index f74c0a45e..b78d938e8 100644 --- a/core/src/net/sf/openrocket/document/DecalRegistry.java +++ b/core/src/net/sf/openrocket/document/DecalRegistry.java @@ -8,32 +8,34 @@ import java.io.InputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; +import net.sf.openrocket.file.FileInfo; + public class DecalRegistry { - private File baseFile; + private FileInfo fileInfo; private boolean isZipFile = false; - + /* FIXME - Caching ? private Map cache = new HashMap(); - */ - - public void setBaseFile(File baseFile) { - this.baseFile = baseFile; + */ + + public void setBaseFile(FileInfo fileInfo) { + this.fileInfo = fileInfo; } public void setIsZipFile( boolean isZipFile ) { this.isZipFile = isZipFile; } - + public InputStream getDecal( String name ) throws FileNotFoundException, IOException { /* FIXME - Caching? byte[] bytes = cache.get(name); if ( bytes != null ) { return new ByteArrayInputStream(bytes); } - */ + */ if ( isZipFile ) { - ZipInputStream zis = new ZipInputStream(new FileInputStream(baseFile)); + ZipInputStream zis = new ZipInputStream(fileInfo.fileURL.openStream()); ZipEntry entry = zis.getNextEntry(); while ( entry != null ) { if ( entry.getName().equals(name) ) { @@ -42,13 +44,13 @@ public class DecalRegistry { entry = zis.getNextEntry(); } } - - if ( baseFile != null ) { - File decal = new File(baseFile.getParentFile(), name); + + if( fileInfo.getDirectory() != null ) { + File decal = new File(fileInfo.getDirectory(), name); // FIXME - update cache return new FileInputStream(decal); } throw new FileNotFoundException( "Unable to locate decal for name " + name ); } - + } diff --git a/core/src/net/sf/openrocket/file/FileInfo.java b/core/src/net/sf/openrocket/file/FileInfo.java new file mode 100644 index 000000000..72ad6e374 --- /dev/null +++ b/core/src/net/sf/openrocket/file/FileInfo.java @@ -0,0 +1,30 @@ +package net.sf.openrocket.file; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; + +public class FileInfo { + + public final URL fileURL; + public final File directory; + + public FileInfo(File sourceFile) throws MalformedURLException { + this.fileURL = sourceFile.toURI().toURL(); + this.directory = sourceFile.getParentFile(); + } + + public FileInfo(URL sourceURL) { + this.fileURL = sourceURL; + this.directory = null; + } + + public URL getFileURL() { + return fileURL; + } + + public File getDirectory() { + return directory; + } + +} diff --git a/core/src/net/sf/openrocket/file/GeneralRocketLoader.java b/core/src/net/sf/openrocket/file/GeneralRocketLoader.java index 4a2773a42..4f0bf9e61 100644 --- a/core/src/net/sf/openrocket/file/GeneralRocketLoader.java +++ b/core/src/net/sf/openrocket/file/GeneralRocketLoader.java @@ -51,7 +51,7 @@ public class GeneralRocketLoader { try { stream = new BufferedInputStream(new FileInputStream(source)); - OpenRocketDocument doc = load(stream, source, motorFinder); + OpenRocketDocument doc = load(stream, new FileInfo(source), motorFinder); return doc; } catch (Exception e) { @@ -67,10 +67,10 @@ public class GeneralRocketLoader { } } - public final OpenRocketDocument load(InputStream source, File file, MotorFinder motorFinder) throws RocketLoadException { + public final OpenRocketDocument load(InputStream source, FileInfo fileInfo, MotorFinder motorFinder) throws RocketLoadException { try { OpenRocketDocument doc = loadFromStream(source, motorFinder ); - doc.getDecalRegistry().setBaseFile(file); + doc.getDecalRegistry().setBaseFile(fileInfo); return doc; } catch (Exception e) { throw new RocketLoadException("Exception loading stream", e); diff --git a/core/src/net/sf/openrocket/gui/main/BasicFrame.java b/core/src/net/sf/openrocket/gui/main/BasicFrame.java index e84c9968a..c481a18da 100644 --- a/core/src/net/sf/openrocket/gui/main/BasicFrame.java +++ b/core/src/net/sf/openrocket/gui/main/BasicFrame.java @@ -1,11 +1,68 @@ package net.sf.openrocket.gui.main; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Toolkit; +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLDecoder; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.ExecutionException; + +import javax.swing.Action; +import javax.swing.BorderFactory; +import javax.swing.InputMap; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.JScrollPane; +import javax.swing.JSpinner; +import javax.swing.JSplitPane; +import javax.swing.JTabbedPane; +import javax.swing.JTextField; +import javax.swing.KeyStroke; +import javax.swing.ListSelectionModel; +import javax.swing.ScrollPaneConstants; +import javax.swing.SwingUtilities; +import javax.swing.border.BevelBorder; +import javax.swing.border.TitledBorder; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.DefaultTreeSelectionModel; +import javax.swing.tree.TreePath; +import javax.swing.tree.TreeSelectionModel; + import net.miginfocom.swing.MigLayout; import net.sf.openrocket.aerodynamics.WarningSet; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.file.GeneralRocketLoader; import net.sf.openrocket.file.RocketLoadException; -import net.sf.openrocket.file.RocketLoader; import net.sf.openrocket.file.RocketSaver; import net.sf.openrocket.file.openrocket.OpenRocketSaver; import net.sf.openrocket.file.rocksim.export.RocksimSaver; @@ -50,63 +107,6 @@ import net.sf.openrocket.util.MemoryManagement.MemoryData; import net.sf.openrocket.util.Reflection; import net.sf.openrocket.util.TestRockets; -import javax.swing.Action; -import javax.swing.BorderFactory; -import javax.swing.InputMap; -import javax.swing.JButton; -import javax.swing.JComponent; -import javax.swing.JDialog; -import javax.swing.JFileChooser; -import javax.swing.JFrame; -import javax.swing.JMenu; -import javax.swing.JMenuBar; -import javax.swing.JMenuItem; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JPopupMenu; -import javax.swing.JScrollPane; -import javax.swing.JSpinner; -import javax.swing.JSplitPane; -import javax.swing.JTabbedPane; -import javax.swing.JTextField; -import javax.swing.KeyStroke; -import javax.swing.ListSelectionModel; -import javax.swing.ScrollPaneConstants; -import javax.swing.SwingUtilities; -import javax.swing.border.BevelBorder; -import javax.swing.border.TitledBorder; -import javax.swing.event.TreeSelectionEvent; -import javax.swing.event.TreeSelectionListener; -import javax.swing.tree.DefaultTreeSelectionModel; -import javax.swing.tree.TreePath; -import javax.swing.tree.TreeSelectionModel; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.Toolkit; -import java.awt.Window; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLDecoder; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.ExecutionException; - public class BasicFrame extends JFrame { private static final LogHelper log = Application.getLogger(); @@ -1087,37 +1087,11 @@ public class BasicFrame extends JFrame { // First figure out the file name from the URL - // Try using URI.getPath(); - try { - URI uri = url.toURI(); - filename = uri.getPath(); - } catch (URISyntaxException ignore) { - } - - // Try URL-decoding the URL - if (filename == null) { - try { - filename = URLDecoder.decode(url.toString(), "UTF-8"); - } catch (UnsupportedEncodingException ignore) { - } - } - - // Last resort - if (filename == null) { - filename = ""; - } - - // Remove path from filename - if (filename.lastIndexOf('/') >= 0) { - filename = filename.substring(filename.lastIndexOf('/') + 1); - } - - // Open the file log.info("Opening file from url=" + url + " filename=" + filename); try { InputStream is = url.openStream(); - open(is, filename, parent); + open(is, url, parent); } catch (IOException e) { log.warn("Error opening file" + e); JOptionPane.showMessageDialog(parent, @@ -1138,9 +1112,9 @@ public class BasicFrame extends JFrame { * @param parent the parent component for which a progress dialog is opened. * @return whether the file was successfully loaded and opened. */ - private static boolean open(InputStream stream, String filename, Window parent) { - OpenFileWorker worker = new OpenFileWorker(stream, ROCKET_LOADER); - return open(worker, filename, null, parent); + private static boolean open(InputStream stream, URL fileURL, Window parent) { + OpenFileWorker worker = new OpenFileWorker(stream, fileURL, ROCKET_LOADER); + return open(worker, fileURL.getFile(), null, parent); } diff --git a/core/src/net/sf/openrocket/gui/util/OpenFileWorker.java b/core/src/net/sf/openrocket/gui/util/OpenFileWorker.java index 3d93bf568..841bc9dff 100644 --- a/core/src/net/sf/openrocket/gui/util/OpenFileWorker.java +++ b/core/src/net/sf/openrocket/gui/util/OpenFileWorker.java @@ -7,11 +7,13 @@ import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InterruptedIOException; +import java.net.URL; import javax.swing.SwingWorker; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.file.DatabaseMotorFinder; +import net.sf.openrocket.file.FileInfo; import net.sf.openrocket.file.GeneralRocketLoader; import net.sf.openrocket.logging.LogHelper; import net.sf.openrocket.startup.Application; @@ -27,18 +29,21 @@ public class OpenFileWorker extends SwingWorker { private static final LogHelper log = Application.getLogger(); private final File file; + private final URL jarURL; private final InputStream stream; private final GeneralRocketLoader loader; public OpenFileWorker(File file, GeneralRocketLoader loader) { this.file = file; + this.jarURL = null; this.stream = null; this.loader = loader; } - public OpenFileWorker(InputStream stream, GeneralRocketLoader loader) { + public OpenFileWorker(InputStream stream, URL fileURL, GeneralRocketLoader loader) { this.stream = stream; + this.jarURL = fileURL; this.file = null; this.loader = loader; } @@ -50,12 +55,15 @@ public class OpenFileWorker extends SwingWorker { @Override protected OpenRocketDocument doInBackground() throws Exception { InputStream is; - + + FileInfo fileInfo = null; // Get the correct input stream if (file != null) { is = new FileInputStream(file); + fileInfo = new FileInfo(file); } else { is = stream; + fileInfo = new FileInfo(jarURL); } // Buffer stream unless already buffered @@ -67,7 +75,7 @@ public class OpenFileWorker extends SwingWorker { is = new ProgressInputStream(is); try { - return loader.load(is, file, new DatabaseMotorFinder()); + return loader.load(is, fileInfo, new DatabaseMotorFinder()); } finally { try { is.close();