Checkpoint commit. Added AttachmentFactory interface and

BaseAttachmentFactory.  Reimplemented DecalRegistry to implement
AttachmentFactory and contain a delegate BaseAttachmentFactory.
This commit is contained in:
kruland2607 2013-01-08 21:09:48 -06:00
parent 05ff94836f
commit 8ad89448df
9 changed files with 330 additions and 275 deletions

View File

@ -0,0 +1,7 @@
package net.sf.openrocket.document;
public interface AttachmentFactory<T extends Attachment> {
public T getAttachment(String name);
}

View File

@ -0,0 +1,135 @@
package net.sf.openrocket.document;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import net.sf.openrocket.file.FileInfo;
import net.sf.openrocket.util.FileUtils;
public class BaseAttachmentFactory implements AttachmentFactory<BaseAttachmentFactory.BaseAttachment> {
private FileInfo fileInfo;
private boolean isZipFile = false;
public void setBaseFile(FileInfo fileInfo) {
this.fileInfo = fileInfo;
}
public void setIsZipFile(boolean isZipFile) {
this.isZipFile = isZipFile;
}
public class BaseAttachment implements Attachment, Comparable {
protected String name;
BaseAttachment(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
public InputStream getBytes() throws FileNotFoundException, IOException {
return BaseAttachmentFactory.this.getBytes(this);
}
@Override
public int compareTo(Object o) {
if (!(o instanceof BaseAttachment)) {
return -1;
}
return this.name.compareTo(((BaseAttachment) o).name);
}
@Override
public String toString() {
return getName();
}
}
@Override
public BaseAttachment getAttachment(String name) {
return new BaseAttachment(name);
}
/**
* 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.
*
* @param name
* @return
* @throws FileNotFoundException
* @throws IOException
*/
private InputStream getBytes(BaseAttachment attachment) throws FileNotFoundException, IOException {
// This is the InputStream to be returned.
InputStream rawIs = null;
String name = attachment.getName();
if (rawIs == null && isZipFile) {
rawIs = findInZipContainer(name);
}
// Try relative to the model file directory. This is so we can support unzipped container format.
if (rawIs == null) {
if (fileInfo != null && fileInfo.getDirectory() != null) {
File decalFile = new File(fileInfo.getDirectory(), name);
rawIs = new FileInputStream(decalFile);
}
}
if (rawIs == null) {
throw new FileNotFoundException("Unable to locate decal for name " + name);
}
try {
byte[] bytes = FileUtils.readBytes(rawIs);
return new ByteArrayInputStream(bytes);
} finally {
rawIs.close();
}
}
private ZipInputStream findInZipContainer(String name) {
ZipInputStream zis = null;
try {
zis = new ZipInputStream(fileInfo.getFileURL().openStream());
} catch (IOException ex) {
return null;
}
try {
ZipEntry entry = zis.getNextEntry();
while (entry != null) {
if (entry.getName().equals(name)) {
return zis;
}
entry = zis.getNextEntry();
}
zis.close();
return null;
} catch (IOException ioex) {
try {
zis.close();
} catch (IOException ex) {
// why does close throw? it's maddening
}
return null;
}
}
}

View File

@ -10,164 +10,121 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import net.sf.openrocket.appearance.DecalImage; import net.sf.openrocket.appearance.DecalImage;
import net.sf.openrocket.file.FileInfo; import net.sf.openrocket.document.BaseAttachmentFactory.BaseAttachment;
import net.sf.openrocket.logging.LogHelper; import net.sf.openrocket.logging.LogHelper;
import net.sf.openrocket.startup.Application; import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.BugException; import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.FileUtils; import net.sf.openrocket.util.FileUtils;
public class DecalRegistry { public class DecalRegistry implements AttachmentFactory<DecalImage> {
private static LogHelper log = Application.getLogger(); private static LogHelper log = Application.getLogger();
private FileInfo fileInfo; private final BaseAttachmentFactory baseFactory;
private boolean isZipFile = false;
public DecalRegistry(BaseAttachmentFactory baseFactory) {
private Map<String,DecalImageImpl> registeredDecals = new HashMap<String,DecalImageImpl>(); this.baseFactory = baseFactory;
public void setBaseFile(FileInfo fileInfo) {
this.fileInfo = fileInfo;
} }
public void setIsZipFile( boolean isZipFile ) { private Map<String, DecalImageImpl> registeredDecals = new HashMap<String, DecalImageImpl>();
this.isZipFile = isZipFile;
} public DecalImage getAttachment(String decalName) {
public DecalImage getDecalImage( String decalName ) {
DecalImageImpl d = registeredDecals.get(decalName); DecalImageImpl d = registeredDecals.get(decalName);
if ( d == null ) { if (d == null) {
d = new DecalImageImpl(decalName); BaseAttachment attachment = baseFactory.getAttachment(decalName);
d = new DecalImageImpl(attachment);
registeredDecals.put(decalName, d); registeredDecals.put(decalName, d);
} }
return d; return d;
} }
public DecalImage getDecalImage( File file ) { public DecalImage getAttachment(File file) {
// See if this file is being used already // See if this file is being used already
DecalImageImpl decal = findDecalForFile( file ); DecalImageImpl decal = findDecalForFile(file);
if ( decal != null ) { if (decal != null) {
return decal; return decal;
} }
// It's a new file, generate a name for it. // It's a new file, generate a name for it.
String decalName = makeUniqueName( file.getName() ); String decalName = makeUniqueName(file.getName());
decal = new DecalImageImpl( decalName ); BaseAttachment attachment = baseFactory.getAttachment(decalName);
decal.setFileSystemLocation( file ); decal = new DecalImageImpl(attachment);
decal.setFileSystemLocation(file);
registeredDecals.put(decalName, decal); registeredDecals.put(decalName, decal);
return decal; return decal;
} }
public Set<DecalImage> getDecalList( ) { public Collection<DecalImage> getDecalList() {
Set<DecalImage> decals = new TreeSet<DecalImage>(); Set<DecalImage> decals = new TreeSet<DecalImage>();
decals.addAll(registeredDecals.values()); decals.addAll(registeredDecals.values());
return decals; return decals;
} }
public Set<DecalImage> getExportableDecalsList() {
Set<DecalImage> exportableDecals = new HashSet<DecalImage>();
for( DecalImage d : registeredDecals.values() ) {
if ( isExportable(d.getName())) {
exportableDecals.add(d);
}
}
return exportableDecals;
}
public class DecalImageImpl implements DecalImage, Comparable { public class DecalImageImpl implements DecalImage, Comparable {
private final String name; private final BaseAttachment delegate;
private File fileSystemLocation; private File fileSystemLocation;
private DecalImageImpl( String name ) { private DecalImageImpl(BaseAttachment delegate) {
this.name = name; this.delegate = delegate;
} }
@Override @Override
public String getName() { public String getName() {
return name; return delegate.getName();
} }
@Override @Override
public InputStream getBytes() throws FileNotFoundException, IOException { public InputStream getBytes() throws FileNotFoundException, IOException {
return DecalRegistry.this.getDecal(this); return DecalRegistry.this.getDecal(this);
} }
@Override @Override
public void exportImage(File file, boolean watchForChanges) throws IOException { public void exportImage(File file, boolean watchForChanges) throws IOException {
this.fileSystemLocation = file;
DecalRegistry.this.exportDecal(this, file); DecalRegistry.this.exportDecal(this, file);
this.fileSystemLocation = file;
} }
File getFileSystemLocation() { File getFileSystemLocation() {
return fileSystemLocation; return fileSystemLocation;
} }
void setFileSystemLocation( File fileSystemLocation ) { void setFileSystemLocation(File fileSystemLocation) {
this.fileSystemLocation = fileSystemLocation; this.fileSystemLocation = fileSystemLocation;
} }
@Override @Override
public String toString() { public String toString() {
return name; return delegate.toString();
} }
@Override @Override
public int compareTo(Object o) { public int compareTo(Object o) {
if ( ! (o instanceof DecalImageImpl ) ) { if (!(o instanceof DecalImageImpl)) {
return -1; return -1;
} }
return this.name.compareTo( ((DecalImageImpl)o).name ); return delegate.compareTo(((DecalImageImpl) o).delegate);
} }
} }
/**
* Returns true if the named decal is exportable - that is, it is currently stored in
* the zip file.
*
* @param name
* @return
*/
private boolean isExportable( String name ) {
if ( !isZipFile ) {
return false;
}
try {
InputStream is = findInZipContainer(name);
if ( is != null ) {
is.close();
return true;
} else {
return false;
}
} catch ( IOException iex ) {
return false;
}
}
/** /**
* This function returns an InputStream backed by a byte[] containing the decal pixels. * 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. * If it reads in the bytes from an actual file, the underlying file is closed.
@ -177,103 +134,52 @@ public class DecalRegistry {
* @throws FileNotFoundException * @throws FileNotFoundException
* @throws IOException * @throws IOException
*/ */
private InputStream getDecal( DecalImageImpl decal ) throws FileNotFoundException, IOException { private InputStream getDecal(DecalImageImpl decal) throws FileNotFoundException, IOException {
// This is the InputStream to be returned.
InputStream rawIs = null;
// First check if the decal is located on the file system // First check if the decal is located on the file system
File exportedFile= decal.getFileSystemLocation(); File exportedFile = decal.getFileSystemLocation();
if ( exportedFile != null ) { if (exportedFile != null) {
rawIs = new FileInputStream(exportedFile); InputStream rawIs = new FileInputStream(exportedFile);
} try {
byte[] bytes = FileUtils.readBytes(rawIs);
String name = decal.getName(); return new ByteArrayInputStream(bytes);
} finally {
if ( rawIs == null && isZipFile ) { rawIs.close();
rawIs = findInZipContainer(name);
}
// Try relative to the model file directory. This is so we can support unzipped container format.
if ( rawIs == null ) {
if( fileInfo != null && fileInfo.getDirectory() != null ) {
File decalFile = new File(fileInfo.getDirectory(), name);
rawIs = new FileInputStream(decalFile);
} }
} }
if ( rawIs == null ) { return decal.delegate.getBytes();
throw new FileNotFoundException( "Unable to locate decal for name " + name );
}
try {
byte[] bytes = FileUtils.readBytes(rawIs);
return new ByteArrayInputStream(bytes);
}
finally {
rawIs.close();
}
} }
private void exportDecal( DecalImageImpl decal, File selectedFile ) throws IOException { private void exportDecal(DecalImageImpl decal, File selectedFile) throws IOException {
try { try {
InputStream is = decal.getBytes(); InputStream is = decal.getBytes();
OutputStream os = new BufferedOutputStream( new FileOutputStream(selectedFile)); OutputStream os = new BufferedOutputStream(new FileOutputStream(selectedFile));
FileUtils.copy(is, os); FileUtils.copy(is, os);
is.close(); is.close();
os.close(); os.close();
} } catch (IOException iex) {
catch (IOException iex) {
throw new BugException(iex); throw new BugException(iex);
} }
} }
private DecalImageImpl findDecalForFile(File file) {
private ZipInputStream findInZipContainer( String name ) {
ZipInputStream zis = null; for (DecalImageImpl d : registeredDecals.values()) {
try { if (file.equals(d.getFileSystemLocation())) {
zis = new ZipInputStream(fileInfo.fileURL.openStream());
} catch( IOException ex ) {
return null;
}
try {
ZipEntry entry = zis.getNextEntry();
while ( entry != null ) {
if ( entry.getName().equals(name) ) {
return zis;
}
entry = zis.getNextEntry();
}
zis.close();
return null;
}
catch ( IOException ioex ) {
try {
zis.close();
} catch ( IOException ex ) {
// why does close throw? it's maddening
}
return null;
}
}
private DecalImageImpl findDecalForFile( File file ) {
for( DecalImageImpl d : registeredDecals.values() ) {
if ( file.equals( d.getFileSystemLocation() ) ) {
return d; return d;
} }
} }
return null; return null;
} }
/** /**
* Regular expression for parsing file names with numerical identifiers. * Regular expression for parsing file names with numerical identifiers.
* For examples: * For examples:
@ -298,49 +204,49 @@ public class DecalRegistry {
private static final int BASE_NAME_INDEX = 1; private static final int BASE_NAME_INDEX = 1;
private static final int NUMBER_INDEX = 3; private static final int NUMBER_INDEX = 3;
private static final int EXTENSION_INDEX = 4; private static final int EXTENSION_INDEX = 4;
private String makeUniqueName( String name ) { private String makeUniqueName(String name) {
String newName = "decals/" + name; String newName = "decals/" + name;
String basename = ""; String basename = "";
String extension = ""; String extension = "";
Matcher nameMatcher = fileNamePattern.matcher(newName); Matcher nameMatcher = fileNamePattern.matcher(newName);
if ( nameMatcher.matches() ) { if (nameMatcher.matches()) {
basename = nameMatcher.group(BASE_NAME_INDEX); basename = nameMatcher.group(BASE_NAME_INDEX);
extension = nameMatcher.group(EXTENSION_INDEX); extension = nameMatcher.group(EXTENSION_INDEX);
} }
Set<Integer> counts = new TreeSet<Integer>(); Set<Integer> counts = new TreeSet<Integer>();
boolean needsRewrite = false; boolean needsRewrite = false;
for ( DecalImageImpl d: registeredDecals.values() ) { for (DecalImageImpl d : registeredDecals.values()) {
Matcher m = fileNamePattern.matcher( d.getName() ); Matcher m = fileNamePattern.matcher(d.getName());
if ( m.matches() ) { if (m.matches()) {
if ( basename.equals(m.group(BASE_NAME_INDEX)) && extension.equals(m.group(EXTENSION_INDEX))) { if (basename.equals(m.group(BASE_NAME_INDEX)) && extension.equals(m.group(EXTENSION_INDEX))) {
String intString = m.group(NUMBER_INDEX); String intString = m.group(NUMBER_INDEX);
if ( intString != null ) { if (intString != null) {
Integer i = Integer.parseInt(intString); Integer i = Integer.parseInt(intString);
counts.add(i); counts.add(i);
} }
needsRewrite = true; needsRewrite = true;
} }
} else if ( newName.equals(d.getName() ) ) { } else if (newName.equals(d.getName())) {
needsRewrite = true; needsRewrite = true;
} }
} }
if ( !needsRewrite ) { if (!needsRewrite) {
return newName; return newName;
} }
// find a missing integer; // find a missing integer;
Integer newIndex = 1; Integer newIndex = 1;
while( counts.contains(newIndex) ) { while (counts.contains(newIndex)) {
newIndex++; newIndex++;
} }
return MessageFormat.format("{0} ({1}).{2}", basename,newIndex,extension); return MessageFormat.format("{0} ({1}).{2}", basename, newIndex, extension);
} }
} }

View File

@ -6,20 +6,17 @@ import java.util.LinkedHashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.TreeSet;
import net.sf.openrocket.appearance.Appearance;
import net.sf.openrocket.appearance.Decal;
import net.sf.openrocket.document.events.DocumentChangeEvent; import net.sf.openrocket.document.events.DocumentChangeEvent;
import net.sf.openrocket.document.events.DocumentChangeListener; import net.sf.openrocket.document.events.DocumentChangeListener;
import net.sf.openrocket.document.events.SimulationChangeEvent; import net.sf.openrocket.document.events.SimulationChangeEvent;
import net.sf.openrocket.file.FileInfo;
import net.sf.openrocket.logging.LogHelper; import net.sf.openrocket.logging.LogHelper;
import net.sf.openrocket.logging.TraceException; import net.sf.openrocket.logging.TraceException;
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent; import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
import net.sf.openrocket.rocketcomponent.ComponentChangeListener; import net.sf.openrocket.rocketcomponent.ComponentChangeListener;
import net.sf.openrocket.rocketcomponent.Configuration; import net.sf.openrocket.rocketcomponent.Configuration;
import net.sf.openrocket.rocketcomponent.Rocket; import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.simulation.FlightDataType; import net.sf.openrocket.simulation.FlightDataType;
import net.sf.openrocket.simulation.customexpression.CustomExpression; import net.sf.openrocket.simulation.customexpression.CustomExpression;
import net.sf.openrocket.simulation.listeners.SimulationListener; import net.sf.openrocket.simulation.listeners.SimulationListener;
@ -61,20 +58,21 @@ public class OpenRocketDocument implements ComponentChangeListener {
private final ArrayList<Simulation> simulations = new ArrayList<Simulation>(); private final ArrayList<Simulation> simulations = new ArrayList<Simulation>();
private ArrayList<CustomExpression> customExpressions = new ArrayList<CustomExpression>(); private ArrayList<CustomExpression> customExpressions = new ArrayList<CustomExpression>();
private DecalRegistry decalRegistry = new DecalRegistry(); private BaseAttachmentFactory attachmentFactory = new BaseAttachmentFactory();
private DecalRegistry decalRegistry = new DecalRegistry(attachmentFactory);
/* /*
* The undo/redo variables and mechanism are documented in doc/undo-redo-flow.* * The undo/redo variables and mechanism are documented in doc/undo-redo-flow.*
*/ */
/** /**
* The undo history of the rocket. Whenever a new undo position is created while the * The undo history of the rocket. Whenever a new undo position is created while the
* rocket is in "dirty" state, the rocket is copied here. * rocket is in "dirty" state, the rocket is copied here.
*/ */
private LinkedList<Rocket> undoHistory = new LinkedList<Rocket>(); private LinkedList<Rocket> undoHistory = new LinkedList<Rocket>();
private LinkedList<String> undoDescription = new LinkedList<String>(); private LinkedList<String> undoDescription = new LinkedList<String>();
/** /**
* The position in the undoHistory we are currently at. If modifications have been * The position in the undoHistory we are currently at. If modifications have been
* made to the rocket, the rocket is in "dirty" state and this points to the previous * made to the rocket, the rocket is in "dirty" state and this points to the previous
@ -88,7 +86,7 @@ public class OpenRocketDocument implements ComponentChangeListener {
private String nextDescription = null; private String nextDescription = null;
private String storedDescription = null; private String storedDescription = null;
private ArrayList<UndoRedoListener> undoRedoListeners = new ArrayList<UndoRedoListener>(2); private ArrayList<UndoRedoListener> undoRedoListeners = new ArrayList<UndoRedoListener>(2);
private File file = null; private File file = null;
@ -96,7 +94,7 @@ public class OpenRocketDocument implements ComponentChangeListener {
private final StorageOptions storageOptions = new StorageOptions(); private final StorageOptions storageOptions = new StorageOptions();
private final List<DocumentChangeListener> listeners = private final List<DocumentChangeListener> listeners =
new ArrayList<DocumentChangeListener>(); new ArrayList<DocumentChangeListener>();
@ -115,38 +113,48 @@ public class OpenRocketDocument implements ComponentChangeListener {
} }
public void addCustomExpression(CustomExpression expression){ public void setBaseFile(FileInfo fileInfo) {
if (customExpressions.contains(expression)){ attachmentFactory.setBaseFile(fileInfo);
log.user("Could not add custom expression "+expression.getName()+" to document as document alerady has a matching expression."); }
public void setIsZipFile(boolean isZipFile) {
attachmentFactory.setIsZipFile(isZipFile);
}
public void addCustomExpression(CustomExpression expression) {
if (customExpressions.contains(expression)) {
log.user("Could not add custom expression " + expression.getName() + " to document as document alerady has a matching expression.");
} else { } else {
customExpressions.add(expression); customExpressions.add(expression);
} }
} }
public void removeCustomExpression(CustomExpression expression){ public void removeCustomExpression(CustomExpression expression) {
customExpressions.remove(expression); customExpressions.remove(expression);
} }
public List<CustomExpression> getCustomExpressions(){ public List<CustomExpression> getCustomExpressions() {
return customExpressions; return customExpressions;
} }
/* /*
* Returns a set of all the flight data types defined or available in any way in the rocket document * Returns a set of all the flight data types defined or available in any way in the rocket document
*/ */
public Set<FlightDataType> getFlightDataTypes(){ public Set<FlightDataType> getFlightDataTypes() {
Set<FlightDataType> allTypes = new LinkedHashSet<FlightDataType>(); Set<FlightDataType> allTypes = new LinkedHashSet<FlightDataType>();
// built in // built in
Collections.addAll(allTypes, FlightDataType.ALL_TYPES); Collections.addAll(allTypes, FlightDataType.ALL_TYPES);
// custom expressions // custom expressions
for (CustomExpression exp : customExpressions){ for (CustomExpression exp : customExpressions) {
allTypes.add(exp.getType()); allTypes.add(exp.getType());
} }
// simulation listeners // simulation listeners
for (Simulation sim : simulations){ for (Simulation sim : simulations) {
for (String className : sim.getSimulationListeners()) { for (String className : sim.getSimulationListeners()) {
SimulationListener l = null; SimulationListener l = null;
try { try {
@ -158,7 +166,7 @@ public class OpenRocketDocument implements ComponentChangeListener {
} catch (Exception e) { } catch (Exception e) {
log.error("Could not instantiate listener: " + className); log.error("Could not instantiate listener: " + className);
} }
} }
} }
// imported data // imported data
@ -168,7 +176,7 @@ public class OpenRocketDocument implements ComponentChangeListener {
return allTypes; return allTypes;
} }
public Rocket getRocket() { public Rocket getRocket() {
return rocket; return rocket;
} }
@ -181,7 +189,7 @@ public class OpenRocketDocument implements ComponentChangeListener {
public DecalRegistry getDecalRegistry() { public DecalRegistry getDecalRegistry() {
return decalRegistry; return decalRegistry;
} }
public File getFile() { public File getFile() {
return file; return file;
} }
@ -212,9 +220,9 @@ public class OpenRocketDocument implements ComponentChangeListener {
} }
public List<Simulation> getSimulations() { public List<Simulation> getSimulations() {
return simulations.clone(); return simulations.clone();
} }
@ -320,14 +328,14 @@ public class OpenRocketDocument implements ComponentChangeListener {
undoDescription.removeLast(); undoDescription.removeLast();
} }
// Add the current state to the undo history // Add the current state to the undo history
undoHistory.add(rocket.copyWithOriginalID()); undoHistory.add(rocket.copyWithOriginalID());
undoDescription.add(null); undoDescription.add(null);
nextDescription = description; nextDescription = description;
undoPosition++; undoPosition++;
// Maintain maximum undo size // Maintain maximum undo size
if (undoHistory.size() > UNDO_LEVELS + UNDO_MARGIN && undoPosition > UNDO_MARGIN) { if (undoHistory.size() > UNDO_LEVELS + UNDO_MARGIN && undoPosition > UNDO_MARGIN) {
for (int i = 0; i < UNDO_MARGIN; i++) { for (int i = 0; i < UNDO_MARGIN; i++) {
@ -384,7 +392,7 @@ public class OpenRocketDocument implements ComponentChangeListener {
undoHistory.add(rocket.copyWithOriginalID()); undoHistory.add(rocket.copyWithOriginalID());
undoDescription.add(null); undoDescription.add(null);
undoPosition = 0; undoPosition = 0;
fireUndoRedoChangeEvent(); fireUndoRedoChangeEvent();
} }
@ -539,7 +547,7 @@ public class OpenRocketDocument implements ComponentChangeListener {
} }
/** /**
* Return a copy of this document. The rocket is copied with original ID's, the default * Return a copy of this document. The rocket is copied with original ID's, the default
* motor configuration ID is maintained and the simulations are copied to the new rocket. * motor configuration ID is maintained and the simulations are copied to the new rocket.
@ -558,14 +566,14 @@ public class OpenRocketDocument implements ComponentChangeListener {
} }
/////// Listeners /////// Listeners
public void addUndoRedoListener( UndoRedoListener listener ) { public void addUndoRedoListener(UndoRedoListener listener) {
undoRedoListeners.add(listener); undoRedoListeners.add(listener);
} }
public void removeUndoRedoListener( UndoRedoListener listener ) { public void removeUndoRedoListener(UndoRedoListener listener) {
undoRedoListeners.remove(listener); undoRedoListeners.remove(listener);
} }
@ -593,6 +601,6 @@ public class OpenRocketDocument implements ComponentChangeListener {
} }
} }

View File

@ -28,7 +28,7 @@ import net.sf.openrocket.util.TextUtil;
public class GeneralRocketLoader { public class GeneralRocketLoader {
protected final WarningSet warnings = new WarningSet(); protected final WarningSet warnings = new WarningSet();
private static final int READ_BYTES = 300; private static final int READ_BYTES = 300;
private static final byte[] GZIP_SIGNATURE = { 31, -117 }; // 0x1f, 0x8b private static final byte[] GZIP_SIGNATURE = { 31, -117 }; // 0x1f, 0x8b
@ -54,7 +54,7 @@ public class GeneralRocketLoader {
return doc; return doc;
} catch (Exception e) { } catch (Exception e) {
throw new RocketLoadException("Exception loading file: " + source,e); throw new RocketLoadException("Exception loading file: " + source, e);
} finally { } finally {
if (stream != null) { if (stream != null) {
try { try {
@ -68,9 +68,9 @@ public class GeneralRocketLoader {
public final OpenRocketDocument load(InputStream source, FileInfo fileInfo, MotorFinder motorFinder) throws RocketLoadException { public final OpenRocketDocument load(InputStream source, FileInfo fileInfo, MotorFinder motorFinder) throws RocketLoadException {
try { try {
OpenRocketDocument doc = loadFromStream(source, motorFinder ); OpenRocketDocument doc = loadFromStream(source, motorFinder);
doc.getDecalRegistry().setBaseFile(fileInfo); doc.setBaseFile(fileInfo);
return doc; return doc;
} catch (Exception e) { } catch (Exception e) {
throw new RocketLoadException("Exception loading stream", e); throw new RocketLoadException("Exception loading stream", e);
} }
@ -79,7 +79,7 @@ public class GeneralRocketLoader {
public final WarningSet getWarnings() { public final WarningSet getWarnings() {
return warnings; return warnings;
} }
protected OpenRocketDocument loadFromStream(InputStream source, MotorFinder motorFinder) throws IOException, protected OpenRocketDocument loadFromStream(InputStream source, MotorFinder motorFinder) throws IOException,
RocketLoadException { RocketLoadException {
@ -99,13 +99,13 @@ public class GeneralRocketLoader {
throw new RocketLoadException("Unsupported or corrupt file."); throw new RocketLoadException("Unsupported or corrupt file.");
} }
// Detect the appropriate loader // Detect the appropriate loader
// Check for GZIP // Check for GZIP
if (buffer[0] == GZIP_SIGNATURE[0] && buffer[1] == GZIP_SIGNATURE[1]) { if (buffer[0] == GZIP_SIGNATURE[0] && buffer[1] == GZIP_SIGNATURE[1]) {
OpenRocketDocument doc = loadFromStream(new GZIPInputStream(source), motorFinder); OpenRocketDocument doc = loadFromStream(new GZIPInputStream(source), motorFinder);
doc.getDecalRegistry().setIsZipFile(false); doc.setIsZipFile(false);
return doc; return doc;
} }
@ -120,7 +120,7 @@ public class GeneralRocketLoader {
} }
if (entry.getName().matches(".*\\.[oO][rR][kK]$")) { if (entry.getName().matches(".*\\.[oO][rR][kK]$")) {
OpenRocketDocument doc = loadFromStream(in, motorFinder); OpenRocketDocument doc = loadFromStream(in, motorFinder);
doc.getDecalRegistry().setIsZipFile(true); doc.setIsZipFile(true);
return doc; return doc;
} else if (entry.getName().matches(".*\\.[rR][kK][tT]$")) { } else if (entry.getName().matches(".*\\.[rR][kK][tT]$")) {
OpenRocketDocument doc = loadFromStream(in, motorFinder); OpenRocketDocument doc = loadFromStream(in, motorFinder);
@ -136,7 +136,7 @@ public class GeneralRocketLoader {
match++; match++;
if (match == OPENROCKET_SIGNATURE.length) { if (match == OPENROCKET_SIGNATURE.length) {
OpenRocketDocument doc = loadUsing(openRocketLoader, source, motorFinder); OpenRocketDocument doc = loadUsing(openRocketLoader, source, motorFinder);
doc.getDecalRegistry().setIsZipFile(false); doc.setIsZipFile(false);
return doc; return doc;
} }
} else { } else {
@ -146,8 +146,8 @@ public class GeneralRocketLoader {
byte[] typeIdentifier = ArrayUtils.copyOf(buffer, ROCKSIM_SIGNATURE.length); byte[] typeIdentifier = ArrayUtils.copyOf(buffer, ROCKSIM_SIGNATURE.length);
if (Arrays.equals(ROCKSIM_SIGNATURE, typeIdentifier)) { if (Arrays.equals(ROCKSIM_SIGNATURE, typeIdentifier)) {
OpenRocketDocument doc = loadUsing(rocksimLoader, source, motorFinder); OpenRocketDocument doc = loadUsing(rocksimLoader, source, motorFinder);
doc.getDecalRegistry().setIsZipFile(false); doc.setIsZipFile(false);
return doc; return doc;
} }
throw new RocketLoadException("Unsupported or corrupt file."); throw new RocketLoadException("Unsupported or corrupt file.");

View File

@ -31,7 +31,7 @@ class AppearanceHandler extends AbstractElementHandler {
throws SAXException { throws SAXException {
if ("decal".equals(element)) { if ("decal".equals(element)) {
String name = attributes.remove("name"); String name = attributes.remove("name");
builder.setImage(context.getOpenRocketDocument().getDecalRegistry().getDecalImage(name)); builder.setImage(context.getOpenRocketDocument().getDecalRegistry().getAttachment(name));
double rotation = Double.parseDouble(attributes.remove("rotation")); double rotation = Double.parseDouble(attributes.remove("rotation"));
builder.setRotation(rotation); builder.setRotation(rotation);
String edgeModeName = attributes.remove("edgemode"); String edgeModeName = attributes.remove("edgemode");

View File

@ -68,7 +68,7 @@ public class RockSimAppearanceBuilder extends AppearanceBuilder {
//Find out how to get path of current rocksim file //Find out how to get path of current rocksim file
//so I can look in it's directory //so I can look in it's directory
} }
setImage(document.getDecalRegistry().getDecalImage(value)); setImage(document.getDecalRegistry().getAttachment(value));
} }
} else if ("repeat".equals(name)) { } else if ("repeat".equals(name)) {
repeat = "1".equals(value); repeat = "1".equals(value);

View File

@ -5,7 +5,7 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.Set; import java.util.Collection;
import javax.swing.JComboBox; import javax.swing.JComboBox;
import javax.swing.JDialog; import javax.swing.JDialog;
@ -22,67 +22,66 @@ import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.BugException; import net.sf.openrocket.util.BugException;
public class ExportDecalDialog extends JDialog { public class ExportDecalDialog extends JDialog {
private final static Translator trans = Application.getTranslator(); private final static Translator trans = Application.getTranslator();
private final OpenRocketDocument document; private final OpenRocketDocument document;
private JComboBox decalComboBox; private JComboBox decalComboBox;
public ExportDecalDialog(Window parent,OpenRocketDocument doc) { public ExportDecalDialog(Window parent, OpenRocketDocument doc) {
super(parent, trans.get("ExportDecalDialog.title"), ModalityType.APPLICATION_MODAL); super(parent, trans.get("ExportDecalDialog.title"), ModalityType.APPLICATION_MODAL);
this.document = doc; this.document = doc;
JPanel panel = new JPanel(new MigLayout()); JPanel panel = new JPanel(new MigLayout());
//// decal list //// decal list
JLabel label = new JLabel(trans.get("ExportDecalDialog.decalList.lbl")); JLabel label = new JLabel(trans.get("ExportDecalDialog.decalList.lbl"));
panel.add(label); panel.add(label);
Set<DecalImage> exportableDecals = document.getDecalRegistry().getExportableDecalsList(); Collection<DecalImage> exportableDecals = document.getDecalRegistry().getDecalList();
decalComboBox = new JComboBox( exportableDecals.toArray( new DecalImage[0] ) ); decalComboBox = new JComboBox(exportableDecals.toArray(new DecalImage[0]));
decalComboBox.setEditable(false); decalComboBox.setEditable(false);
panel.add(decalComboBox, "growx, wrap"); panel.add(decalComboBox, "growx, wrap");
final JFileChooser chooser = new JFileChooser(); final JFileChooser chooser = new JFileChooser();
chooser.setCurrentDirectory(((SwingPreferences) Application.getPreferences()).getDefaultDirectory()); chooser.setCurrentDirectory(((SwingPreferences) Application.getPreferences()).getDefaultDirectory());
chooser.setVisible(true); chooser.setVisible(true);
chooser.setDialogType(JFileChooser.SAVE_DIALOG); chooser.setDialogType(JFileChooser.SAVE_DIALOG);
chooser.addActionListener( new ActionListener() { chooser.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand(); String command = e.getActionCommand();
if ( command.equals(JFileChooser.CANCEL_SELECTION) ) { if (command.equals(JFileChooser.CANCEL_SELECTION)) {
ExportDecalDialog.this.dispose(); ExportDecalDialog.this.dispose();
} else if ( command.equals(JFileChooser.APPROVE_SELECTION)) { } else if (command.equals(JFileChooser.APPROVE_SELECTION)) {
// Here we copy the bits out. // Here we copy the bits out.
// FIXME - confirm overwrite? // FIXME - confirm overwrite?
DecalImage selectedDecal = (DecalImage) decalComboBox.getSelectedItem(); DecalImage selectedDecal = (DecalImage) decalComboBox.getSelectedItem();
File selectedFile = chooser.getSelectedFile(); File selectedFile = chooser.getSelectedFile();
export(selectedDecal,selectedFile); export(selectedDecal, selectedFile);
ExportDecalDialog.this.dispose(); ExportDecalDialog.this.dispose();
} }
} }
}); });
panel.add(chooser, "span, grow"); panel.add(chooser, "span, grow");
this.add(panel); this.add(panel);
this.pack(); this.pack();
} }
private void export( DecalImage decal, File selectedFile ) { private void export(DecalImage decal, File selectedFile) {
try { try {
decal.exportImage(selectedFile, false); decal.exportImage(selectedFile, false);
} } catch (IOException iex) {
catch (IOException iex) {
throw new BugException(iex); throw new BugException(iex);
} }
} }
} }

View File

@ -71,7 +71,7 @@ public class DecalModel extends AbstractListModel implements ComboBoxModel {
if (action == JFileChooser.APPROVE_OPTION) { if (action == JFileChooser.APPROVE_OPTION) {
((SwingPreferences) Application.getPreferences()).setDefaultDirectory(fc.getCurrentDirectory()); ((SwingPreferences) Application.getPreferences()).setDefaultDirectory(fc.getCurrentDirectory());
File file = fc.getSelectedFile(); File file = fc.getSelectedFile();
setSelectedItem(document.getDecalRegistry().getDecalImage(file)); setSelectedItem(document.getDecalRegistry().getAttachment(file));
} }
} }
}); });