Merge pull request #251 from kruland2607/save-dialogs

Save dialogs
This commit is contained in:
kruland2607 2015-11-30 18:57:59 -06:00
commit 00d7e8715d
10 changed files with 629 additions and 420 deletions

View File

@ -258,6 +258,7 @@ pref.dlg.tab.Design = Design
pref.dlg.tab.Simulation = Simulation pref.dlg.tab.Simulation = Simulation
pref.dlg.tab.Launch = Launch pref.dlg.tab.Launch = Launch
pref.dlg.tab.Miscellaneousoptions = Miscellaneous options pref.dlg.tab.Miscellaneousoptions = Miscellaneous options
pref.dlg.lbl.RockSimWarning = Show warning when saving in RockSim format
pref.dlg.tab.Graphics = Graphics pref.dlg.tab.Graphics = Graphics
pref.dlg.lbl.DecalEditor = Graphics Editor pref.dlg.lbl.DecalEditor = Graphics Editor
@ -1134,6 +1135,13 @@ FinsetCfg.ttip.Finfillets1 = <HTML>Adds the predicted mass of fin fillets to the
FinsetCfg.ttip.Finfillets2 = Assumes the fillet is concave and tangent to the body tube and fin.<br> FinsetCfg.ttip.Finfillets2 = Assumes the fillet is concave and tangent to the body tube and fin.<br>
FinsetCfg.ttip.Finfillets3 = Zero radius will give no fillet. FinsetCfg.ttip.Finfillets3 = Zero radius will give no fillet.
! Save RKT Warning Dialog
SaveRktWarningDialog.txt1=Exporting to RockSim file format does not support all features of OpenRocket.
SaveRktWarningDialog.donotshow=Do not show this dialog again
saveAs.openrocket.title=Save as OpenRocket ork file
saveAs.rocksim.title=Export as RockSim rkt file
! StorageOptionChooser ! StorageOptionChooser
StorageOptChooser.lbl.Simdatatostore = Simulated data to store: StorageOptChooser.lbl.Simdatatostore = Simulated data to store:
StorageOptChooser.rdbut.Allsimdata = All simulated data StorageOptChooser.rdbut.Allsimdata = All simulated data
@ -1201,26 +1209,30 @@ main.menu.file.desc = File-handling related tasks
main.menu.file.new = New main.menu.file.new = New
main.menu.file.new.desc = Create a new rocket design main.menu.file.new.desc = Create a new rocket design
main.menu.file.open = Open... main.menu.file.open = Open...
BasicFrame.item.Openrocketdesign = Open a rocket design main.menu.file.open.desc = Open a rocket design
main.menu.file.openRecent = Open Recent... main.menu.file.openRecent = Open Recent...
BasicFrame.item.Openrecentrocketdesign = Open a recent rocket design main.menu.file.openRecent.desc = Open a recent rocket design
main.menu.file.openExample = Open example... main.menu.file.openExample = Open Example...
BasicFrame.item.Openexamplerocketdesign = Open an example rocket design main.menu.file.openExample.desc = Open an example rocket design
main.menu.file.save = Save main.menu.file.save = Save
BasicFrame.item.SavecurRocketdesign = Save the current rocket design main.menu.file.save.desc = Save the current rocket design
main.menu.file.saveAs = Save as... main.menu.file.saveAs = Save as...
BasicFrame.item.SavecurRocketdesnewfile = Save the current rocket design to a new file main.menu.file.saveAs.desc = Save the current rocket design to a new file
main.menu.file.import = Import...
main.menu.file.import.desc = Import model from RockSim rkt file
main.menu.file.export = Export...
main.menu.file.export.desc = Export model to RockSim rkt file
main.menu.file.print = Print / Export PDF... main.menu.file.print = Print / Export PDF...
main.menu.file.print.desc = Print or save as PDF the parts list and fin templates main.menu.file.print.desc = Print or save as PDF the parts list and fin templates
main.menu.file.close = Close main.menu.file.close = Close
BasicFrame.item.Closedesign = Close the current rocket design main.menu.file.close.desc = Close the current rocket design
main.menu.file.quit = Quit main.menu.file.quit = Quit
BasicFrame.item.Quitprogram = Quit the program main.menu.file.quit.desc = Quit the program
main.menu.file.exportDecal = Export Decal main.menu.file.exportDecal = Export Decal
main.menu.file.exportDecal.desc = Export a decal from the current rocket design to a file for editing. main.menu.file.exportDecal.desc = Export a decal from the current rocket design to a file for editing.
main.menu.edit = Edit main.menu.edit = Edit
BasicFrame.menu.Rocketedt = Rocket editing main.menu.edit.desc = Rocket editing
main.menu.edit.undo = Undo main.menu.edit.undo = Undo
main.menu.edit.undo.desc = Undo the previous operation main.menu.edit.undo.desc = Undo the previous operation
main.menu.edit.redo = Redo main.menu.edit.redo = Redo

View File

@ -4,9 +4,15 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.List; import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.document.Simulation; import net.sf.openrocket.document.Simulation;
import net.sf.openrocket.document.StorageOptions; import net.sf.openrocket.document.StorageOptions;
import net.sf.openrocket.document.StorageOptions.FileType;
import net.sf.openrocket.file.AbstractRocketLoader; import net.sf.openrocket.file.AbstractRocketLoader;
import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.DocumentLoadingContext;
import net.sf.openrocket.file.RocketLoadException; import net.sf.openrocket.file.RocketLoadException;
@ -15,11 +21,6 @@ import net.sf.openrocket.simulation.FlightDataBranch;
import net.sf.openrocket.simulation.FlightDataType; import net.sf.openrocket.simulation.FlightDataType;
import net.sf.openrocket.simulation.extension.SimulationExtension; import net.sf.openrocket.simulation.extension.SimulationExtension;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/** /**
* Class that loads a rocket definition from an OpenRocket rocket file. * Class that loads a rocket definition from an OpenRocket rocket file.
@ -81,6 +82,7 @@ public class OpenRocketLoader extends AbstractRocketLoader {
timeSkip = Math.rint(timeSkip * 100) / 100; timeSkip = Math.rint(timeSkip * 100) / 100;
doc.getDefaultStorageOptions().setSimulationTimeSkip(timeSkip); doc.getDefaultStorageOptions().setSimulationTimeSkip(timeSkip);
doc.getDefaultStorageOptions().setExplicitlySet(false); doc.getDefaultStorageOptions().setExplicitlySet(false);
doc.getDefaultStorageOptions().setFileType(FileType.OPENROCKET);
// Call simulation extensions // Call simulation extensions
for (Simulation sim : doc.getSimulations()) { for (Simulation sim : doc.getSimulations()) {

View File

@ -6,14 +6,15 @@ package net.sf.openrocket.file.rocksim.importt;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import net.sf.openrocket.document.StorageOptions.FileType;
import net.sf.openrocket.file.AbstractRocketLoader; import net.sf.openrocket.file.AbstractRocketLoader;
import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.DocumentLoadingContext;
import net.sf.openrocket.file.RocketLoadException; import net.sf.openrocket.file.RocketLoadException;
import net.sf.openrocket.file.simplesax.SimpleSAX; import net.sf.openrocket.file.simplesax.SimpleSAX;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/** /**
* This class is the main entry point for Rocksim design file imported to OpenRocket. Currently only Rocksim v9 * This class is the main entry point for Rocksim design file imported to OpenRocket. Currently only Rocksim v9
* file formats are supported, although it is possible that v8 formats will work for most components. * file formats are supported, although it is possible that v8 formats will work for most components.
@ -52,5 +53,6 @@ public class RocksimLoader extends AbstractRocketLoader {
context.getOpenRocketDocument().setFile(null); context.getOpenRocketDocument().setFile(null);
context.getOpenRocketDocument().clearUndo(); context.getOpenRocketDocument().clearUndo();
context.getOpenRocketDocument().getDefaultStorageOptions().setFileType(FileType.ROCKSIM);
} }
} }

View File

@ -61,6 +61,7 @@ public abstract class Preferences implements ChangeSource {
// Node names // Node names
public static final String PREFERRED_THRUST_CURVE_MOTOR_NODE = "preferredThrustCurveMotors"; public static final String PREFERRED_THRUST_CURVE_MOTOR_NODE = "preferredThrustCurveMotors";
private static final String AUTO_OPEN_LAST_DESIGN = "AUTO_OPEN_LAST_DESIGN"; private static final String AUTO_OPEN_LAST_DESIGN = "AUTO_OPEN_LAST_DESIGN";
private static final String SHOW_ROCKSIM_FORMAT_WARNING = "SHOW_ROCKSIM_FORMAT_WARNING";
//Preferences related to 3D graphics //Preferences related to 3D graphics
public static final String OPENGL_ENABLED = "OpenGL_Is_Enabled"; public static final String OPENGL_ENABLED = "OpenGL_Is_Enabled";
@ -162,6 +163,14 @@ public abstract class Preferences implements ChangeSource {
this.putBoolean(LAUNCH_INTO_WIND, check); this.putBoolean(LAUNCH_INTO_WIND, check);
} }
public final boolean getShowRockSimFormatWarning() {
return this.getBoolean(SHOW_ROCKSIM_FORMAT_WARNING, true);
}
public final void setShowRockSimFormatWarning(boolean check) {
this.putBoolean(SHOW_ROCKSIM_FORMAT_WARNING, check);
}
public final double getDefaultMach() { public final double getDefaultMach() {
return Application.getPreferences().getChoice(Preferences.DEFAULT_MACH_NUMBER, 0.9, 0.3); return Application.getPreferences().getChoice(Preferences.DEFAULT_MACH_NUMBER, 0.9, 0.3);
} }
@ -736,12 +745,14 @@ public abstract class Preferences implements ChangeSource {
*/ */
private static final HashMap<Class<?>, String> DEFAULT_LINE_STYLES = new HashMap<Class<?>, String>(); private static final HashMap<Class<?>, String> DEFAULT_LINE_STYLES = new HashMap<Class<?>, String>();
static { static {
DEFAULT_LINE_STYLES.put(RocketComponent.class, LineStyle.SOLID.name()); DEFAULT_LINE_STYLES.put(RocketComponent.class, LineStyle.SOLID.name());
DEFAULT_LINE_STYLES.put(MassObject.class, LineStyle.DASHED.name()); DEFAULT_LINE_STYLES.put(MassObject.class, LineStyle.DASHED.name());
} }
private static final HashMap<Class<?>, String> DEFAULT_COLORS = new HashMap<Class<?>, String>(); private static final HashMap<Class<?>, String> DEFAULT_COLORS = new HashMap<Class<?>, String>();
static { static {
DEFAULT_COLORS.put(BodyComponent.class, "0,0,240"); DEFAULT_COLORS.put(BodyComponent.class, "0,0,240");
DEFAULT_COLORS.put(TubeFinSet.class, "0,0,200"); DEFAULT_COLORS.put(TubeFinSet.class, "0,0,200");

View File

@ -208,6 +208,30 @@ public class GeneralPreferencesPanel extends PreferencesPanel {
} }
}); });
this.add(button, "right, wrap"); this.add(button, "right, wrap");
//// Open most recent file on startup
final JCheckBox openRecentOnStartupBox = new JCheckBox(trans.get("pref.dlg.but.openlast"));
openRecentOnStartupBox.setSelected(preferences.isAutoOpenLastDesignOnStartupEnabled());
openRecentOnStartupBox.addActionListener( new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
preferences.setAutoOpenLastDesignOnStartup(openRecentOnStartupBox.isSelected());
}
});
this.add(openRecentOnStartupBox,"spanx, wrap");
//// Save RockSim Format warning dialog
final JCheckBox rocksimWarningDialogBox = new JCheckBox(trans.get("pref.dlg.lbl.RockSimWarning"));
rocksimWarningDialogBox.setSelected(preferences.getShowRockSimFormatWarning());
rocksimWarningDialogBox.addActionListener( new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
preferences.setShowRockSimFormatWarning(rocksimWarningDialogBox.isSelected());
}
});
this.add(rocksimWarningDialogBox,"spanx, wrap");
} }

View File

@ -12,8 +12,6 @@ import java.awt.event.MouseEvent;
import java.awt.event.MouseListener; import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter; import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent; import java.awt.event.WindowEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
@ -33,6 +31,7 @@ import javax.swing.Action;
import javax.swing.BorderFactory; import javax.swing.BorderFactory;
import javax.swing.InputMap; import javax.swing.InputMap;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JDialog; import javax.swing.JDialog;
import javax.swing.JFileChooser; import javax.swing.JFileChooser;
@ -54,22 +53,25 @@ import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.border.BevelBorder; import javax.swing.border.BevelBorder;
import javax.swing.border.TitledBorder; import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener; import javax.swing.event.TreeSelectionListener;
import javax.swing.event.ChangeEvent;
import javax.swing.tree.DefaultTreeSelectionModel; import javax.swing.tree.DefaultTreeSelectionModel;
import javax.swing.tree.TreePath; import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel; import javax.swing.tree.TreeSelectionModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.aerodynamics.WarningSet; import net.sf.openrocket.aerodynamics.WarningSet;
import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.document.OpenRocketDocumentFactory; import net.sf.openrocket.document.OpenRocketDocumentFactory;
import net.sf.openrocket.document.StorageOptions; import net.sf.openrocket.document.StorageOptions;
import net.sf.openrocket.document.StorageOptions.FileType;
import net.sf.openrocket.file.GeneralRocketSaver; import net.sf.openrocket.file.GeneralRocketSaver;
import net.sf.openrocket.file.RocketLoadException; import net.sf.openrocket.file.RocketLoadException;
import net.sf.openrocket.gui.ExportDecalDialog; import net.sf.openrocket.gui.components.StyledLabel;
import net.sf.openrocket.gui.StorageOptionChooser;
import net.sf.openrocket.gui.configdialog.ComponentConfigDialog; import net.sf.openrocket.gui.configdialog.ComponentConfigDialog;
import net.sf.openrocket.gui.customexpression.CustomExpressionDialog; import net.sf.openrocket.gui.customexpression.CustomExpressionDialog;
import net.sf.openrocket.gui.dialogs.AboutDialog; import net.sf.openrocket.gui.dialogs.AboutDialog;
@ -94,7 +96,6 @@ import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.gui.util.Icons; import net.sf.openrocket.gui.util.Icons;
import net.sf.openrocket.gui.util.OpenFileWorker; import net.sf.openrocket.gui.util.OpenFileWorker;
import net.sf.openrocket.gui.util.SaveFileWorker; import net.sf.openrocket.gui.util.SaveFileWorker;
import net.sf.openrocket.gui.util.SimpleFileFilter;
import net.sf.openrocket.gui.util.SwingPreferences; import net.sf.openrocket.gui.util.SwingPreferences;
import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.logging.Markers; import net.sf.openrocket.logging.Markers;
@ -103,6 +104,7 @@ import net.sf.openrocket.rocketcomponent.ComponentChangeListener;
import net.sf.openrocket.rocketcomponent.Rocket; import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.startup.Application; import net.sf.openrocket.startup.Application;
import net.sf.openrocket.startup.Preferences;
import net.sf.openrocket.util.BugException; import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.MemoryManagement; import net.sf.openrocket.util.MemoryManagement;
import net.sf.openrocket.util.MemoryManagement.MemoryData; import net.sf.openrocket.util.MemoryManagement.MemoryData;
@ -111,15 +113,13 @@ import net.sf.openrocket.util.StateChangeListener;
import net.sf.openrocket.util.TestRockets; import net.sf.openrocket.util.TestRockets;
import net.sf.openrocket.utils.ComponentPresetEditor; import net.sf.openrocket.utils.ComponentPresetEditor;
import org.slf4j.Logger; public class BasicFrame extends JFrame {
import org.slf4j.LoggerFactory;
public class BasicFrame extends JFrame implements PropertyChangeListener {
private static final Logger log = LoggerFactory.getLogger(BasicFrame.class); private static final Logger log = LoggerFactory.getLogger(BasicFrame.class);
private static final GeneralRocketSaver ROCKET_SAVER = new GeneralRocketSaver(); private static final GeneralRocketSaver ROCKET_SAVER = new GeneralRocketSaver();
private static final Translator trans = Application.getTranslator(); private static final Translator trans = Application.getTranslator();
private static final Preferences prefs = Application.getPreferences();
private static final int SHORTCUT_KEY = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); private static final int SHORTCUT_KEY = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
@ -141,8 +141,6 @@ public class BasicFrame extends JFrame implements PropertyChangeListener {
*/ */
private boolean replaceable = false; private boolean replaceable = false;
private final OpenRocketDocument document; private final OpenRocketDocument document;
private final Rocket rocket; private final Rocket rocket;
@ -429,7 +427,7 @@ public class BasicFrame extends JFrame implements PropertyChangeListener {
item = new JMenuItem(trans.get("main.menu.file.open"), KeyEvent.VK_O); item = new JMenuItem(trans.get("main.menu.file.open"), KeyEvent.VK_O);
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, SHORTCUT_KEY)); item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, SHORTCUT_KEY));
//// Open a rocket design //// Open a rocket design
item.getAccessibleContext().setAccessibleDescription(trans.get("BasicFrame.item.Openrocketdesign")); item.getAccessibleContext().setAccessibleDescription(trans.get("main.menu.file.open.desc"));
item.setIcon(Icons.FILE_OPEN); item.setIcon(Icons.FILE_OPEN);
item.addActionListener(new ActionListener() { item.addActionListener(new ActionListener() {
@Override @Override
@ -442,13 +440,13 @@ public class BasicFrame extends JFrame implements PropertyChangeListener {
//// Open Recent... //// Open Recent...
item = new MRUDesignFileAction(trans.get("main.menu.file.openRecent"), this); item = new MRUDesignFileAction(trans.get("main.menu.file.openRecent"), this);
item.getAccessibleContext().setAccessibleDescription(trans.get("BasicFrame.item.Openrecentrocketdesign")); item.getAccessibleContext().setAccessibleDescription(trans.get("main.menu.file.openRecent.desc"));
item.setIcon(Icons.FILE_OPEN); item.setIcon(Icons.FILE_OPEN);
menu.add(item); menu.add(item);
//// Open example... //// Open example...
item = new ExampleDesignFileAction(trans.get("main.menu.file.openExample"), this); item = new ExampleDesignFileAction(trans.get("main.menu.file.openExample"), this);
item.getAccessibleContext().setAccessibleDescription(trans.get("BasicFrame.item.Openexamplerocketdesign")); item.getAccessibleContext().setAccessibleDescription(trans.get("main.menu.file.openExample.desc"));
item.setIcon(Icons.FILE_OPEN_EXAMPLE); item.setIcon(Icons.FILE_OPEN_EXAMPLE);
menu.add(item); menu.add(item);
@ -458,7 +456,7 @@ public class BasicFrame extends JFrame implements PropertyChangeListener {
item = new JMenuItem(trans.get("main.menu.file.save"), KeyEvent.VK_S); item = new JMenuItem(trans.get("main.menu.file.save"), KeyEvent.VK_S);
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, SHORTCUT_KEY)); item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, SHORTCUT_KEY));
//// Save the current rocket design //// Save the current rocket design
item.getAccessibleContext().setAccessibleDescription(trans.get("BasicFrame.item.SavecurRocketdesign")); item.getAccessibleContext().setAccessibleDescription(trans.get("main.menu.file.save.desc"));
item.setIcon(Icons.FILE_SAVE); item.setIcon(Icons.FILE_SAVE);
item.addActionListener(new ActionListener() { item.addActionListener(new ActionListener() {
@Override @Override
@ -474,7 +472,7 @@ public class BasicFrame extends JFrame implements PropertyChangeListener {
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,
SHORTCUT_KEY | ActionEvent.SHIFT_MASK)); SHORTCUT_KEY | ActionEvent.SHIFT_MASK));
//// Save the current rocket design to a new file //// Save the current rocket design to a new file
item.getAccessibleContext().setAccessibleDescription(trans.get("BasicFrame.item.SavecurRocketdesnewfile")); item.getAccessibleContext().setAccessibleDescription(trans.get("main.menu.file.saveAs.desc"));
item.setIcon(Icons.FILE_SAVE_AS); item.setIcon(Icons.FILE_SAVE_AS);
item.addActionListener(new ActionListener() { item.addActionListener(new ActionListener() {
@Override @Override
@ -485,6 +483,31 @@ public class BasicFrame extends JFrame implements PropertyChangeListener {
}); });
menu.add(item); menu.add(item);
menu.addSeparator();
//// Import Rocksim
item = new JMenuItem(trans.get("main.menu.file.import"));
item.getAccessibleContext().setAccessibleDescription(trans.get("main.menu.file.import.desc"));
item.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
log.info(Markers.USER_MARKER, "Import... selected");
importAction();
}
});
menu.add(item);
//// Export Rocksim
item = new JMenuItem(trans.get("main.menu.file.export"));
item.getAccessibleContext().setAccessibleDescription(trans.get("main.menu.file.export.desc"));
item.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
log.info(Markers.USER_MARKER, "Export... selected");
exportAction();
}
});
menu.add(item);
//// Export decal... //// Export decal...
item = new JMenuItem(trans.get("main.menu.file.exportDecal")); item = new JMenuItem(trans.get("main.menu.file.exportDecal"));
@ -530,7 +553,7 @@ public class BasicFrame extends JFrame implements PropertyChangeListener {
item = new JMenuItem(trans.get("main.menu.file.close"), KeyEvent.VK_C); item = new JMenuItem(trans.get("main.menu.file.close"), KeyEvent.VK_C);
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W, SHORTCUT_KEY)); item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W, SHORTCUT_KEY));
//// Close the current rocket design //// Close the current rocket design
item.getAccessibleContext().setAccessibleDescription(trans.get("BasicFrame.item.Closedesign")); item.getAccessibleContext().setAccessibleDescription(trans.get("main.menu.file.close.desc"));
item.setIcon(Icons.FILE_CLOSE); item.setIcon(Icons.FILE_CLOSE);
item.addActionListener(new ActionListener() { item.addActionListener(new ActionListener() {
@Override @Override
@ -547,7 +570,7 @@ public class BasicFrame extends JFrame implements PropertyChangeListener {
item = new JMenuItem(trans.get("main.menu.file.quit"), KeyEvent.VK_Q); item = new JMenuItem(trans.get("main.menu.file.quit"), KeyEvent.VK_Q);
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, SHORTCUT_KEY)); item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, SHORTCUT_KEY));
//// Quit the program //// Quit the program
item.getAccessibleContext().setAccessibleDescription(trans.get("BasicFrame.item.Quitprogram")); item.getAccessibleContext().setAccessibleDescription(trans.get("main.menu.file.quit.desc"));
item.setIcon(Icons.FILE_QUIT); item.setIcon(Icons.FILE_QUIT);
item.addActionListener(new ActionListener() { item.addActionListener(new ActionListener() {
@Override @Override
@ -564,7 +587,7 @@ public class BasicFrame extends JFrame implements PropertyChangeListener {
menu = new JMenu(trans.get("main.menu.edit")); menu = new JMenu(trans.get("main.menu.edit"));
menu.setMnemonic(KeyEvent.VK_E); menu.setMnemonic(KeyEvent.VK_E);
//// Rocket editing //// Rocket editing
menu.getAccessibleContext().setAccessibleDescription(trans.get("BasicFrame.menu.Rocketedt")); menu.getAccessibleContext().setAccessibleDescription(trans.get("main.menu.edit.desc"));
menubar.add(menu); menubar.add(menu);
@ -1067,8 +1090,7 @@ public class BasicFrame extends JFrame implements PropertyChangeListener {
chooser.addChoosableFileFilter(FileHelper.ALL_DESIGNS_FILTER); chooser.addChoosableFileFilter(FileHelper.ALL_DESIGNS_FILTER);
chooser.addChoosableFileFilter(FileHelper.OPENROCKET_DESIGN_FILTER); chooser.addChoosableFileFilter(FileHelper.OPENROCKET_DESIGN_FILTER);
chooser.addChoosableFileFilter(FileHelper.ROCKSIM_DESIGN_FILTER); chooser.setFileFilter(FileHelper.OPENROCKET_DESIGN_FILTER);
chooser.setFileFilter(FileHelper.ALL_DESIGNS_FILTER);
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
chooser.setMultiSelectionEnabled(true); chooser.setMultiSelectionEnabled(true);
@ -1093,6 +1115,37 @@ public class BasicFrame extends JFrame implements PropertyChangeListener {
} }
} }
private void importAction() {
JFileChooser chooser = new JFileChooser();
chooser.addChoosableFileFilter(FileHelper.ALL_DESIGNS_FILTER);
chooser.addChoosableFileFilter(FileHelper.ROCKSIM_DESIGN_FILTER);
chooser.setFileFilter(FileHelper.ROCKSIM_DESIGN_FILTER);
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
chooser.setMultiSelectionEnabled(true);
chooser.setCurrentDirectory(((SwingPreferences) Application.getPreferences()).getDefaultDirectory());
int option = chooser.showOpenDialog(this);
if (option != JFileChooser.APPROVE_OPTION) {
log.info(Markers.USER_MARKER, "Decided not to open files, option=" + option);
return;
}
((SwingPreferences) Application.getPreferences()).setDefaultDirectory(chooser.getCurrentDirectory());
File[] files = chooser.getSelectedFiles();
log.info(Markers.USER_MARKER, "Opening files " + Arrays.toString(files));
for (File file : files) {
log.info("Opening file: " + file);
if (open(file, this)) {
MRUDesignFile opts = MRUDesignFile.getInstance();
opts.addFile(file.getAbsolutePath());
}
}
}
void closeIfReplaceable() { void closeIfReplaceable() {
// Close previous window if replacing // Close previous window if replacing
if (replaceable && document.isSaved()) { if (replaceable && document.isSaved()) {
@ -1265,88 +1318,29 @@ public class BasicFrame extends JFrame implements PropertyChangeListener {
*/ */
private boolean saveAction() { private boolean saveAction() {
File file = document.getFile(); File file = document.getFile();
if (file == null) { if (file == null || document.getDefaultStorageOptions().getFileType().equals(FileType.ROCKSIM)) {
log.info("Document does not contain file, opening save as dialog instead"); log.info("Document does not contain file, opening save as dialog instead");
return saveAsAction(); return saveAsAction();
} }
log.info("Saving document to " + file); log.info("Saving document to " + file);
if (FileHelper.ROCKSIM_DESIGN_FILTER.accept(file)) { return saveAsOpenRocket(file);
return saveAsRocksim(file);
}
return saveAs(file);
} }
private static String oldFileName=null;
public void propertyChange(PropertyChangeEvent event){
if( JFileChooser.SELECTED_FILE_CHANGED_PROPERTY == event.getPropertyName()){
if(null != event.getOldValue()){
BasicFrame.oldFileName = ((File)event.getOldValue()).getName();
}
return;
}else if(JFileChooser.FILE_FILTER_CHANGED_PROPERTY == event.getPropertyName()){
JFileChooser chooser = (JFileChooser)event.getSource();
SimpleFileFilter filter = (SimpleFileFilter)(chooser.getFileFilter());
String desiredExtension = filter.getExtensions()[0];
if( null == BasicFrame.oldFileName){
return;
}
String thisFileName = BasicFrame.oldFileName;
if ( filter.accept( new File(thisFileName))){
// nop
return;
}else{
String[] splitResults = thisFileName.split("\\.");
if(0 < splitResults.length){
thisFileName = splitResults[0];
}
chooser.setSelectedFile(new File( thisFileName+desiredExtension));
return;
}
}
}
/** /**
* "Save As" action. * "Export" action.
*
* Never should a .rkt file contain an OpenRocket content, or an .ork file contain a Rocksim design. Regardless of
* what extension the user has chosen, it would violate the Principle of Least Astonishment to do otherwise
* (and we want to make doing the wrong thing really hard to do). So always force the appropriate extension.
*
* This can result in some odd looking filenames (MyDesign.rkt.ork, MyDesign.rkt.ork.rkt, etc.) if the user is
* not paying attention, but the user can control that by modifying the filename in the dialog.
* *
* @return true if the file was saved, false otherwise * @return true if the file was saved, false otherwise
*/ */
private boolean saveAsAction() { private boolean exportAction() {
File file = null; File file = null;
StorageOptionChooser storageChooser = final SaveAsFileChooser chooser = SaveAsFileChooser.build(document, FileType.ROCKSIM);
new StorageOptionChooser(document, document.getDefaultStorageOptions());
final JFileChooser chooser = new JFileChooser();
chooser.setAcceptAllFileFilterUsed(false);
chooser.addChoosableFileFilter(FileHelper.OPENROCKET_DESIGN_FILTER);
chooser.addChoosableFileFilter(FileHelper.ROCKSIM_DESIGN_FILTER);
chooser.addPropertyChangeListener(JFileChooser.FILE_FILTER_CHANGED_PROPERTY, this);
chooser.addPropertyChangeListener(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY, this);
chooser.addPropertyChangeListener(JFileChooser.SELECTED_FILES_CHANGED_PROPERTY, this);
//Force the file filter to match the file extension that was opened. Will default to OR if the file is null.
if (FileHelper.ROCKSIM_DESIGN_FILTER.accept(document.getFile())) {
chooser.setFileFilter(FileHelper.ROCKSIM_DESIGN_FILTER);
}
else {
chooser.setFileFilter(FileHelper.OPENROCKET_DESIGN_FILTER);
}
chooser.setCurrentDirectory(((SwingPreferences) Application.getPreferences()).getDefaultDirectory());
chooser.setAccessory(storageChooser);
if (document.getFile() != null) {
chooser.setSelectedFile(document.getFile());
}
int option = chooser.showSaveDialog(BasicFrame.this); int option = chooser.showSaveDialog(BasicFrame.this);
if (option != JFileChooser.APPROVE_OPTION) { if (option != JFileChooser.APPROVE_OPTION) {
log.info(Markers.USER_MARKER, "User decided not to save, option=" + option); log.info(Markers.USER_MARKER, "User decided not to save, option=" + option);
return false; return false;
@ -1359,20 +1353,12 @@ public class BasicFrame extends JFrame implements PropertyChangeListener {
} }
((SwingPreferences) Application.getPreferences()).setDefaultDirectory(chooser.getCurrentDirectory()); ((SwingPreferences) Application.getPreferences()).setDefaultDirectory(chooser.getCurrentDirectory());
storageChooser.storeOptions(document.getDefaultStorageOptions());
if (chooser.getFileFilter().equals(FileHelper.ROCKSIM_DESIGN_FILTER)) { file = FileHelper.forceExtension(file, "ork");
if (FileHelper.confirmWrite(file, this) ) {
return saveAsRocksim(file); return saveAsRocksim(file);
} }
else { return false;
file = FileHelper.forceExtension(file, "ork");
boolean result = FileHelper.confirmWrite(file, this) && saveAs(file);
if (result) {
MRUDesignFile opts = MRUDesignFile.getInstance();
opts.addFile(file.getAbsolutePath());
}
return result;
}
} }
/** /**
@ -1383,7 +1369,31 @@ public class BasicFrame extends JFrame implements PropertyChangeListener {
* @return true if the file was written * @return true if the file was written
*/ */
private boolean saveAsRocksim(File file) { private boolean saveAsRocksim(File file) {
file = FileHelper.forceExtension(file, "rkt"); if ( prefs.getShowRockSimFormatWarning() ) {
// Show Rocksim format warning
JPanel panel = new JPanel(new MigLayout());
panel.add(new StyledLabel(trans.get("SaveRktWarningDialog.txt1")), "wrap");
final JCheckBox check = new JCheckBox(trans.get("SaveRktWarningDialog.donotshow"));
check.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
prefs.setShowRockSimFormatWarning(!check.isSelected());
}
});
panel.add(check);
int sel = JOptionPane.showOptionDialog(null,
panel,
"", // title
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.WARNING_MESSAGE,
null, // icon
null, // options
null // default option
);
if ( sel == 1 ) {
return false;
}
}
if (!FileHelper.confirmWrite(file, this)) { if (!FileHelper.confirmWrite(file, this)) {
return false; return false;
} }
@ -1399,6 +1409,41 @@ public class BasicFrame extends JFrame implements PropertyChangeListener {
} }
} }
/**
* "Save As" action.
*
* @return true if the file was saved, false otherwise
*/
private boolean saveAsAction() {
File file = null;
final SaveAsFileChooser chooser = SaveAsFileChooser.build(document, FileType.OPENROCKET);
int option = chooser.showSaveDialog(BasicFrame.this);
if (option != JFileChooser.APPROVE_OPTION) {
log.info(Markers.USER_MARKER, "User decided not to save, option=" + option);
return false;
}
file = chooser.getSelectedFile();
if (file == null) {
log.info(Markers.USER_MARKER, "User did not select a file");
return false;
}
((SwingPreferences) Application.getPreferences()).setDefaultDirectory(chooser.getCurrentDirectory());
chooser.storeOptions(document.getDefaultStorageOptions());
file = FileHelper.forceExtension(file, "ork");
boolean result = FileHelper.confirmWrite(file, this) && saveAsOpenRocket(file);
if (result) {
MRUDesignFile opts = MRUDesignFile.getInstance();
opts.addFile(file.getAbsolutePath());
}
return result;
}
/** /**
* Perform the writing of the design to the given file in OpenRocket format. * Perform the writing of the design to the given file in OpenRocket format.
* *
@ -1406,9 +1451,9 @@ public class BasicFrame extends JFrame implements PropertyChangeListener {
* *
* @return true if the file was written * @return true if the file was written
*/ */
private boolean saveAs(File file) { private boolean saveAsOpenRocket(File file) {
file = FileHelper.forceExtension(file, "ork");
log.info("Saving document as " + file); log.info("Saving document as " + file);
boolean saved = false;
if (!StorageOptionChooser.verifyStorageOptions(document, this)) { if (!StorageOptionChooser.verifyStorageOptions(document, this)) {
// User cancelled the dialog // User cancelled the dialog
@ -1416,7 +1461,7 @@ public class BasicFrame extends JFrame implements PropertyChangeListener {
return false; return false;
} }
document.getDefaultStorageOptions().setFileType(FileType.OPENROCKET);
SaveFileWorker worker = new SaveFileWorker(document, file, ROCKET_SAVER); SaveFileWorker worker = new SaveFileWorker(document, file, ROCKET_SAVER);
if (!SwingWorkerDialog.runWorker(this, "Saving file", if (!SwingWorkerDialog.runWorker(this, "Saving file",
@ -1432,8 +1477,8 @@ public class BasicFrame extends JFrame implements PropertyChangeListener {
worker.get(); worker.get();
document.setFile(file); document.setFile(file);
document.setSaved(true); document.setSaved(true);
saved = true;
setTitle(); setTitle();
return true;
} catch (ExecutionException e) { } catch (ExecutionException e) {
Throwable cause = e.getCause(); Throwable cause = e.getCause();
@ -1452,7 +1497,7 @@ public class BasicFrame extends JFrame implements PropertyChangeListener {
throw new BugException("EDT was interrupted", e); throw new BugException("EDT was interrupted", e);
} }
return saved; return false;
} }
@ -1504,10 +1549,7 @@ public class BasicFrame extends JFrame implements PropertyChangeListener {
public void printAction() { public void printAction() {
Double rotation = rocketpanel.getFigure().getRotation(); double rotation = rocketpanel.getFigure().getRotation();
if (rotation == null) {
rotation = 0d;
}
new PrintDialog(this, document, rotation).setVisible(true); new PrintDialog(this, document, rotation).setVisible(true);
} }
@ -1618,3 +1660,4 @@ class BasicFrame_changeAdapter implements javax.swing.event.ChangeListener {
adaptee.stateChanged(e); adaptee.stateChanged(e);
} }
} }

View File

@ -1,4 +1,4 @@
package net.sf.openrocket.gui; package net.sf.openrocket.gui.main;
import java.awt.Window; import java.awt.Window;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;

View File

@ -0,0 +1,113 @@
package net.sf.openrocket.gui.main;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import javax.swing.JFileChooser;
import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.document.StorageOptions;
import net.sf.openrocket.document.StorageOptions.FileType;
import net.sf.openrocket.gui.util.FileHelper;
import net.sf.openrocket.gui.util.SimpleFileFilter;
import net.sf.openrocket.gui.util.SwingPreferences;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.startup.Application;
public class SaveAsFileChooser extends JFileChooser {
private final FileType type;
private final OpenRocketDocument document;
private final StorageOptionChooser storageChooser;
private static final Translator trans = Application.getTranslator();
public static SaveAsFileChooser build( OpenRocketDocument document, FileType type ) {
return new SaveAsFileChooser(document,type);
}
private SaveAsFileChooser( OpenRocketDocument document, FileType type ) {
this.document = document;
this.type = type;
this.setAcceptAllFileFilterUsed(true);
File defaultFilename = document.getFile();
switch( type ) {
default:
case OPENROCKET:
defaultFilename = FileHelper.forceExtension(defaultFilename,"ork");
this.setDialogTitle(trans.get("saveAs.openrocket.title"));
storageChooser = new StorageOptionChooser(document, document.getDefaultStorageOptions());
this.setAccessory(storageChooser);
this.addChoosableFileFilter(FileHelper.OPENROCKET_DESIGN_FILTER);
this.setFileFilter(FileHelper.OPENROCKET_DESIGN_FILTER);
break;
case ROCKSIM:
defaultFilename = FileHelper.forceExtension(defaultFilename,"rkt");
this.setDialogTitle(trans.get("saveAs.rocksim.title"));
storageChooser = null;
this.addChoosableFileFilter(FileHelper.ROCKSIM_DESIGN_FILTER);
this.setFileFilter(FileHelper.ROCKSIM_DESIGN_FILTER);
break;
}
final RememberFilenamePropertyListener listner = new RememberFilenamePropertyListener();
this.addPropertyChangeListener(JFileChooser.FILE_FILTER_CHANGED_PROPERTY, listner);
this.addPropertyChangeListener(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY, listner);
this.addPropertyChangeListener(JFileChooser.SELECTED_FILES_CHANGED_PROPERTY, listner);
this.setCurrentDirectory(((SwingPreferences) Application.getPreferences()).getDefaultDirectory());
if (defaultFilename != null) {
this.setSelectedFile(defaultFilename);
}
}
public void storeOptions(StorageOptions opts) {
if ( storageChooser != null ) {
storageChooser.storeOptions(opts);
}
}
}
class RememberFilenamePropertyListener implements PropertyChangeListener {
private String oldFileName=null;
@Override
public void propertyChange(PropertyChangeEvent event){
if( JFileChooser.SELECTED_FILE_CHANGED_PROPERTY == event.getPropertyName()){
if(null != event.getOldValue()){
this.oldFileName = ((File)event.getOldValue()).getName();
}
return;
}else if(JFileChooser.FILE_FILTER_CHANGED_PROPERTY == event.getPropertyName()){
JFileChooser chooser = (JFileChooser)event.getSource();
SimpleFileFilter filter = (SimpleFileFilter)(chooser.getFileFilter());
String desiredExtension = filter.getExtensions()[0];
if( null == this.oldFileName){
return;
}
String thisFileName = this.oldFileName;
if ( filter.accept( new File(thisFileName))){
// nop
return;
}else{
String[] splitResults = thisFileName.split("\\.");
if(0 < splitResults.length){
thisFileName = splitResults[0];
}
chooser.setSelectedFile(new File( thisFileName+desiredExtension));
return;
}
}
}
}

View File

@ -1,4 +1,4 @@
package net.sf.openrocket.gui; package net.sf.openrocket.gui.main;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;

View File

@ -117,7 +117,9 @@ public final class FileHelper {
* @return the resulting file * @return the resulting file
*/ */
public static File forceExtension(File original, String extension) { public static File forceExtension(File original, String extension) {
if ( original == null ) {
return null;
}
if (!original.getName().toLowerCase(Locale.ENGLISH).endsWith(extension.toLowerCase(Locale.ENGLISH))) { if (!original.getName().toLowerCase(Locale.ENGLISH).endsWith(extension.toLowerCase(Locale.ENGLISH))) {
log.debug("File name does not contain extension, adding '" + extension + "'"); log.debug("File name does not contain extension, adding '" + extension + "'");
String name = original.getAbsolutePath(); String name = original.getAbsolutePath();