diff --git a/core/src/net/sf/openrocket/document/DecalRegistry.java b/core/src/net/sf/openrocket/document/DecalRegistry.java index ed61f9bbe..73677a636 100644 --- a/core/src/net/sf/openrocket/document/DecalRegistry.java +++ b/core/src/net/sf/openrocket/document/DecalRegistry.java @@ -1,15 +1,22 @@ package net.sf.openrocket.document; +import java.io.BufferedOutputStream; 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; +import java.io.OutputStream; +import java.util.HashMap; +import java.util.Map; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import net.sf.openrocket.file.FileInfo; +import net.sf.openrocket.gui.ExportDecalDialog; +import net.sf.openrocket.util.BugException; import net.sf.openrocket.util.FileUtils; public class DecalRegistry { @@ -17,6 +24,8 @@ public class DecalRegistry { private FileInfo fileInfo; private boolean isZipFile = false; + private Map exportedDecalMap = new HashMap(); + /* FIXME - Caching ? private Map cache = new HashMap(); */ @@ -29,6 +38,13 @@ public class DecalRegistry { this.isZipFile = isZipFile; } + /** + * Returns true if the named decal is exportable - that is, it is currently stored in + * the zip file. + * + * @param name + * @return + */ public boolean isExportable( String name ) { if ( !isZipFile ) { return false; @@ -45,6 +61,7 @@ public class DecalRegistry { return false; } } + /** * This function returns an InputStream backed by a byte[] containing the decal pixels. * If it reads in the bytes from an actual file, the underlying file is closed. @@ -62,9 +79,19 @@ public class DecalRegistry { } */ + // This is the InputStream to be returned. InputStream rawIs = null; - if ( isZipFile ) { + + // First check if the decal had been exported + { + File exportedFile= exportedDecalMap.get(name); + if ( exportedFile != null ) { + rawIs = new FileInputStream(exportedFile); + } + } + + if ( rawIs == null && isZipFile ) { rawIs = forwardToEntry(name); } @@ -99,6 +126,29 @@ public class DecalRegistry { } + public void exportDecal( String decalName, File selectedFile ) throws IOException { + + try { + InputStream is = getDecal(decalName); + OutputStream os = new BufferedOutputStream( new FileOutputStream(selectedFile)); + + FileUtils.copy(is, os); + + is.close(); + os.close(); + + exportedDecalMap.put(decalName, selectedFile ); + + } + catch (IOException iex) { + throw new BugException(iex); + } + + + + } + + private ZipInputStream forwardToEntry( String name ) throws IOException { ZipInputStream zis = new ZipInputStream(fileInfo.fileURL.openStream()); try { diff --git a/core/src/net/sf/openrocket/gui/ExportDecalDialog.java b/core/src/net/sf/openrocket/gui/ExportDecalDialog.java new file mode 100644 index 000000000..b4bf8b675 --- /dev/null +++ b/core/src/net/sf/openrocket/gui/ExportDecalDialog.java @@ -0,0 +1,100 @@ +package net.sf.openrocket.gui; + +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import javax.swing.JComboBox; +import javax.swing.JDialog; +import javax.swing.JFileChooser; +import javax.swing.JLabel; +import javax.swing.JPanel; + +import net.miginfocom.swing.MigLayout; +import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.gui.util.SwingPreferences; +import net.sf.openrocket.startup.Application; +import net.sf.openrocket.util.BugException; +import net.sf.openrocket.util.FileUtils; + +public class ExportDecalDialog extends JDialog { + + private final OpenRocketDocument document; + + private JComboBox decalComboBox; + + + public ExportDecalDialog(Window parent,OpenRocketDocument doc) { + // FIXME i18n + // FIXME add buttons. + super(parent, "title", ModalityType.APPLICATION_MODAL); + + this.document = doc; + + JPanel panel = new JPanel(new MigLayout()); + + //// decal list + JLabel label = new JLabel("Decal"); + panel.add(label); + + Set allDecals = document.getDecalList(); + List exportableDecals = new ArrayList(); + for ( String decal : allDecals ) { + if ( document.getDecalRegistry().isExportable(decal) ) { + exportableDecals.add(decal); + } + } + + decalComboBox = new JComboBox( exportableDecals.toArray( new String[0] ) ); + decalComboBox.setEditable(false); + panel.add(decalComboBox, "growx, wrap"); + + final JFileChooser chooser = new JFileChooser(); + chooser.setCurrentDirectory(((SwingPreferences) Application.getPreferences()).getDefaultDirectory()); + chooser.setVisible(true); + chooser.setDialogType(JFileChooser.SAVE_DIALOG); + + chooser.addActionListener( new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + JFileChooser chooser = (JFileChooser) e.getSource(); + String command = e.getActionCommand(); + if ( command.equals(JFileChooser.CANCEL_SELECTION) ) { + ExportDecalDialog.this.dispose(); + } else if ( command.equals(JFileChooser.APPROVE_SELECTION)) { + // Here we copy the bits out. + + String selectedDecal = (String) decalComboBox.getSelectedItem(); + File selectedFile = chooser.getSelectedFile(); + + export(selectedDecal,selectedFile); + ExportDecalDialog.this.dispose(); + } + } + }); + panel.add(chooser, "span, grow"); + + this.add(panel); + this.pack(); + } + + private void export( String decalName, File selectedFile ) { + + try { + document.getDecalRegistry().exportDecal(decalName,selectedFile); + } + catch (IOException iex) { + throw new BugException(iex); + } + } + +} diff --git a/core/src/net/sf/openrocket/gui/main/BasicFrame.java b/core/src/net/sf/openrocket/gui/main/BasicFrame.java index 1d90347eb..c1a5d597c 100644 --- a/core/src/net/sf/openrocket/gui/main/BasicFrame.java +++ b/core/src/net/sf/openrocket/gui/main/BasicFrame.java @@ -65,6 +65,7 @@ import net.sf.openrocket.document.StorageOptions; import net.sf.openrocket.file.GeneralRocketLoader; import net.sf.openrocket.file.GeneralRocketSaver; import net.sf.openrocket.file.RocketLoadException; +import net.sf.openrocket.gui.ExportDecalDialog; import net.sf.openrocket.gui.StorageOptionChooser; import net.sf.openrocket.gui.configdialog.ComponentConfigDialog; import net.sf.openrocket.gui.customexpression.CustomExpressionDialog; @@ -489,6 +490,16 @@ public class BasicFrame extends JFrame { } }); menu.add(item); + + //// Export decal... + item = new JMenuItem("Export Decal"); + item.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + exportDecalAction(); + } + }); + menu.add(item); //// Print... item = new JMenuItem(trans.get("main.menu.file.print"), KeyEvent.VK_P); @@ -1455,7 +1466,9 @@ public class BasicFrame extends JFrame { return true; } - + public void exportDecalAction() { + new ExportDecalDialog(this, document).setVisible(true); + } /** *