diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties
index d2ea4caed..f9abe5920 100644
--- a/core/resources/l10n/messages.properties
+++ b/core/resources/l10n/messages.properties
@@ -95,7 +95,10 @@ BasicFrame.WarningDialog.title = Warnings while opening file
BasicFrame.WarningDialog.saving.title = Warnings while opening file
BasicFrame.ErrorWarningDialog.txt1 = Please correct the errors.
BasicFrame.ErrorWarningDialog.saving.title = Errors/Warnings while saving file
+BasicFrame.lbl.SaveRocketInfo = Save Design Info
+! SaveDesignInfoPanel
+SaveDesignInfoPanel.lbl.FillInInfo = (Optional) Fill in the design information for this file
! General error messages used in multiple contexts
error.fileExists.title = File exists
diff --git a/core/src/net/sf/openrocket/startup/Preferences.java b/core/src/net/sf/openrocket/startup/Preferences.java
index 382bfc438..02d272f03 100644
--- a/core/src/net/sf/openrocket/startup/Preferences.java
+++ b/core/src/net/sf/openrocket/startup/Preferences.java
@@ -82,6 +82,7 @@ public abstract class Preferences implements ChangeSource {
private static final String AUTO_OPEN_LAST_DESIGN = "AutoOpenLastDesign";
private static final String OPEN_LEFTMOST_DESIGN_TAB = "OpenLeftmostDesignTab";
private static final String SHOW_DISCARD_CONFIRMATION = "IgnoreDiscardEditingWarning";
+ private static final String SHOW_SAVE_ROCKET_INFO = "ShowSaveRocketInfo";
private static final String SHOW_DISCARD_SIMULATION_CONFIRMATION = "IgnoreDiscardSimulationEditingWarning";
private static final String SHOW_DISCARD_PREFERENCES_CONFIRMATION = "IgnoreDiscardPreferencesWarning";
public static final String MARKER_STYLE_ICON = "MarkerStyleIcon";
@@ -592,6 +593,21 @@ public abstract class Preferences implements ChangeSource {
this.putBoolean(SHOW_DISCARD_CONFIRMATION, enabled);
}
+ /**
+ * Returns whether a 'save rocket information' dialog should be shown after saving a new design file.
+ * @return true if the 'save rocket information' dialog should be shown.
+ */
+ public final boolean isShowSaveRocketInfo() {
+ return this.getBoolean(SHOW_SAVE_ROCKET_INFO, true);
+ }
+
+ /**
+ * Enable/Disable showing a 'save rocket information' dialog after saving a new design file.
+ * @return true if the 'save rocket information' dialog should be shown.
+ */
+ public final void setShowSaveRocketInfo(boolean enabled) {
+ this.putBoolean(SHOW_SAVE_ROCKET_INFO, enabled);
+ }
/**
* Answer if a confirmation dialog should be shown when canceling a simulation config operation.
*
diff --git a/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java
index 045e88be7..fb9dc9a95 100644
--- a/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java
+++ b/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java
@@ -39,7 +39,6 @@ import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.gui.SpinnerEditor;
import net.sf.openrocket.gui.adaptors.BooleanModel;
import net.sf.openrocket.gui.adaptors.DoubleModel;
-import net.sf.openrocket.gui.adaptors.IntegerModel;
import net.sf.openrocket.gui.adaptors.PresetModel;
import net.sf.openrocket.gui.adaptors.TextComponentSelectionKeyListener;
import net.sf.openrocket.gui.components.BasicSlider;
@@ -70,7 +69,7 @@ public class RocketComponentConfig extends JPanel {
protected final OpenRocketDocument document;
protected final RocketComponent component;
protected final JTabbedPane tabbedPane;
- protected final ComponentConfigDialog parent;
+ protected final JDialog parent;
protected boolean isNewComponent = false; // Checks whether this config dialog is editing an existing component, or a new one
private final List invalidatables = new ArrayList();
@@ -87,7 +86,7 @@ public class RocketComponentConfig extends JPanel {
private DescriptionArea componentInfo;
private IconToggleButton infoBtn;
- private JPanel buttonPanel;
+ protected JPanel buttonPanel;
protected JButton okButton;
protected JButton cancelButton;
private AppearancePanel appearancePanel = null;
@@ -103,11 +102,7 @@ public class RocketComponentConfig extends JPanel {
this.document = document;
this.component = component;
- if (parent instanceof ComponentConfigDialog) {
- this.parent = (ComponentConfigDialog) parent;
- } else {
- this.parent = null;
- }
+ this.parent = parent;
// Check the listeners for the same type and massive status
allSameType = true;
@@ -195,7 +190,7 @@ public class RocketComponentConfig extends JPanel {
/**
* Add a section to the component configuration dialog that displays information about the component.
*/
- private void addComponentInfo(JPanel buttonPanel) {
+ protected void addComponentInfo(JPanel buttonPanel) {
// Don't add the info panel if this is a multi-comp edit
List listeners = component.getConfigListeners();
if (listeners != null && listeners.size() > 0) {
@@ -274,14 +269,14 @@ public class RocketComponentConfig extends JPanel {
@Override
public void actionPerformed(ActionEvent arg0) {
// Don't do anything on cancel if you are editing an existing component, and it is not modified
- if (!isNewComponent && parent != null && !parent.isModified()) {
- ComponentConfigDialog.disposeDialog();
+ if (!isNewComponent && parent != null && (parent instanceof ComponentConfigDialog && !((ComponentConfigDialog) parent).isModified())) {
+ disposeDialog();
return;
}
// Apply the cancel operation if set to auto discard in preferences
if (!preferences.isShowDiscardConfirmation()) {
ComponentConfigDialog.clearConfigListeners = false; // Undo action => config listeners of new component will be cleared
- ComponentConfigDialog.disposeDialog();
+ disposeDialog();
document.undo();
return;
}
@@ -292,7 +287,7 @@ public class RocketComponentConfig extends JPanel {
trans.get("RocketCompCfg.CancelOperation.title"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
if (resultYesNo == JOptionPane.YES_OPTION) {
ComponentConfigDialog.clearConfigListeners = false; // Undo action => config listeners of new component will be cleared
- ComponentConfigDialog.disposeDialog();
+ disposeDialog();
document.undo();
}
}
@@ -305,7 +300,7 @@ public class RocketComponentConfig extends JPanel {
okButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
- ComponentConfigDialog.disposeDialog();
+ disposeDialog();
}
});
buttonPanel.add(okButton);
@@ -315,7 +310,17 @@ public class RocketComponentConfig extends JPanel {
this.add(buttonPanel, "newline, spanx, growx");
}
- private JPanel createCancelOperationContent() {
+ protected void disposeDialog() {
+ if (parent != null) {
+ if (parent instanceof ComponentConfigDialog) {
+ ComponentConfigDialog.disposeDialog();
+ } else {
+ parent.dispose();
+ }
+ }
+ }
+
+ protected JPanel createCancelOperationContent() {
JPanel panel = new JPanel(new MigLayout());
String msg = isNewComponent ? trans.get("RocketCompCfg.CancelOperation.msg.undoAdd") :
trans.get("RocketCompCfg.CancelOperation.msg.discardChanges");
diff --git a/swing/src/net/sf/openrocket/gui/configdialog/SaveDesignInfoPanel.java b/swing/src/net/sf/openrocket/gui/configdialog/SaveDesignInfoPanel.java
new file mode 100644
index 000000000..ec53c60bf
--- /dev/null
+++ b/swing/src/net/sf/openrocket/gui/configdialog/SaveDesignInfoPanel.java
@@ -0,0 +1,104 @@
+package net.sf.openrocket.gui.configdialog;
+
+import net.miginfocom.swing.MigLayout;
+import net.sf.openrocket.document.OpenRocketDocument;
+import net.sf.openrocket.gui.components.StyledLabel;
+import net.sf.openrocket.gui.widgets.SelectColorButton;
+import net.sf.openrocket.l10n.Translator;
+import net.sf.openrocket.rocketcomponent.RocketComponent;
+import net.sf.openrocket.startup.Application;
+import net.sf.openrocket.startup.Preferences;
+
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JDialog;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+/**
+ * This class is used to create a panel that is shown when a new design file is saved. It is used to fill in the design
+ * information for the file.
+ */
+public class SaveDesignInfoPanel extends RocketConfig {
+ private static final Translator trans = Application.getTranslator();
+ private static final Preferences preferences = Application.getPreferences();
+
+ public SaveDesignInfoPanel(OpenRocketDocument d, RocketComponent c, JDialog parent) {
+ super(d, c, parent);
+
+ // (Optional) Fill in the design information for this file
+ StyledLabel label = new StyledLabel(trans.get("SaveDesignInfoPanel.lbl.FillInInfo"), StyledLabel.Style.BOLD);
+ this.add(label, "spanx, wrap para", 0);
+ }
+
+ @Override
+ protected void addButtons(JButton... buttons) {
+ if (buttonPanel != null) {
+ this.remove(buttonPanel);
+ }
+
+ buttonPanel = new JPanel(new MigLayout("fill, ins 5, hidemode 3"));
+
+ //// Don't show this dialog again
+ JCheckBox dontShowAgain = new JCheckBox(trans.get("welcome.dlg.checkbox.dontShowAgain"));
+ dontShowAgain.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ preferences.setShowSaveRocketInfo(!((JCheckBox) e.getSource()).isSelected());
+ }
+ });
+ buttonPanel.add(dontShowAgain, "gapright 10, growx");
+
+ //// Cancel button
+ this.cancelButton = new SelectColorButton(trans.get("dlg.but.cancel"));
+ this.cancelButton.setToolTipText(trans.get("RocketCompCfg.btn.Cancel.ttip"));
+ cancelButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ // Don't do anything on cancel if you are editing an existing component, and it is not modified
+ if (!isNewComponent && parent != null && (parent instanceof ComponentConfigDialog && !((ComponentConfigDialog) parent).isModified())) {
+ disposeDialog();
+ return;
+ }
+ // Apply the cancel operation if set to auto discard in preferences
+ if (!preferences.isShowDiscardConfirmation()) {
+ ComponentConfigDialog.clearConfigListeners = false; // Undo action => config listeners of new component will be cleared
+ disposeDialog();
+ document.undo();
+ return;
+ }
+
+ // Yes/No dialog: Are you sure you want to discard your changes?
+ JPanel msg = createCancelOperationContent();
+ int resultYesNo = JOptionPane.showConfirmDialog(SaveDesignInfoPanel.this, msg,
+ trans.get("RocketCompCfg.CancelOperation.title"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
+ if (resultYesNo == JOptionPane.YES_OPTION) {
+ ComponentConfigDialog.clearConfigListeners = false; // Undo action => config listeners of new component will be cleared
+ disposeDialog();
+ document.undo();
+ }
+ }
+ });
+ buttonPanel.add(cancelButton, "split 2, right, gapleft 30lp");
+
+ //// Ok button
+ this.okButton = new SelectColorButton(trans.get("dlg.but.ok"));
+ this.okButton.setToolTipText(trans.get("RocketCompCfg.btn.OK.ttip"));
+ okButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ disposeDialog();
+ }
+ });
+ buttonPanel.add(okButton);
+
+ this.add(buttonPanel, "newline, spanx, growx");
+ }
+
+ @Override
+ public void updateFields() {
+ // Do nothing
+ }
+}
diff --git a/swing/src/net/sf/openrocket/gui/main/BasicFrame.java b/swing/src/net/sf/openrocket/gui/main/BasicFrame.java
index d114b64f8..06e449c80 100644
--- a/swing/src/net/sf/openrocket/gui/main/BasicFrame.java
+++ b/swing/src/net/sf/openrocket/gui/main/BasicFrame.java
@@ -49,6 +49,7 @@ import javax.swing.tree.DefaultTreeSelectionModel;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import net.miginfocom.swing.MigLayout;
+import net.sf.openrocket.gui.configdialog.SaveDesignInfoPanel;
import net.sf.openrocket.gui.dialogs.ErrorWarningDialog;
import net.sf.openrocket.logging.ErrorSet;
import net.sf.openrocket.logging.WarningSet;
@@ -1596,6 +1597,9 @@ public class BasicFrame extends JFrame {
* @return true if the file was saved, false otherwise
*/
private boolean saveAsAction() {
+ // Open dialog for saving rocket info
+ showSaveRocketInfoDialog();
+
File file = openFileSaveAsDialog(FileType.OPENROCKET);
if (file == null) {
return false;
@@ -1610,6 +1614,25 @@ public class BasicFrame extends JFrame {
return result;
}
+ private void showSaveRocketInfoDialog() {
+ if (!prefs.isShowSaveRocketInfo()) {
+ return;
+ }
+
+ // Select the rocket in the component tree to indicate to users that they can edit the rocket info by editing the rocket
+ setSelectedComponent(rocket);
+
+ // Open the save rocket info
+ JDialog dialog = new JDialog();
+ SaveDesignInfoPanel panel = new SaveDesignInfoPanel(document, rocket, dialog);
+ dialog.setContentPane(panel);
+ dialog.pack();
+ dialog.setTitle(trans.get("BasicFrame.lbl.SaveRocketInfo"));
+ dialog.setModal(true);
+ dialog.setLocationRelativeTo(null);
+ dialog.setVisible(true);
+ }
+
/**
* Perform the writing of the design to the given file in OpenRocket format.