diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties
index 921e076bd..d83826602 100644
--- a/core/resources/l10n/messages.properties
+++ b/core/resources/l10n/messages.properties
@@ -2028,6 +2028,8 @@ DecalModel.lbl.choose = From file...
ExportDecalDialog.title = Export Decal
ExportDecalDialog.decalList.lbl = Decal
ExportDecalDialog.exception = Unable to write decal to file ''{0}''
+ExportDecalDialog.source.title = No decal source file
+ExportDecalDialog.source.exception = Could not find decal source file ''{0}''.
Would you like to look for this file?
! Component Preset Chooser Dialog
ComponentPresetChooserDialog.title = Choose component preset
diff --git a/core/src/net/sf/openrocket/appearance/DecalImage.java b/core/src/net/sf/openrocket/appearance/DecalImage.java
index cd12cc69e..58e3ed57e 100644
--- a/core/src/net/sf/openrocket/appearance/DecalImage.java
+++ b/core/src/net/sf/openrocket/appearance/DecalImage.java
@@ -6,6 +6,7 @@ import java.io.IOException;
import java.io.InputStream;
import net.sf.openrocket.util.ChangeSource;
+import net.sf.openrocket.util.DecalNotFoundException;
/**
* Interface to handle image files for decals
@@ -26,18 +27,42 @@ public interface DecalImage extends ChangeSource, Comparable {
* @throws FileNotFoundException
* @throws IOException
*/
- public InputStream getBytes() throws FileNotFoundException, IOException;
+ public InputStream getBytes() throws FileNotFoundException, IOException, DecalNotFoundException;
/**
* exports an image into the File
* @param file The File handler object
* @throws IOException
*/
- public void exportImage(File file) throws IOException;
+ public void exportImage(File file) throws IOException, DecalNotFoundException;
/**
* wake up call to listeners
* @param source The source of the wake up call
*/
public void fireChangeEvent(Object source);
+
+ /**
+ * Get the decal file on which the DecalImage is based
+ * @return decal source file
+ */
+ public File getDecalFile();
+
+ /**
+ * Set the decal file on which the DecalImage is based
+ * @param file decal source file
+ */
+ public void setDecalFile(File file);
+
+ /**
+ * Checks whether this DecalImage should be ignored when saving the OpenRocket document.
+ * @return true if DecalImage should be ignored, false if should be saved
+ */
+ public boolean isIgnored();
+
+ /**
+ * Sets the flag to know whether this DecalImage should be ignored when saving the OpenRocket document.
+ * @param ignored true if DecalImage should be ignored, false if should be saved
+ */
+ public void setIgnored(boolean ignored);
}
diff --git a/core/src/net/sf/openrocket/appearance/defaults/ResourceDecalImage.java b/core/src/net/sf/openrocket/appearance/defaults/ResourceDecalImage.java
index 85d24ebf6..b1a53853c 100644
--- a/core/src/net/sf/openrocket/appearance/defaults/ResourceDecalImage.java
+++ b/core/src/net/sf/openrocket/appearance/defaults/ResourceDecalImage.java
@@ -16,7 +16,10 @@ import net.sf.openrocket.util.StateChangeListener;
public class ResourceDecalImage implements DecalImage {
/** File path to the image*/
- final String resource;
+ private String resource;
+
+ // Flag to check whether this DecalImage should be ignored for saving
+ private boolean ignored = false;
/**
* main constructor, stores the file path given
@@ -63,5 +66,28 @@ public class ResourceDecalImage implements DecalImage {
public int compareTo(DecalImage o) {
return getName().compareTo(o.getName());
}
-
+
+ @Override
+ public void setDecalFile(File file) {
+ if (file != null) {
+ this.resource = file.getAbsolutePath();
+ }
+ }
+
+ @Override
+ public boolean isIgnored() {
+ return this.ignored;
+ }
+
+ @Override
+ public void setIgnored(boolean ignored) {
+ this.ignored = ignored;
+ }
+
+ @Override
+ public File getDecalFile() {
+ return new File(resource);
+ }
+
+
}
diff --git a/core/src/net/sf/openrocket/document/Attachment.java b/core/src/net/sf/openrocket/document/Attachment.java
index a46d6300f..24a44911e 100644
--- a/core/src/net/sf/openrocket/document/Attachment.java
+++ b/core/src/net/sf/openrocket/document/Attachment.java
@@ -6,6 +6,7 @@ import java.io.InputStream;
import net.sf.openrocket.util.AbstractChangeSource;
import net.sf.openrocket.util.ChangeSource;
+import net.sf.openrocket.util.DecalNotFoundException;
/**
*
@@ -39,7 +40,7 @@ public abstract class Attachment extends AbstractChangeSource implements Compara
* @throws FileNotFoundException
* @throws IOException
*/
- public abstract InputStream getBytes() throws FileNotFoundException, IOException;
+ public abstract InputStream getBytes() throws FileNotFoundException, IOException, DecalNotFoundException;
/**
* {@inheritDoc}
diff --git a/core/src/net/sf/openrocket/document/DecalRegistry.java b/core/src/net/sf/openrocket/document/DecalRegistry.java
index 7f512bff9..4f1cb233d 100644
--- a/core/src/net/sf/openrocket/document/DecalRegistry.java
+++ b/core/src/net/sf/openrocket/document/DecalRegistry.java
@@ -20,8 +20,10 @@ import java.util.regex.Pattern;
import net.sf.openrocket.appearance.DecalImage;
import net.sf.openrocket.document.attachments.FileSystemAttachment;
-import net.sf.openrocket.util.BugException;
+import net.sf.openrocket.l10n.Translator;
+import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.ChangeSource;
+import net.sf.openrocket.util.DecalNotFoundException;
import net.sf.openrocket.util.FileUtils;
import net.sf.openrocket.util.StateChangeListener;
@@ -91,7 +93,7 @@ public class DecalRegistry {
decalName = makeUniqueName(location.getName());
d = new DecalImageImpl(decalName, attachment);
- d.setFileSystemLocation(location);
+ d.setDecalFile(location);
registeredDecals.put(decalName, d);
return d;
@@ -121,7 +123,10 @@ public class DecalRegistry {
private final Attachment delegate;
private String name;
- private File fileSystemLocation;
+ private File decalFile;
+ private final Translator trans = Application.getTranslator();
+ // Flag to check whether this DecalImage should be ignored for saving
+ private boolean ignored = false;
private DecalImageImpl(String name, Attachment delegate) {
this.name = name;
@@ -151,10 +156,13 @@ public class DecalRegistry {
* @throws IOException
*/
@Override
- public InputStream getBytes() throws FileNotFoundException, IOException {
+ public InputStream getBytes() throws FileNotFoundException, IOException, DecalNotFoundException {
// First check if the decal is located on the file system
- File exportedFile = getFileSystemLocation();
+ File exportedFile = getDecalFile();
if (exportedFile != null) {
+ if (!exportedFile.exists()) {
+ throw new DecalNotFoundException(exportedFile.getAbsolutePath(), this);
+ }
InputStream rawIs = new FileInputStream(exportedFile);
try {
byte[] bytes = FileUtils.readBytes(rawIs);
@@ -164,38 +172,45 @@ public class DecalRegistry {
}
}
-
- return delegate.getBytes();
+ try {
+ return delegate.getBytes();
+ } catch (DecalNotFoundException decex) {
+ throw new DecalNotFoundException(delegate.getName(), this);
+ }
}
@Override
- public void exportImage(File file) throws IOException {
- try {
- InputStream is = getBytes();
- OutputStream os = new BufferedOutputStream(new FileOutputStream(file));
-
- FileUtils.copy(is, os);
-
- is.close();
- os.close();
-
- this.fileSystemLocation = file;
-
- } catch (IOException iex) {
- throw new BugException(iex);
- }
+ public void exportImage(File file) throws IOException, DecalNotFoundException {
+ InputStream is;
+ is = getBytes();
+ OutputStream os = new BufferedOutputStream(new FileOutputStream(file));
+
+ FileUtils.copy(is, os);
+
+ is.close();
+ os.close();
}
/**
*
* @return
*/
- File getFileSystemLocation() {
- return fileSystemLocation;
+ public File getDecalFile() {
+ return decalFile;
}
-
- void setFileSystemLocation(File fileSystemLocation) {
- this.fileSystemLocation = fileSystemLocation;
+
+ public void setDecalFile(File file) {
+ this.decalFile = file;
+ }
+
+ @Override
+ public boolean isIgnored() {
+ return this.ignored;
+ }
+
+ @Override
+ public void setIgnored(boolean ignored) {
+ this.ignored = ignored;
}
@Override
@@ -211,7 +226,7 @@ public class DecalRegistry {
@Override
protected DecalImageImpl clone() {
DecalImageImpl clone = new DecalImageImpl(this.delegate);
- clone.fileSystemLocation = this.fileSystemLocation;
+ clone.decalFile = this.decalFile;
return clone;
}
@@ -237,7 +252,7 @@ public class DecalRegistry {
private DecalImageImpl findDecalForFile(File file) {
for (DecalImageImpl d : registeredDecals.values()) {
- if (file.equals(d.getFileSystemLocation())) {
+ if (file.equals(d.getDecalFile())) {
return d;
}
}
diff --git a/core/src/net/sf/openrocket/document/attachments/FileSystemAttachment.java b/core/src/net/sf/openrocket/document/attachments/FileSystemAttachment.java
index 08ed7f7de..815312f36 100644
--- a/core/src/net/sf/openrocket/document/attachments/FileSystemAttachment.java
+++ b/core/src/net/sf/openrocket/document/attachments/FileSystemAttachment.java
@@ -7,6 +7,7 @@ import java.io.IOException;
import java.io.InputStream;
import net.sf.openrocket.document.Attachment;
+import net.sf.openrocket.util.DecalNotFoundException;
/**
*
@@ -41,7 +42,7 @@ public class FileSystemAttachment extends Attachment {
* creates the stream based on the location passed while building
*/
@Override
- public InputStream getBytes() throws IOException {
+ public InputStream getBytes() throws DecalNotFoundException, IOException {
return new FileInputStream(location);
}
diff --git a/core/src/net/sf/openrocket/document/attachments/ZipFileAttachment.java b/core/src/net/sf/openrocket/document/attachments/ZipFileAttachment.java
index d1baa9bfb..c48640f3e 100644
--- a/core/src/net/sf/openrocket/document/attachments/ZipFileAttachment.java
+++ b/core/src/net/sf/openrocket/document/attachments/ZipFileAttachment.java
@@ -1,7 +1,6 @@
package net.sf.openrocket.document.attachments;
import java.io.ByteArrayInputStream;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
@@ -9,6 +8,7 @@ import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import net.sf.openrocket.document.Attachment;
+import net.sf.openrocket.util.DecalNotFoundException;
import net.sf.openrocket.util.FileUtils;
public class ZipFileAttachment extends Attachment {
@@ -21,7 +21,7 @@ public class ZipFileAttachment extends Attachment {
}
@Override
- public InputStream getBytes() throws IOException {
+ public InputStream getBytes() throws DecalNotFoundException, IOException {
String name = getName();
ZipInputStream zis = new ZipInputStream(zipFileLocation.openStream());
@@ -35,7 +35,7 @@ public class ZipFileAttachment extends Attachment {
}
entry = zis.getNextEntry();
}
- throw new FileNotFoundException("Unable to locate decal for name " + name);
+ throw new DecalNotFoundException(name, null);
} finally {
zis.close();
}
diff --git a/core/src/net/sf/openrocket/file/AttachmentUtils.java b/core/src/net/sf/openrocket/file/AttachmentUtils.java
index 5d76d2036..e0bc3e749 100644
--- a/core/src/net/sf/openrocket/file/AttachmentUtils.java
+++ b/core/src/net/sf/openrocket/file/AttachmentUtils.java
@@ -8,11 +8,12 @@ import java.io.InputStream;
import java.io.OutputStream;
import net.sf.openrocket.document.Attachment;
+import net.sf.openrocket.util.DecalNotFoundException;
import net.sf.openrocket.util.FileUtils;
public abstract class AttachmentUtils {
- public static void exportAttachment(Attachment a, File outFile) throws IOException {
+ public static void exportAttachment(Attachment a, File outFile) throws IOException, DecalNotFoundException {
InputStream is = a.getBytes();
OutputStream os = new BufferedOutputStream(new FileOutputStream(outFile));
diff --git a/core/src/net/sf/openrocket/file/GeneralRocketSaver.java b/core/src/net/sf/openrocket/file/GeneralRocketSaver.java
index 4d4d5863e..1a8a26b42 100644
--- a/core/src/net/sf/openrocket/file/GeneralRocketSaver.java
+++ b/core/src/net/sf/openrocket/file/GeneralRocketSaver.java
@@ -22,6 +22,7 @@ import net.sf.openrocket.file.openrocket.OpenRocketSaver;
import net.sf.openrocket.file.rocksim.export.RocksimSaver;
import net.sf.openrocket.rocketcomponent.InsideColorComponent;
import net.sf.openrocket.rocketcomponent.RocketComponent;
+import net.sf.openrocket.util.DecalNotFoundException;
import net.sf.openrocket.util.MathUtil;
public class GeneralRocketSaver {
@@ -52,7 +53,7 @@ public class GeneralRocketSaver {
* @param document the document to save.
* @throws IOException in case of an I/O error.
*/
- public final void save(File dest, OpenRocketDocument document) throws IOException {
+ public final void save(File dest, OpenRocketDocument document) throws IOException, DecalNotFoundException {
save(dest, document, document.getDefaultStorageOptions());
}
@@ -64,7 +65,7 @@ public class GeneralRocketSaver {
* @param options the storage options.
* @throws IOException in case of an I/O error.
*/
- public final void save(File dest, OpenRocketDocument document, StorageOptions options) throws IOException {
+ public final void save(File dest, OpenRocketDocument document, StorageOptions options) throws IOException, DecalNotFoundException {
save(dest, document, options, null);
}
@@ -76,7 +77,7 @@ public class GeneralRocketSaver {
* @param progress a SavingProgress object used to provide progress information
* @throws IOException in case of an I/O error.
*/
- public final void save(File dest, OpenRocketDocument doc, SavingProgress progress) throws IOException {
+ public final void save(File dest, OpenRocketDocument doc, SavingProgress progress) throws IOException, DecalNotFoundException {
save(dest, doc, doc.getDefaultStorageOptions(), progress);
}
@@ -89,7 +90,7 @@ public class GeneralRocketSaver {
* @param progress a SavingProgress object used to provide progress information
* @throws IOException in case of an I/O error.
*/
- public final void save(File dest, OpenRocketDocument doc, StorageOptions opts, SavingProgress progress) throws IOException {
+ public final void save(File dest, OpenRocketDocument doc, StorageOptions opts, SavingProgress progress) throws IOException, DecalNotFoundException {
// This method is the core operational method. It saves the document into a new (hopefully unique)
// file, then if the save is successful, it will copy the file over the old one.
@@ -105,6 +106,9 @@ public class GeneralRocketSaver {
}
try {
save(dest.getName(), s, doc, opts);
+ } catch (DecalNotFoundException decex) {
+ temporaryNewFile.delete();
+ throw decex;
} finally {
s.close();
}
@@ -145,7 +149,7 @@ public class GeneralRocketSaver {
}
}
- private void save(String fileName, OutputStream output, OpenRocketDocument document, StorageOptions options) throws IOException {
+ private void save(String fileName, OutputStream output, OpenRocketDocument document, StorageOptions options) throws IOException, DecalNotFoundException {
// For now, we don't save decal information in ROCKSIM files, so don't do anything
// which follows.
@@ -181,8 +185,8 @@ public class GeneralRocketSaver {
saveAllPartsZipFile(output, document, options, usedDecals);
}
- public void saveAllPartsZipFile(OutputStream output, OpenRocketDocument document, StorageOptions options, Set decals) throws IOException {
-
+ public void saveAllPartsZipFile(OutputStream output, OpenRocketDocument document, StorageOptions options, Set decals) throws IOException, DecalNotFoundException {
+
// Open a zip stream to write to.
ZipOutputStream zos = new ZipOutputStream(output);
zos.setLevel(9);
@@ -196,9 +200,12 @@ public class GeneralRocketSaver {
zos.closeEntry();
// Now we write out all the decal images files.
-
for (DecalImage image : decals) {
-
+ if (image.isIgnored()) {
+ image.setIgnored(false);
+ continue;
+ }
+
String name = image.getName();
ZipEntry decal = new ZipEntry(name);
zos.putNextEntry(decal);
diff --git a/core/src/net/sf/openrocket/util/DecalNotFoundException.java b/core/src/net/sf/openrocket/util/DecalNotFoundException.java
new file mode 100644
index 000000000..b3a2a49cb
--- /dev/null
+++ b/core/src/net/sf/openrocket/util/DecalNotFoundException.java
@@ -0,0 +1,43 @@
+package net.sf.openrocket.util;
+
+import net.sf.openrocket.appearance.DecalImage;
+import net.sf.openrocket.l10n.Translator;
+import net.sf.openrocket.startup.Application;
+
+import java.text.MessageFormat;
+
+/**
+ * Exception for decals without a valid source file.
+ *
+ * @author Sibo Van Gool
+ */
+public class DecalNotFoundException extends Exception {
+ private final DecalImage decal;
+ private final Translator trans = Application.getTranslator();
+
+ /**
+ * Exception for decals without a valid source file.
+ * @param message the file path or decal name of the faulty DecalImage
+ * @param decal DecalImage that has an issue with its source file
+ */
+ public DecalNotFoundException(String message, DecalImage decal) {
+ super(message);
+ this.decal = decal;
+ }
+
+ /**
+ * Get the DecalImage that was the cause of this DecalNotFoundException.
+ * @return DecalImage that had an issue with its source file
+ */
+ public DecalImage getDecal() {
+ return decal;
+ }
+
+ /**
+ * Automatically combine the exception message with the DecalImage file name.
+ */
+ @Override
+ public String getMessage() {
+ return MessageFormat.format(trans.get("ExportDecalDialog.source.exception"), super.getMessage());
+ }
+}
diff --git a/swing/src/net/sf/openrocket/gui/dialogs/DecalNotFoundDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/DecalNotFoundDialog.java
new file mode 100644
index 000000000..e14c05a15
--- /dev/null
+++ b/swing/src/net/sf/openrocket/gui/dialogs/DecalNotFoundDialog.java
@@ -0,0 +1,50 @@
+package net.sf.openrocket.gui.dialogs;
+
+import net.sf.openrocket.gui.util.MessageWidthUtil;
+import net.sf.openrocket.gui.util.SwingPreferences;
+import net.sf.openrocket.l10n.Translator;
+import net.sf.openrocket.startup.Application;
+import net.sf.openrocket.util.DecalNotFoundException;
+
+import javax.swing.JFileChooser;
+import javax.swing.JOptionPane;
+import java.awt.Component;
+import java.io.File;
+
+/**
+ * Dialog for handling a DecalNotFoundException.
+ *
+ * @author Sibo Van Gool
+ */
+public abstract class DecalNotFoundDialog {
+
+ /**
+ * Show a yes/no dialog telling the user that a certain decal source file can't be found and asking whether he/she
+ * wants to look for that file. If prompted yes, a FileChooser opens up to select the file. If a file is selected,
+ * the source file of the decal, present in , will be replaced with the selected file.
+ * @param parent parent window for the pop-up windows
+ * @param decex exception containing the decal file path as message and DecalImage
+ * @return true if the decal has been replaced/found, false if the decal source file issue did not get fixed by the user
+ */
+ public static boolean showDialog(Component parent, DecalNotFoundException decex) {
+ Translator trans = Application.getTranslator();
+
+ // Show 'look up file" yes/no dialog
+ String message = MessageWidthUtil.setMessageWidth(decex.getMessage(), 400);
+ int resultYesNo = JOptionPane.showConfirmDialog(parent, message,
+ trans.get("ExportDecalDialog.source.title"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
+ int resultFileChooser = JFileChooser.CANCEL_OPTION;
+
+ // Look for the file
+ if (resultYesNo == JOptionPane.YES_OPTION) {
+ JFileChooser chooser = new JFileChooser();
+ chooser.setCurrentDirectory(((SwingPreferences) Application.getPreferences()).getDefaultDirectory());
+ resultFileChooser = chooser.showOpenDialog(parent);
+ if (resultFileChooser == JFileChooser.APPROVE_OPTION) {
+ File file = chooser.getSelectedFile();
+ decex.getDecal().setDecalFile(file);
+ }
+ }
+ return (resultYesNo == JOptionPane.YES_OPTION) && (resultFileChooser == JFileChooser.APPROVE_OPTION);
+ }
+}
diff --git a/swing/src/net/sf/openrocket/gui/main/BasicFrame.java b/swing/src/net/sf/openrocket/gui/main/BasicFrame.java
index 74279499b..d3182f3e4 100644
--- a/swing/src/net/sf/openrocket/gui/main/BasicFrame.java
+++ b/swing/src/net/sf/openrocket/gui/main/BasicFrame.java
@@ -60,8 +60,11 @@ import javax.swing.tree.DefaultTreeSelectionModel;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
+import net.sf.openrocket.appearance.DecalImage;
+import net.sf.openrocket.gui.dialogs.DecalNotFoundDialog;
import net.sf.openrocket.gui.widgets.SelectColorButton;
import net.sf.openrocket.rocketcomponent.AxialStage;
+import net.sf.openrocket.util.DecalNotFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -1418,14 +1421,31 @@ public class BasicFrame extends JFrame {
}
}
+ StorageOptions options = new StorageOptions();
+ options.setFileType(StorageOptions.FileType.ROCKSIM);
+ return saveRocksimFile(file, options);
+ }
+
+ /**
+ * Perform the actual saving of the Rocksim file
+ * @param file file to be stored
+ * @param options storage options to use
+ * @return true if the file was written
+ */
+ private boolean saveRocksimFile(File file, StorageOptions options) {
try {
- StorageOptions options = new StorageOptions();
- options.setFileType(StorageOptions.FileType.ROCKSIM);
ROCKET_SAVER.save(file, document, options);
// Do not update the save state of the document.
return true;
} catch (IOException e) {
return false;
+ } catch (DecalNotFoundException decex) {
+ DecalImage decal = decex.getDecal();
+ // Check if the user replaced the source file, if not, just ignore the faulty decal on the next save
+ if (!DecalNotFoundDialog.showDialog(null, decex) && decal != null) {
+ decal.setIgnored(true);
+ }
+ return saveRocksimFile(file, options); // Resave
}
}
@@ -1509,6 +1529,16 @@ public class BasicFrame extends JFrame {
"An I/O error occurred while saving:",
e.getMessage() }, "Saving failed", JOptionPane.ERROR_MESSAGE);
return false;
+ }
+ else if (cause instanceof DecalNotFoundException) {
+ DecalNotFoundException decex = (DecalNotFoundException) cause;
+ DecalImage decal = decex.getDecal();
+ // Check if the user replaced the source file, if not, just ignore the faulty decal on the next save
+ if (!DecalNotFoundDialog.showDialog(null, decex) && decal != null) {
+ decal.setIgnored(true);
+ }
+ return saveAsOpenRocket(file); // Resave
+
} else {
Reflection.handleWrappedException(e);
}
diff --git a/swing/src/net/sf/openrocket/gui/main/ExportDecalDialog.java b/swing/src/net/sf/openrocket/gui/main/ExportDecalDialog.java
index bb7afe25a..18e3c4ba1 100644
--- a/swing/src/net/sf/openrocket/gui/main/ExportDecalDialog.java
+++ b/swing/src/net/sf/openrocket/gui/main/ExportDecalDialog.java
@@ -20,10 +20,12 @@ import javax.swing.JPanel;
import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.appearance.DecalImage;
import net.sf.openrocket.document.OpenRocketDocument;
+import net.sf.openrocket.gui.dialogs.DecalNotFoundDialog;
import net.sf.openrocket.gui.util.FileHelper;
import net.sf.openrocket.gui.util.SwingPreferences;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.startup.Application;
+import net.sf.openrocket.util.DecalNotFoundException;
@SuppressWarnings("serial")
public class ExportDecalDialog extends JDialog {
@@ -102,6 +104,8 @@ public class ExportDecalDialog extends JDialog {
try {
decal.exportImage(selectedFile);
+ } catch (DecalNotFoundException e) {
+ DecalNotFoundDialog.showDialog(this, e);
} catch (IOException iex) {
String message = MessageFormat.format(trans.get("ExportDecalDialog.exception"), selectedFile.getAbsoluteFile());
JOptionPane.showMessageDialog(this, message, "", JOptionPane.ERROR_MESSAGE);
diff --git a/swing/src/net/sf/openrocket/gui/util/EditDecalHelper.java b/swing/src/net/sf/openrocket/gui/util/EditDecalHelper.java
index 7fbf24e17..146630e23 100644
--- a/swing/src/net/sf/openrocket/gui/util/EditDecalHelper.java
+++ b/swing/src/net/sf/openrocket/gui/util/EditDecalHelper.java
@@ -11,6 +11,7 @@ import net.sf.openrocket.appearance.DecalImage;
import net.sf.openrocket.arch.SystemInfo;
import net.sf.openrocket.arch.SystemInfo.Platform;
import net.sf.openrocket.document.OpenRocketDocument;
+import net.sf.openrocket.gui.dialogs.DecalNotFoundDialog;
import net.sf.openrocket.gui.dialogs.EditDecalDialog;
import net.sf.openrocket.gui.watcher.FileWatcher;
import net.sf.openrocket.gui.watcher.WatchEvent;
@@ -21,6 +22,7 @@ import net.sf.openrocket.rocketcomponent.InsideColorComponentHandler;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import com.google.inject.Inject;
+import net.sf.openrocket.util.DecalNotFoundException;
public class EditDecalHelper {
@@ -83,7 +85,7 @@ public class EditDecalHelper {
//First Check preferences
if (usageCount == 1 && (sysPrefSet || isSnapConfined)) {
String commandLine = isSnapConfined ? "xdg-open %%" : prefs.getDecalEditorCommandLine();
- launchEditor(prefs.isDecalEditorPreferenceSystem(), commandLine, decal);
+ launchEditor(parent, prefs.isDecalEditorPreferenceSystem(), commandLine, decal);
return decal;
}
@@ -121,7 +123,7 @@ public class EditDecalHelper {
decal = makeDecalUniqueInside(doc, component, decal);
}
- launchEditor(useSystemEditor, commandLine, decal);
+ launchEditor(parent, useSystemEditor, commandLine, decal);
return decal;
@@ -154,7 +156,7 @@ public class EditDecalHelper {
return newImage;
}
- private void launchEditor(boolean useSystemEditor, String commandTemplate, final DecalImage decal) throws EditDecalHelperException {
+ private void launchEditor(Window parent, boolean useSystemEditor, String commandTemplate, final DecalImage decal) throws EditDecalHelperException {
String decalId = decal.getName();
// Create Temp File.
@@ -188,6 +190,11 @@ public class EditDecalHelper {
} catch (IOException ioex) {
String message = MessageFormat.format(trans.get("EditDecalHelper.createFileException"), tmpFile.getAbsoluteFile());
throw new EditDecalHelperException(message, ioex);
+ } catch (DecalNotFoundException decex) {
+ if (DecalNotFoundDialog.showDialog(parent, decex)) {
+ launchEditor(parent, useSystemEditor, commandTemplate, decal);
+ }
+ return;
}
diff --git a/swing/src/net/sf/openrocket/gui/util/MessageWidthUtil.java b/swing/src/net/sf/openrocket/gui/util/MessageWidthUtil.java
new file mode 100644
index 000000000..1c8f22e1e
--- /dev/null
+++ b/swing/src/net/sf/openrocket/gui/util/MessageWidthUtil.java
@@ -0,0 +1,19 @@
+package net.sf.openrocket.gui.util;
+
+/**
+ * Helper class for setting the message width for e.g. JOptionPane pop-ups using HTML formatting.
+ *
+ * @author Sibo Van Gool
+ */
+public abstract class MessageWidthUtil {
+ /**
+ * Set the message width of to pixels using HTML formatting.
+ * @param message message to be formatted
+ * @param px width of the message in pixels
+ * @return HTML-formatted message
+ *
+ */
+ public static String setMessageWidth(String message, int px) {
+ return String.format("%s
", px, message);
+ }
+}
diff --git a/swing/src/net/sf/openrocket/utils/RocksimConverter.java b/swing/src/net/sf/openrocket/utils/RocksimConverter.java
index e60a808a1..651e61c3f 100644
--- a/swing/src/net/sf/openrocket/utils/RocksimConverter.java
+++ b/swing/src/net/sf/openrocket/utils/RocksimConverter.java
@@ -9,6 +9,8 @@ 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.dialogs.DecalNotFoundDialog;
+import net.sf.openrocket.util.DecalNotFoundException;
/**
* Utility that loads Rocksim file formats and saves them in ORK format.
@@ -64,6 +66,8 @@ public class RocksimConverter {
System.err.println("ERROR: Error loading '" + inputFile + "': " + e.getMessage());
} catch (IOException e) {
System.err.println("ERROR: Error saving '" + outputFile + "': " + e.getMessage());
+ } catch (DecalNotFoundException decex) {
+ DecalNotFoundDialog.showDialog(null, decex);
}
}