From 3e2aec6e3e25106fed8f3d78445bf2c4639e923a Mon Sep 17 00:00:00 2001 From: SiboVG Date: Fri, 31 Mar 2023 18:01:25 +0200 Subject: [PATCH 01/15] WIP --- core/resources/l10n/messages.properties | 13 +++- core/resources/l10n/messages_ar.properties | 4 +- core/resources/l10n/messages_nl.properties | 4 +- .../preferences/GeneralPreferencesPanel.java | 47 ++++++++++++-- .../preferences/PreferencesDialog.java | 8 +++ .../sf/openrocket/gui/util/FileHelper.java | 4 ++ .../gui/util/PreferencesExporter.java | 61 +++++++++++++++++++ .../gui/util/PreferencesImporter.java | 48 +++++++++++++++ .../openrocket/gui/util/SwingPreferences.java | 4 ++ 9 files changed, 181 insertions(+), 12 deletions(-) create mode 100644 swing/src/net/sf/openrocket/gui/util/PreferencesExporter.java create mode 100644 swing/src/net/sf/openrocket/gui/util/PreferencesImporter.java diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index 88290ee6d..aa902f8f4 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -122,6 +122,7 @@ FileHelper.RASAERO_DESIGN_FILTER = RASAero designs (*.CDX1) FileHelper.OPEN_ROCKET_COMPONENT_FILTER = OpenRocket presets (*.orc) FileHelper.PNG_FILTER = PNG image (*.png) FileHelper.IMAGES = Image files +FileHelper.XML_FILTER = XML files (*.xml) ! About Dialog @@ -290,8 +291,12 @@ pref.dlg.tab.Simulation = Simulation pref.dlg.tab.Launch = Launch pref.dlg.tab.Miscellaneousoptions = Miscellaneous options pref.dlg.lbl.RockSimWarning = Show warning when saving in RockSim format -pref.dlg.but.clearCachedPreferences = Reset all preferences -pref.dlg.but.clearCachedPreferences.ttip = Reset all the preferences, including cached preferences (UI settings, recent files, etc.) +pref.dlg.but.resetAllPreferences = Reset all preferences +pref.dlg.but.resetAllPreferences.ttip = Reset all the preferences, including cached preferences (UI settings, recent files, etc.) +pref.dlg.but.exportPreferences = Export preferences +pref.dlg.but.exportPreferences.ttip = Export all your OpenRocket preferences to an external file +pref.dlg.but.importPreferences = Import preferences +pref.dlg.but.importPreferences.ttip = Import new OpenRocket preferences from an external file pref.dlg.clearCachedPreferences.title = Reset preferences? pref.dlg.clearCachedPreferences.message = Are you sure you want to reset all your preferences? @@ -372,6 +377,10 @@ generalprefs.lbl.language = Interface language generalprefs.languages.default = System default generalprefs.lbl.languageEffect = The language will change the next time you start OpenRocket. +PreferencesExporter.chooser.title = Export the Preferences File + +PreferencesImporter.chooser.title = Import a Preferences File + ! Welcome dialog welcome.dlg.title = Welcome to OpenRocket welcome.dlg.lbl.thankYou = Thank you for downloading OpenRocket diff --git a/core/resources/l10n/messages_ar.properties b/core/resources/l10n/messages_ar.properties index 5db732751..96b45e6ab 100644 --- a/core/resources/l10n/messages_ar.properties +++ b/core/resources/l10n/messages_ar.properties @@ -276,8 +276,8 @@ pref.dlg.tab.Simulation = محاكاة pref.dlg.tab.Launch = إطلاق pref.dlg.tab.Miscellaneousoptions = الخيارات المتنوعة pref.dlg.lbl.RockSimWarning = إظهار تحذير عند الحفظ بتنسيق روكسيم -pref.dlg.but.clearCachedPreferences = إعادة تعيين كل التفضيلات -pref.dlg.but.clearCachedPreferences.ttip = (إعدادات واجهة المستخدم والملفات الحديثة وما إلى ذلك)إعادة تعيين جميع التفضيلات ، بما في ذلك التفضيلات المخزنة مؤقتًا +pref.dlg.but.resetAllPreferences = إعادة تعيين كل التفضيلات +pref.dlg.but.resetAllPreferences.ttip = (إعدادات واجهة المستخدم والملفات الحديثة وما إلى ذلك)إعادة تعيين جميع التفضيلات ، بما في ذلك التفضيلات المخزنة مؤقتًا pref.dlg.clearCachedPreferences.title = هل تريد إعادة تعيين التفضيلات؟ pref.dlg.clearCachedPreferences.message = هل أنت متأكد أنك تريد إعادة تعيين كل تفضيلاتك؟ diff --git a/core/resources/l10n/messages_nl.properties b/core/resources/l10n/messages_nl.properties index a2de9a92c..cf6f94ddd 100644 --- a/core/resources/l10n/messages_nl.properties +++ b/core/resources/l10n/messages_nl.properties @@ -277,8 +277,8 @@ pref.dlg.tab.Simulation = Simulatie pref.dlg.tab.Launch = Lanceer pref.dlg.tab.Miscellaneousoptions = Diverse opties pref.dlg.lbl.RockSimWarning = Toon waarschuwingen bij opslaan in RockSim-formaat -pref.dlg.but.clearCachedPreferences = Alle voorkeuren opnieuw instellen -pref.dlg.but.clearCachedPreferences.ttip = Alle voorkeuren opnieuw instellen, inclusief voorkeuren in de cache (UI-instellingen, recente bestanden, enz.) +pref.dlg.but.resetAllPreferences = Alle voorkeuren opnieuw instellen +pref.dlg.but.resetAllPreferences.ttip = Alle voorkeuren opnieuw instellen, inclusief voorkeuren in de cache (UI-instellingen, recente bestanden, enz.) pref.dlg.clearCachedPreferences.title = Voorkeuren opnieuw instellen? pref.dlg.clearCachedPreferences.message = Bent u zeker dat u al uw voorkeuren opnieuw wilt instellen? diff --git a/swing/src/net/sf/openrocket/gui/dialogs/preferences/GeneralPreferencesPanel.java b/swing/src/net/sf/openrocket/gui/dialogs/preferences/GeneralPreferencesPanel.java index de73270f9..cd2be571d 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/preferences/GeneralPreferencesPanel.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/preferences/GeneralPreferencesPanel.java @@ -19,6 +19,7 @@ import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.JTextField; +import javax.swing.SwingUtilities; import javax.swing.Timer; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; @@ -35,6 +36,8 @@ import net.sf.openrocket.gui.dialogs.UpdateInfoDialog; import net.sf.openrocket.gui.util.GUIUtil; import net.sf.openrocket.gui.util.SimpleFileFilter; import net.sf.openrocket.gui.util.SwingPreferences; +import net.sf.openrocket.gui.util.PreferencesExporter; +import net.sf.openrocket.gui.util.PreferencesImporter; import net.sf.openrocket.l10n.L10N; import net.sf.openrocket.logging.Markers; import net.sf.openrocket.startup.Preferences; @@ -46,7 +49,7 @@ import net.sf.openrocket.gui.widgets.SelectColorButton; @SuppressWarnings("serial") public class GeneralPreferencesPanel extends PreferencesPanel { - public GeneralPreferencesPanel(JDialog parent) { + public GeneralPreferencesPanel(PreferencesDialog parent) { super(parent, new MigLayout("fillx, ins 30lp n n n")); @@ -240,10 +243,41 @@ public class GeneralPreferencesPanel extends PreferencesPanel { }); this.add(rocksimWarningDialogBox,"spanx, wrap"); - //// Clear cached preferences - final JButton clearCachedPreferences = new SelectColorButton(trans.get("pref.dlg.but.clearCachedPreferences")); - clearCachedPreferences.setToolTipText(trans.get("pref.dlg.but.clearCachedPreferences.ttip")); - clearCachedPreferences.addActionListener(new ActionListener() { + // Preference buttons + JPanel buttonPanel = new JPanel(new MigLayout("fillx, ins 0")); + + //// Export preferences + final JButton exportPreferences = new SelectColorButton(trans.get("pref.dlg.but.exportPreferences")); + exportPreferences.setToolTipText(trans.get("pref.dlg.but.exportPreferences.ttip")); + exportPreferences.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + PreferencesExporter.exportPreferences(parent, preferences.getPreferences()); + } + }); + buttonPanel.add(exportPreferences); + + //// Import preferences + final JButton importPreferences = new SelectColorButton(trans.get("pref.dlg.but.importPreferences")); + importPreferences.setToolTipText(trans.get("pref.dlg.but.importPreferences.ttip")); + importPreferences.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + PreferencesImporter.importPreferences(parent); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + PreferencesDialog.showPreferences(parent.getParentFrame()); // Refresh the preferences dialog + } + }); + } + }); + buttonPanel.add(importPreferences); + + //// Reset all preferences + final JButton resetAllPreferences = new SelectColorButton(trans.get("pref.dlg.but.resetAllPreferences")); + resetAllPreferences.setToolTipText(trans.get("pref.dlg.but.resetAllPreferences.ttip")); + resetAllPreferences.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { int resultYesNo = JOptionPane.showConfirmDialog(parent, trans.get("pref.dlg.clearCachedPreferences.message"), @@ -253,8 +287,9 @@ public class GeneralPreferencesPanel extends PreferencesPanel { } } }); - this.add(clearCachedPreferences, "spanx, pushy, bottom, wrap"); + buttonPanel.add(resetAllPreferences, "pushx, right, wrap"); + this.add(buttonPanel, "spanx, growx, pushy, bottom, wrap"); } diff --git a/swing/src/net/sf/openrocket/gui/dialogs/preferences/PreferencesDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/preferences/PreferencesDialog.java index 6a438e3d2..5b1065f9b 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/preferences/PreferencesDialog.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/preferences/PreferencesDialog.java @@ -33,11 +33,15 @@ public class PreferencesDialog extends JDialog { private final SwingPreferences preferences = (SwingPreferences) Application .getPreferences(); + private BasicFrame parentFrame; + private PreferencesDialog(BasicFrame parent) { // // Preferences super(parent, trans.get("pref.dlg.title.Preferences"), Dialog.ModalityType.APPLICATION_MODAL); + this.parentFrame = parent; + JPanel panel = new JPanel(new MigLayout("fill, gap unrel", "[grow]", "[grow][]")); @@ -104,6 +108,10 @@ public class PreferencesDialog extends JDialog { GUIUtil.setDisposableDialogOptions(this, close); } + public BasicFrame getParentFrame() { + return parentFrame; + } + // ////// Singleton implementation //////// private static PreferencesDialog dialog = null; diff --git a/swing/src/net/sf/openrocket/gui/util/FileHelper.java b/swing/src/net/sf/openrocket/gui/util/FileHelper.java index 9ea309450..c2bc914d6 100644 --- a/swing/src/net/sf/openrocket/gui/util/FileHelper.java +++ b/swing/src/net/sf/openrocket/gui/util/FileHelper.java @@ -64,6 +64,10 @@ public final class FileHelper { public static final FileFilter PNG_FILTER = new SimpleFileFilter(trans.get("FileHelper.PNG_FILTER"), ".png"); + /** File filter for XML files (*.xml) */ + public static final FileFilter XML_FILTER = + new SimpleFileFilter(trans.get("FileHelper.XML_FILTER"), ".xml"); + diff --git a/swing/src/net/sf/openrocket/gui/util/PreferencesExporter.java b/swing/src/net/sf/openrocket/gui/util/PreferencesExporter.java new file mode 100644 index 000000000..02564fafb --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/util/PreferencesExporter.java @@ -0,0 +1,61 @@ +package net.sf.openrocket.gui.util; + +import net.sf.openrocket.gui.widgets.SaveFileChooser; +import net.sf.openrocket.l10n.Translator; +import net.sf.openrocket.startup.Application; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.swing.JFileChooser; +import java.awt.Window; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.prefs.BackingStoreException; +import java.util.prefs.Preferences; + +public abstract class PreferencesExporter { + private static final Translator trans = Application.getTranslator(); + private static final Logger log = LoggerFactory.getLogger(PreferencesExporter.class); + + public static boolean exportPreferences(Window parent, Preferences preferences) { + JFileChooser chooser = new SaveFileChooser(); + chooser.setDialogTitle(trans.get("PreferencesExporter.chooser.title")); + chooser.setAcceptAllFileFilterUsed(false); + chooser.setFileFilter(FileHelper.XML_FILTER); + chooser.setCurrentDirectory(((SwingPreferences) Application.getPreferences()).getDefaultDirectory()); + + + // TODO: add storageoptions to choose whether to export user directories or not (default to not) + + + //// Ensures No Problems When Choosing File + if (chooser.showSaveDialog(parent) != JFileChooser.APPROVE_OPTION) { + log.info("Cancelled export of preferences."); + return false; + } + + ((SwingPreferences) Application.getPreferences()).setDefaultDirectory(chooser.getCurrentDirectory()); + + File file = chooser.getSelectedFile(); + if (file == null) { + log.info("No file selected to export preferences to."); + return false; + } + + file = FileHelper.forceExtension(file, "xml"); + if (!FileHelper.confirmWrite(file, parent)) { + log.info("Cancelled export of preferences."); + return false; + } + + try (FileOutputStream fos = new FileOutputStream(file)) { + preferences.exportSubtree(fos); + log.info("Preferences exported successfully."); + } catch (IOException | BackingStoreException e) { + log.warn("Error while importing preferences: " + e.getMessage()); + } + + return true; + } +} diff --git a/swing/src/net/sf/openrocket/gui/util/PreferencesImporter.java b/swing/src/net/sf/openrocket/gui/util/PreferencesImporter.java new file mode 100644 index 000000000..7b3aba43f --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/util/PreferencesImporter.java @@ -0,0 +1,48 @@ +package net.sf.openrocket.gui.util; + +import net.sf.openrocket.l10n.Translator; +import net.sf.openrocket.startup.Application; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.swing.JFileChooser; +import java.awt.Window; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.prefs.InvalidPreferencesFormatException; +import java.util.prefs.Preferences; + +public abstract class PreferencesImporter { + private static final Translator trans = Application.getTranslator(); + private static final Logger log = LoggerFactory.getLogger(PreferencesImporter.class); + + public static boolean importPreferences(Window parent) { + final JFileChooser chooser = new JFileChooser(); + chooser.setDialogTitle(trans.get("PreferencesImporter.chooser.title")); + chooser.setCurrentDirectory(((SwingPreferences) Application.getPreferences()).getDefaultDirectory()); + chooser.setFileFilter(FileHelper.XML_FILTER); + chooser.setAcceptAllFileFilterUsed(false); + + int returnVal = chooser.showOpenDialog(parent); + if (returnVal != JFileChooser.APPROVE_OPTION) { + log.info("Cancelled import of preferences."); + return false; + } + + ((SwingPreferences) Application.getPreferences()).setDefaultDirectory(chooser.getCurrentDirectory()); + + File importFile = chooser.getSelectedFile(); + try (FileInputStream fis = new FileInputStream(importFile)) { + + // TODO: don't import user directories? + + Preferences.importPreferences(fis); + log.info("Preferences imported successfully."); + } catch (IOException | InvalidPreferencesFormatException e) { + log.warn("Error while importing preferences: " + e.getMessage()); + } + + return true; + } +} diff --git a/swing/src/net/sf/openrocket/gui/util/SwingPreferences.java b/swing/src/net/sf/openrocket/gui/util/SwingPreferences.java index bf30f6c39..9ac18081f 100644 --- a/swing/src/net/sf/openrocket/gui/util/SwingPreferences.java +++ b/swing/src/net/sf/openrocket/gui/util/SwingPreferences.java @@ -92,6 +92,10 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences { ////////////////////// + + public Preferences getPreferences() { + return PREFNODE; + } public void clearPreferences() { try { From e11c2dbaa6b141d88bf163ede4f99fae791bc096 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Sat, 1 Apr 2023 20:40:58 +0200 Subject: [PATCH 02/15] Standardize preferences keys --- .../net/sf/openrocket/startup/Preferences.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/core/src/net/sf/openrocket/startup/Preferences.java b/core/src/net/sf/openrocket/startup/Preferences.java index eac3b3642..dd714c8bc 100644 --- a/core/src/net/sf/openrocket/startup/Preferences.java +++ b/core/src/net/sf/openrocket/startup/Preferences.java @@ -73,18 +73,18 @@ public abstract class Preferences implements ChangeSource { public static final String MATCH_AFT_DIAMETER = "MatchAftDiameter"; // Node names - 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 OPEN_LEFTMOST_DESIGN_TAB = "OPEN_LEFTMOST_DESIGN_TAB"; + public static final String PREFERRED_THRUST_CURVE_MOTOR_NODE = "PreferredThrustCurveMotors"; + 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"; - public static final String MARKER_STYLE_ICON = "MARKER_STYLE_ICON"; - private static final String SHOW_MARKERS = "SHOW_MARKERS"; - private static final String SHOW_ROCKSIM_FORMAT_WARNING = "SHOW_ROCKSIM_FORMAT_WARNING"; + public static final String MARKER_STYLE_ICON = "MarkerStyleIcon"; + private static final String SHOW_MARKERS = "ShowMarkers"; + private static final String SHOW_ROCKSIM_FORMAT_WARNING = "ShowRocksimFormatWarning"; //Preferences related to 3D graphics - public static final String OPENGL_ENABLED = "OpenGL_Is_Enabled"; - public static final String OPENGL_ENABLE_AA = "OpenGL_Antialiasing_Is_Enabled"; - public static final String OPENGL_USE_FBO = "OpenGL_Use_FBO"; + public static final String OPENGL_ENABLED = "OpenGLIsEnabled"; + public static final String OPENGL_ENABLE_AA = "OpenGLAntialiasingIsEnabled"; + public static final String OPENGL_USE_FBO = "OpenGLUseFBO"; public static final String ROCKET_INFO_FONT_SIZE = "RocketInfoFontSize"; From 7186aa6dd03670ea7678545ff83e7c49b272390d Mon Sep 17 00:00:00 2001 From: SiboVG Date: Sat, 1 Apr 2023 20:48:39 +0200 Subject: [PATCH 03/15] Ensure default directory is updated after file chooser update --- .../sf/openrocket/gui/configdialog/FreeformFinSetConfig.java | 2 ++ .../openrocket/gui/customexpression/CustomExpressionPanel.java | 2 ++ .../src/net/sf/openrocket/gui/dialogs/DecalNotFoundDialog.java | 1 + swing/src/net/sf/openrocket/gui/dialogs/EditDecalDialog.java | 3 +++ .../gui/dialogs/preferences/GeneralPreferencesPanel.java | 1 + .../gui/dialogs/preferences/GraphicsPreferencesPanel.java | 3 +++ swing/src/net/sf/openrocket/gui/main/ExportDecalDialog.java | 1 + swing/src/net/sf/openrocket/gui/preset/PresetEditorDialog.java | 3 +++ swing/src/net/sf/openrocket/utils/ComponentPresetEditor.java | 2 ++ 9 files changed, 18 insertions(+) diff --git a/swing/src/net/sf/openrocket/gui/configdialog/FreeformFinSetConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/FreeformFinSetConfig.java index 9f898774c..cce14deba 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/FreeformFinSetConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/FreeformFinSetConfig.java @@ -303,6 +303,7 @@ public class FreeformFinSetConfig extends FinSetConfig { } FreeformFinSetConfig.writeCSVFile(table, selectedFile); + ((SwingPreferences) Application.getPreferences()).setDefaultDirectory(chooser.getCurrentDirectory()); } } }); @@ -400,6 +401,7 @@ public class FreeformFinSetConfig extends FinSetConfig { trans.get("CustomFinImport.error.title"), JOptionPane.ERROR_MESSAGE); } finally { document.stopUndo(); + ((SwingPreferences) Application.getPreferences()).setDefaultDirectory(chooser.getCurrentDirectory()); } } } diff --git a/swing/src/net/sf/openrocket/gui/customexpression/CustomExpressionPanel.java b/swing/src/net/sf/openrocket/gui/customexpression/CustomExpressionPanel.java index 272044bc4..394daec86 100644 --- a/swing/src/net/sf/openrocket/gui/customexpression/CustomExpressionPanel.java +++ b/swing/src/net/sf/openrocket/gui/customexpression/CustomExpressionPanel.java @@ -18,6 +18,7 @@ import javax.swing.JScrollPane; import javax.swing.SwingUtilities; import javax.swing.filechooser.FileNameExtensionFilter; +import net.sf.openrocket.gui.util.SwingPreferences; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -110,6 +111,7 @@ public class CustomExpressionPanel extends JPanel { log.info(Markers.USER_MARKER, "Error opening document to import expressions from."); } updateExpressions(); + ((SwingPreferences) Application.getPreferences()).setDefaultDirectory(fc.getCurrentDirectory()); } } }); diff --git a/swing/src/net/sf/openrocket/gui/dialogs/DecalNotFoundDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/DecalNotFoundDialog.java index e14c05a15..e726e0015 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/DecalNotFoundDialog.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/DecalNotFoundDialog.java @@ -43,6 +43,7 @@ public abstract class DecalNotFoundDialog { if (resultFileChooser == JFileChooser.APPROVE_OPTION) { File file = chooser.getSelectedFile(); decex.getDecal().setDecalFile(file); + ((SwingPreferences) Application.getPreferences()).setDefaultDirectory(chooser.getCurrentDirectory()); } } return (resultYesNo == JOptionPane.YES_OPTION) && (resultFileChooser == JFileChooser.APPROVE_OPTION); diff --git a/swing/src/net/sf/openrocket/gui/dialogs/EditDecalDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/EditDecalDialog.java index 8ed3bf885..678e0edbc 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/EditDecalDialog.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/EditDecalDialog.java @@ -20,6 +20,7 @@ import javax.swing.event.ChangeListener; import net.miginfocom.swing.MigLayout; import net.sf.openrocket.gui.util.GUIUtil; +import net.sf.openrocket.gui.util.SwingPreferences; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.startup.Application; import net.sf.openrocket.gui.widgets.SelectColorButton; @@ -75,6 +76,7 @@ public class EditDecalDialog extends JDialog { int action = fc.showOpenDialog(owner); if (action == JFileChooser.APPROVE_OPTION) { commandText.setText(fc.getSelectedFile().getAbsolutePath()); + ((SwingPreferences) Application.getPreferences()).setDefaultDirectory(fc.getCurrentDirectory()); } } @@ -109,6 +111,7 @@ public class EditDecalDialog extends JDialog { int action = fc.showOpenDialog(owner); if (action == JFileChooser.APPROVE_OPTION) { commandText.setText(fc.getSelectedFile().getAbsolutePath()); + ((SwingPreferences) Application.getPreferences()).setDefaultDirectory(fc.getCurrentDirectory()); } } diff --git a/swing/src/net/sf/openrocket/gui/dialogs/preferences/GeneralPreferencesPanel.java b/swing/src/net/sf/openrocket/gui/dialogs/preferences/GeneralPreferencesPanel.java index cd2be571d..09e1ef7d1 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/preferences/GeneralPreferencesPanel.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/preferences/GeneralPreferencesPanel.java @@ -40,6 +40,7 @@ import net.sf.openrocket.gui.util.PreferencesExporter; import net.sf.openrocket.gui.util.PreferencesImporter; import net.sf.openrocket.l10n.L10N; import net.sf.openrocket.logging.Markers; +import net.sf.openrocket.startup.Application; import net.sf.openrocket.startup.Preferences; import net.sf.openrocket.util.BuildProperties; import net.sf.openrocket.util.Named; diff --git a/swing/src/net/sf/openrocket/gui/dialogs/preferences/GraphicsPreferencesPanel.java b/swing/src/net/sf/openrocket/gui/dialogs/preferences/GraphicsPreferencesPanel.java index b0b241b9b..3f16a27d3 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/preferences/GraphicsPreferencesPanel.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/preferences/GraphicsPreferencesPanel.java @@ -29,6 +29,8 @@ import net.sf.openrocket.gui.adaptors.BooleanModel; import net.sf.openrocket.gui.components.StyledLabel; import net.sf.openrocket.gui.components.StyledLabel.Style; import net.sf.openrocket.gui.util.GUIUtil; +import net.sf.openrocket.gui.util.SwingPreferences; +import net.sf.openrocket.startup.Application; import net.sf.openrocket.startup.Preferences; import net.sf.openrocket.gui.widgets.SelectColorButton; @@ -119,6 +121,7 @@ public class GraphicsPreferencesPanel extends PreferencesPanel { String commandLine = fc.getSelectedFile().getAbsolutePath(); commandText.setText(commandLine); preferences.setDecalEditorPreference(false, commandLine); + ((SwingPreferences) Application.getPreferences()).setDefaultDirectory(fc.getCurrentDirectory()); } } diff --git a/swing/src/net/sf/openrocket/gui/main/ExportDecalDialog.java b/swing/src/net/sf/openrocket/gui/main/ExportDecalDialog.java index 18e3c4ba1..932547cc5 100644 --- a/swing/src/net/sf/openrocket/gui/main/ExportDecalDialog.java +++ b/swing/src/net/sf/openrocket/gui/main/ExportDecalDialog.java @@ -90,6 +90,7 @@ public class ExportDecalDialog extends JDialog { export(selectedDecal, selectedFile); // If the user doesn't confirm over write, then leave this dialog open. ExportDecalDialog.this.dispose(); + ((SwingPreferences) Application.getPreferences()).setDefaultDirectory(chooser.getCurrentDirectory()); } } } diff --git a/swing/src/net/sf/openrocket/gui/preset/PresetEditorDialog.java b/swing/src/net/sf/openrocket/gui/preset/PresetEditorDialog.java index 3818ebe17..b10331a21 100644 --- a/swing/src/net/sf/openrocket/gui/preset/PresetEditorDialog.java +++ b/swing/src/net/sf/openrocket/gui/preset/PresetEditorDialog.java @@ -44,6 +44,7 @@ import javax.swing.border.EmptyBorder; import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.text.JTextComponent; +import net.sf.openrocket.gui.util.SwingPreferences; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -389,6 +390,7 @@ public class PresetEditorDialog extends JDialog implements ItemListener { File file = imageChooser.getSelectedFile(); ncImage = scaleImage(new ImageIcon(file.getAbsolutePath()).getImage(), 155); ncImageBtn.setIcon(ncImage); + ((SwingPreferences) Application.getPreferences()).setDefaultDirectory(imageChooser.getCurrentDirectory()); } } }); @@ -1318,6 +1320,7 @@ public class PresetEditorDialog extends JDialog implements ItemListener { */ private JFileChooser createImageChooser() { final JFileChooser chooser = new JFileChooser(); + chooser.setCurrentDirectory(((SwingPreferences) Application.getPreferences()).getDefaultDirectory()); ImagePreviewPanel preview = new ImagePreviewPanel(); chooser.setAccessory(preview); chooser.addPropertyChangeListener(preview); diff --git a/swing/src/net/sf/openrocket/utils/ComponentPresetEditor.java b/swing/src/net/sf/openrocket/utils/ComponentPresetEditor.java index a70cfc878..a1baf53f3 100644 --- a/swing/src/net/sf/openrocket/utils/ComponentPresetEditor.java +++ b/swing/src/net/sf/openrocket/utils/ComponentPresetEditor.java @@ -342,6 +342,8 @@ public class ComponentPresetEditor extends JPanel implements PresetResultListene log.info(Markers.USER_MARKER, "User decided not to open, option=" + option); return false; } + + ((SwingPreferences) Application.getPreferences()).setDefaultDirectory(chooser.getCurrentDirectory()); File file = chooser.getSelectedFile(); try { From db55a2f4f35a2323f1cf5494447f85c378da9261 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Mon, 3 Apr 2023 00:30:11 +0200 Subject: [PATCH 04/15] Add option to exclude user directories from preferences export --- core/resources/l10n/messages.properties | 4 + .../sf/openrocket/startup/Preferences.java | 12 +- .../components/PreferencesOptionPanel.java | 40 +++++ .../gui/util/PreferencesExporter.java | 149 +++++++++++++++++- .../gui/util/PreferencesImporter.java | 3 - .../openrocket/gui/util/SwingPreferences.java | 8 +- 6 files changed, 201 insertions(+), 15 deletions(-) create mode 100644 swing/src/net/sf/openrocket/gui/components/PreferencesOptionPanel.java diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index aa902f8f4..0e34aeb97 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -381,6 +381,10 @@ PreferencesExporter.chooser.title = Export the Preferences File PreferencesImporter.chooser.title = Import a Preferences File +PreferencesOptionPanel.title = Export settings +PreferencesOptionPanel.checkbox.userDirectories = Export user directories +PreferencesOptionPanel.checkbox.userDirectories.ttip = If checked, user directories (possible sensitive information) will be exported. + ! Welcome dialog welcome.dlg.title = Welcome to OpenRocket welcome.dlg.lbl.thankYou = Thank you for downloading OpenRocket diff --git a/core/src/net/sf/openrocket/startup/Preferences.java b/core/src/net/sf/openrocket/startup/Preferences.java index dd714c8bc..522f90c99 100644 --- a/core/src/net/sf/openrocket/startup/Preferences.java +++ b/core/src/net/sf/openrocket/startup/Preferences.java @@ -53,6 +53,7 @@ public abstract class Preferences implements ChangeSource { public static final String EXPORT_EVENT_COMMENTS = "ExportEventComments"; public static final String EXPORT_COMMENT_CHARACTER = "ExportCommentCharacter"; public static final String USER_LOCAL = "locale"; + public static final String DEFAULT_DIRECTORY = "defaultDirectory"; public static final String PLOT_SHOW_POINTS = "ShowPlotPoints"; @@ -80,6 +81,7 @@ public abstract class Preferences implements ChangeSource { public static final String MARKER_STYLE_ICON = "MarkerStyleIcon"; private static final String SHOW_MARKERS = "ShowMarkers"; private static final String SHOW_ROCKSIM_FORMAT_WARNING = "ShowRocksimFormatWarning"; + private static final String EXPORT_USER_DIRECTORIES = "ExportUserDirectories"; //Preferences related to 3D graphics public static final String OPENGL_ENABLED = "OpenGLIsEnabled"; @@ -231,7 +233,15 @@ public abstract class Preferences implements ChangeSource { public final void setShowRockSimFormatWarning(boolean check) { this.putBoolean(SHOW_ROCKSIM_FORMAT_WARNING, check); } - + + public final boolean getExportUserDirectories() { + return this.getBoolean(EXPORT_USER_DIRECTORIES, false); + } + + public final void setExportUserDirectories(boolean check) { + this.putBoolean(EXPORT_USER_DIRECTORIES, check); + } + public final double getDefaultMach() { return Application.getPreferences().getChoice(Preferences.DEFAULT_MACH_NUMBER, 0.9, 0.3); } diff --git a/swing/src/net/sf/openrocket/gui/components/PreferencesOptionPanel.java b/swing/src/net/sf/openrocket/gui/components/PreferencesOptionPanel.java new file mode 100644 index 000000000..34e33d9f2 --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/components/PreferencesOptionPanel.java @@ -0,0 +1,40 @@ +package net.sf.openrocket.gui.components; + +import net.miginfocom.swing.MigLayout; +import net.sf.openrocket.l10n.Translator; +import net.sf.openrocket.startup.Application; +import net.sf.openrocket.startup.Preferences; + +import javax.swing.BorderFactory; +import javax.swing.JCheckBox; +import javax.swing.JPanel; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; + +/** + * A panel that adds storage options for exporting preferences. + */ +public class PreferencesOptionPanel extends JPanel { + private static final Translator trans = Application.getTranslator(); + private static final Preferences prefs = Application.getPreferences(); + + public PreferencesOptionPanel() { + super(new MigLayout("fill, ins 0")); + + JPanel panel = new JPanel(new MigLayout("fill, ins 4lp")); + panel.setBorder(BorderFactory.createTitledBorder(trans.get("PreferencesOptionPanel.title"))); + + JCheckBox exportUserDirectories = new JCheckBox(trans.get("PreferencesOptionPanel.checkbox.userDirectories")); + exportUserDirectories.setToolTipText(trans.get("PreferencesOptionPanel.checkbox.userDirectories.ttip")); + exportUserDirectories.setSelected(prefs.getExportUserDirectories()); + exportUserDirectories.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + prefs.setExportUserDirectories(e.getStateChange() == ItemEvent.SELECTED); + } + }); + panel.add(exportUserDirectories, "wrap 10lp"); + + this.add(panel, "growx, north"); + } +} diff --git a/swing/src/net/sf/openrocket/gui/util/PreferencesExporter.java b/swing/src/net/sf/openrocket/gui/util/PreferencesExporter.java index 02564fafb..d4d2d47ae 100644 --- a/swing/src/net/sf/openrocket/gui/util/PreferencesExporter.java +++ b/swing/src/net/sf/openrocket/gui/util/PreferencesExporter.java @@ -1,22 +1,56 @@ package net.sf.openrocket.gui.util; +import net.sf.openrocket.arch.SystemInfo; +import net.sf.openrocket.gui.components.PreferencesOptionPanel; +import net.sf.openrocket.gui.main.MRUDesignFile; import net.sf.openrocket.gui.widgets.SaveFileChooser; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.startup.Application; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; import javax.swing.JFileChooser; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import java.awt.Dimension; import java.awt.Window; import java.io.File; +import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.prefs.BackingStoreException; import java.util.prefs.Preferences; public abstract class PreferencesExporter { private static final Translator trans = Application.getTranslator(); private static final Logger log = LoggerFactory.getLogger(PreferencesExporter.class); + private static final net.sf.openrocket.startup.Preferences prefs = Application.getPreferences(); + + private static final String[] userDirectoriesKeysToIgnore; // Preference keys to ignore when exporting user directories (= keys that export user directories) + private static final String[] prefixKeysToIgnore; // Preference keys to ignore when exporting user directories (= keys that start with these prefixes) + + static { + userDirectoriesKeysToIgnore = new String[] { + net.sf.openrocket.startup.Preferences.USER_THRUST_CURVES_KEY, + net.sf.openrocket.startup.Preferences.DEFAULT_DIRECTORY + }; + prefixKeysToIgnore = new String[] { + MRUDesignFile.MRU_FILE_LIST_PROPERTY + }; + } + public static boolean exportPreferences(Window parent, Preferences preferences) { JFileChooser chooser = new SaveFileChooser(); @@ -24,10 +58,15 @@ public abstract class PreferencesExporter { chooser.setAcceptAllFileFilterUsed(false); chooser.setFileFilter(FileHelper.XML_FILTER); chooser.setCurrentDirectory(((SwingPreferences) Application.getPreferences()).getDefaultDirectory()); + chooser.setAccessory(new PreferencesOptionPanel()); - - // TODO: add storageoptions to choose whether to export user directories or not (default to not) - + // TODO: update this dynamically instead of hard-coded values + // The macOS file chooser has an issue where it does not update its size when the accessory is added. + if (SystemInfo.getPlatform() == SystemInfo.Platform.MAC_OS) { + Dimension currentSize = chooser.getPreferredSize(); + Dimension newSize = new Dimension((int) (1.25 * currentSize.width), (int) (1.2 * currentSize.height)); + chooser.setPreferredSize(newSize); + } //// Ensures No Problems When Choosing File if (chooser.showSaveDialog(parent) != JFileChooser.APPROVE_OPTION) { @@ -35,7 +74,7 @@ public abstract class PreferencesExporter { return false; } - ((SwingPreferences) Application.getPreferences()).setDefaultDirectory(chooser.getCurrentDirectory()); + ((SwingPreferences) prefs).setDefaultDirectory(chooser.getCurrentDirectory()); File file = chooser.getSelectedFile(); if (file == null) { @@ -43,14 +82,20 @@ public abstract class PreferencesExporter { return false; } - file = FileHelper.forceExtension(file, "xml"); - if (!FileHelper.confirmWrite(file, parent)) { + final File newFile = FileHelper.forceExtension(file, "xml"); + if (!FileHelper.confirmWrite(newFile, parent)) { log.info("Cancelled export of preferences."); return false; } - try (FileOutputStream fos = new FileOutputStream(file)) { - preferences.exportSubtree(fos); + try (FileOutputStream fos = new FileOutputStream(newFile)) { + if (prefs.getExportUserDirectories()) { + // Export all preferences + preferences.exportSubtree(fos); + } else { + // Export all preferences except user directories + exportFilteredPreferences(preferences, fos); + } log.info("Preferences exported successfully."); } catch (IOException | BackingStoreException e) { log.warn("Error while importing preferences: " + e.getMessage()); @@ -58,4 +103,92 @@ public abstract class PreferencesExporter { return true; } + + private static void exportFilteredPreferences(Preferences preferences, FileOutputStream fos) throws BackingStoreException, IOException { + // Filter out user directories + Preferences root = Preferences.userRoot(); + String originalNodeName = ((SwingPreferences) prefs).getNodename(); + String nodeName = originalNodeName + "-temp"; + if (root.nodeExists(nodeName)) { + root.node(nodeName).removeNode(); + } + Preferences tempPrefs = root.node(nodeName); + + // Fill in all parameters to the temporary preferences, except for user directories + copyFilteredPreferences(preferences, tempPrefs, userDirectoriesKeysToIgnore, prefixKeysToIgnore); + + // Export the filtered preferences + try { + // Export the filtered preferences to a temporary file + Path tempFile = Files.createTempFile("ORprefs_" + System.currentTimeMillis(), ".xml"); + try (FileOutputStream tempFos = new FileOutputStream(tempFile.toFile())) { + tempPrefs.exportSubtree(tempFos); + } + + // Read and parse the temporary file + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + Document doc; + try (FileInputStream tempFis = new FileInputStream(tempFile.toFile())) { + doc = factory.newDocumentBuilder().parse(tempFis); + } + + // Find and rename the node + NodeList nodeList = doc.getElementsByTagName("node"); + for (int i = 0; i < nodeList.getLength(); i++) { + Element element = (Element) nodeList.item(i); + if (element.getAttribute("name").equals(nodeName)) { + element.setAttribute("name", ((SwingPreferences) prefs).getNodename()); + break; + } + } + + // Create a transformer to write the XML document to the FileOutputStream + Transformer transformer = TransformerFactory.newInstance().newTransformer(); + + // Set output properties to include the correct DOCTYPE declaration + transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "http://java.sun.com/dtd/preferences.dtd"); + transformer.setOutputProperty(OutputKeys.STANDALONE, "no"); + + // Write the XML document to the FileOutputStream + DOMSource source = new DOMSource(doc); + StreamResult result = new StreamResult(fos); + transformer.transform(source, result); + + // Clean up the temporary file + Files.deleteIfExists(tempFile); + } catch (ParserConfigurationException | TransformerException | SAXException e) { + e.printStackTrace(); + } finally { + root.node(nodeName).removeNode(); + } + } + + private static void copyFilteredPreferences(Preferences src, Preferences dest, String[] keysToIgnore, String[] prefixKeysToIgnore) throws BackingStoreException { + for (String key : src.keys()) { + boolean ignoreKey = false; + for (String keyToIgnore : keysToIgnore) { + if (key.equals(keyToIgnore)) { + ignoreKey = true; + break; + } + } + if (!ignoreKey) { + for (String prefixKeyToIgnore : prefixKeysToIgnore) { + if (key.startsWith(prefixKeyToIgnore)) { + ignoreKey = true; + break; + } + } + } + if (!ignoreKey) { + dest.put(key, src.get(key, null)); + } + } + + for (String childNodeName : src.childrenNames()) { + Preferences srcChild = src.node(childNodeName); + Preferences destChild = dest.node(childNodeName); + copyFilteredPreferences(srcChild, destChild, keysToIgnore, prefixKeysToIgnore); + } + } } diff --git a/swing/src/net/sf/openrocket/gui/util/PreferencesImporter.java b/swing/src/net/sf/openrocket/gui/util/PreferencesImporter.java index 7b3aba43f..32a4044db 100644 --- a/swing/src/net/sf/openrocket/gui/util/PreferencesImporter.java +++ b/swing/src/net/sf/openrocket/gui/util/PreferencesImporter.java @@ -34,9 +34,6 @@ public abstract class PreferencesImporter { File importFile = chooser.getSelectedFile(); try (FileInputStream fis = new FileInputStream(importFile)) { - - // TODO: don't import user directories? - Preferences.importPreferences(fis); log.info("Preferences imported successfully."); } catch (IOException | InvalidPreferencesFormatException e) { diff --git a/swing/src/net/sf/openrocket/gui/util/SwingPreferences.java b/swing/src/net/sf/openrocket/gui/util/SwingPreferences.java index 9ac18081f..686c5bce0 100644 --- a/swing/src/net/sf/openrocket/gui/util/SwingPreferences.java +++ b/swing/src/net/sf/openrocket/gui/util/SwingPreferences.java @@ -88,7 +88,9 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences { PREFNODE = root.node(NODENAME); } - + public String getNodename() { + return NODENAME; + } ////////////////////// @@ -232,7 +234,7 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences { } public File getDefaultDirectory() { - String file = getString("defaultDirectory", null); + String file = getString(net.sf.openrocket.startup.Preferences.DEFAULT_DIRECTORY, null); if (file == null) return null; return new File(file); @@ -245,7 +247,7 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences { } else { d = dir.getAbsolutePath(); } - putString("defaultDirectory", d); + putString(net.sf.openrocket.startup.Preferences.DEFAULT_DIRECTORY, d); storeVersion(); } From e7824c55532e687895cfc00e2aaa18d8d571e4b7 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Mon, 3 Apr 2023 10:19:25 +0200 Subject: [PATCH 05/15] Remove unused imports --- swing/src/net/sf/openrocket/gui/util/DummyFrameMenuOSX.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/swing/src/net/sf/openrocket/gui/util/DummyFrameMenuOSX.java b/swing/src/net/sf/openrocket/gui/util/DummyFrameMenuOSX.java index 9a4a84a33..4b9f1537b 100644 --- a/swing/src/net/sf/openrocket/gui/util/DummyFrameMenuOSX.java +++ b/swing/src/net/sf/openrocket/gui/util/DummyFrameMenuOSX.java @@ -1,11 +1,6 @@ package net.sf.openrocket.gui.util; -import net.sf.openrocket.gui.dialogs.AboutDialog; -import net.sf.openrocket.gui.dialogs.LicenseDialog; -import net.sf.openrocket.gui.help.tours.GuidedTourSelectionDialog; import net.sf.openrocket.gui.main.BasicFrame; -import net.sf.openrocket.gui.main.ExampleDesignFileAction; -import net.sf.openrocket.gui.main.MRUDesignFileAction; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.logging.Markers; import net.sf.openrocket.startup.Application; From 42714e73e750a392a0fa9ac57978e150ca6d404a Mon Sep 17 00:00:00 2001 From: SiboVG Date: Mon, 3 Apr 2023 11:11:23 +0200 Subject: [PATCH 06/15] Add option to ignore window information exporting --- core/resources/l10n/messages.properties | 2 + .../sf/openrocket/startup/Preferences.java | 9 +++ .../components/PreferencesOptionPanel.java | 16 ++++- .../gui/util/PreferencesExporter.java | 59 +++++++++---------- .../openrocket/gui/util/SwingPreferences.java | 16 ++--- 5 files changed, 63 insertions(+), 39 deletions(-) diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index 0e34aeb97..a33d04389 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -384,6 +384,8 @@ PreferencesImporter.chooser.title = Import a Preferences File PreferencesOptionPanel.title = Export settings PreferencesOptionPanel.checkbox.userDirectories = Export user directories PreferencesOptionPanel.checkbox.userDirectories.ttip = If checked, user directories (possible sensitive information) will be exported. +PreferencesOptionPanel.checkbox.windowInfo = Export window information (position, size\u2026) +PreferencesOptionPanel.checkbox.windowInfo.ttip = If checked, window information (position, size\u2026) will be exported. ! Welcome dialog welcome.dlg.title = Welcome to OpenRocket diff --git a/core/src/net/sf/openrocket/startup/Preferences.java b/core/src/net/sf/openrocket/startup/Preferences.java index 522f90c99..a3dfedc3f 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 SHOW_MARKERS = "ShowMarkers"; private static final String SHOW_ROCKSIM_FORMAT_WARNING = "ShowRocksimFormatWarning"; private static final String EXPORT_USER_DIRECTORIES = "ExportUserDirectories"; + private static final String EXPORT_WINDOW_INFORMATION = "ExportWindowInformation"; //Preferences related to 3D graphics public static final String OPENGL_ENABLED = "OpenGLIsEnabled"; @@ -242,6 +243,14 @@ public abstract class Preferences implements ChangeSource { this.putBoolean(EXPORT_USER_DIRECTORIES, check); } + public final boolean getExportWindowInformation() { + return this.getBoolean(EXPORT_WINDOW_INFORMATION, false); + } + + public final void setExportWindowInformation(boolean check) { + this.putBoolean(EXPORT_WINDOW_INFORMATION, check); + } + public final double getDefaultMach() { return Application.getPreferences().getChoice(Preferences.DEFAULT_MACH_NUMBER, 0.9, 0.3); } diff --git a/swing/src/net/sf/openrocket/gui/components/PreferencesOptionPanel.java b/swing/src/net/sf/openrocket/gui/components/PreferencesOptionPanel.java index 34e33d9f2..63790e681 100644 --- a/swing/src/net/sf/openrocket/gui/components/PreferencesOptionPanel.java +++ b/swing/src/net/sf/openrocket/gui/components/PreferencesOptionPanel.java @@ -24,6 +24,7 @@ public class PreferencesOptionPanel extends JPanel { JPanel panel = new JPanel(new MigLayout("fill, ins 4lp")); panel.setBorder(BorderFactory.createTitledBorder(trans.get("PreferencesOptionPanel.title"))); + // Export user directories JCheckBox exportUserDirectories = new JCheckBox(trans.get("PreferencesOptionPanel.checkbox.userDirectories")); exportUserDirectories.setToolTipText(trans.get("PreferencesOptionPanel.checkbox.userDirectories.ttip")); exportUserDirectories.setSelected(prefs.getExportUserDirectories()); @@ -33,7 +34,20 @@ public class PreferencesOptionPanel extends JPanel { prefs.setExportUserDirectories(e.getStateChange() == ItemEvent.SELECTED); } }); - panel.add(exportUserDirectories, "wrap 10lp"); + panel.add(exportUserDirectories, "wrap"); + + // Export window information (position, size...) + JCheckBox exportWindowInfo = new JCheckBox(trans.get("PreferencesOptionPanel.checkbox.windowInfo")); + exportWindowInfo.setToolTipText(trans.get("PreferencesOptionPanel.checkbox.windowInfo.ttip")); + exportWindowInfo.setSelected(prefs.getExportWindowInformation()); + exportWindowInfo.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + prefs.setExportWindowInformation(e.getStateChange() == ItemEvent.SELECTED); + } + }); + panel.add(exportWindowInfo, "wrap 10lp"); + this.add(panel, "growx, north"); } diff --git a/swing/src/net/sf/openrocket/gui/util/PreferencesExporter.java b/swing/src/net/sf/openrocket/gui/util/PreferencesExporter.java index d4d2d47ae..72e875e57 100644 --- a/swing/src/net/sf/openrocket/gui/util/PreferencesExporter.java +++ b/swing/src/net/sf/openrocket/gui/util/PreferencesExporter.java @@ -30,6 +30,9 @@ import java.io.FileOutputStream; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.function.BiPredicate; import java.util.prefs.BackingStoreException; import java.util.prefs.Preferences; @@ -38,17 +41,20 @@ public abstract class PreferencesExporter { private static final Logger log = LoggerFactory.getLogger(PreferencesExporter.class); private static final net.sf.openrocket.startup.Preferences prefs = Application.getPreferences(); - private static final String[] userDirectoriesKeysToIgnore; // Preference keys to ignore when exporting user directories (= keys that export user directories) - private static final String[] prefixKeysToIgnore; // Preference keys to ignore when exporting user directories (= keys that start with these prefixes) + private static final List keysToIgnore = new ArrayList<>(); // Preference keys to ignore when exporting user directories (= keys that export user directories) + private static final List prefixKeysToIgnore = new ArrayList<>(); // Preference keys to ignore when exporting user directories (= keys that start with these prefixes), e.g. + private static final List nodesToIgnore = new ArrayList<>(); // Preferences nodes that should not be exported static { - userDirectoriesKeysToIgnore = new String[] { - net.sf.openrocket.startup.Preferences.USER_THRUST_CURVES_KEY, - net.sf.openrocket.startup.Preferences.DEFAULT_DIRECTORY - }; - prefixKeysToIgnore = new String[] { - MRUDesignFile.MRU_FILE_LIST_PROPERTY - }; + if (!prefs.getExportUserDirectories()) { + keysToIgnore.add(net.sf.openrocket.startup.Preferences.USER_THRUST_CURVES_KEY); + keysToIgnore.add(net.sf.openrocket.startup.Preferences.DEFAULT_DIRECTORY); + prefixKeysToIgnore.add(MRUDesignFile.MRU_FILE_LIST_PROPERTY); + } + + if (!prefs.getExportWindowInformation()) { + nodesToIgnore.add(SwingPreferences.NODE_WINDOWS); + } } @@ -64,7 +70,7 @@ public abstract class PreferencesExporter { // The macOS file chooser has an issue where it does not update its size when the accessory is added. if (SystemInfo.getPlatform() == SystemInfo.Platform.MAC_OS) { Dimension currentSize = chooser.getPreferredSize(); - Dimension newSize = new Dimension((int) (1.25 * currentSize.width), (int) (1.2 * currentSize.height)); + Dimension newSize = new Dimension((int) (1.35 * currentSize.width), (int) (1.2 * currentSize.height)); chooser.setPreferredSize(newSize); } @@ -89,7 +95,7 @@ public abstract class PreferencesExporter { } try (FileOutputStream fos = new FileOutputStream(newFile)) { - if (prefs.getExportUserDirectories()) { + if (keysToIgnore.isEmpty() && nodesToIgnore.isEmpty() && prefixKeysToIgnore.isEmpty()) { // Export all preferences preferences.exportSubtree(fos); } else { @@ -115,7 +121,7 @@ public abstract class PreferencesExporter { Preferences tempPrefs = root.node(nodeName); // Fill in all parameters to the temporary preferences, except for user directories - copyFilteredPreferences(preferences, tempPrefs, userDirectoriesKeysToIgnore, prefixKeysToIgnore); + copyFilteredPreferences(preferences, tempPrefs, nodesToIgnore, keysToIgnore, prefixKeysToIgnore); // Export the filtered preferences try { @@ -163,32 +169,23 @@ public abstract class PreferencesExporter { } } - private static void copyFilteredPreferences(Preferences src, Preferences dest, String[] keysToIgnore, String[] prefixKeysToIgnore) throws BackingStoreException { + private static void copyFilteredPreferences(Preferences src, Preferences dest, + List nodesToIgnore, List keysToIgnore, List prefixKeysToIgnore) throws BackingStoreException { for (String key : src.keys()) { - boolean ignoreKey = false; - for (String keyToIgnore : keysToIgnore) { - if (key.equals(keyToIgnore)) { - ignoreKey = true; - break; - } - } - if (!ignoreKey) { - for (String prefixKeyToIgnore : prefixKeysToIgnore) { - if (key.startsWith(prefixKeyToIgnore)) { - ignoreKey = true; - break; - } - } - } - if (!ignoreKey) { - dest.put(key, src.get(key, null)); + if (keysToIgnore.contains(key) + || prefixKeysToIgnore.stream().anyMatch(key::startsWith)) { + continue; } + dest.put(key, src.get(key, null)); } for (String childNodeName : src.childrenNames()) { + if (nodesToIgnore.contains(childNodeName)) { + continue; + } Preferences srcChild = src.node(childNodeName); Preferences destChild = dest.node(childNodeName); - copyFilteredPreferences(srcChild, destChild, keysToIgnore, prefixKeysToIgnore); + copyFilteredPreferences(srcChild, destChild, nodesToIgnore, keysToIgnore, prefixKeysToIgnore); } } } diff --git a/swing/src/net/sf/openrocket/gui/util/SwingPreferences.java b/swing/src/net/sf/openrocket/gui/util/SwingPreferences.java index 686c5bce0..277edc0b4 100644 --- a/swing/src/net/sf/openrocket/gui/util/SwingPreferences.java +++ b/swing/src/net/sf/openrocket/gui/util/SwingPreferences.java @@ -38,7 +38,9 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences { private static final Logger log = LoggerFactory.getLogger(SwingPreferences.class); private static final String SPLIT_CHARACTER = "|"; - + + + public static final String NODE_WINDOWS = "windows"; private static final List SUPPORTED_LOCALES; static { @@ -378,7 +380,7 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences { public Point getWindowPosition(Class c) { int x, y; - String pref = PREFNODE.node("windows").get("position." + c.getCanonicalName(), null); + String pref = PREFNODE.node(NODE_WINDOWS).get("position." + c.getCanonicalName(), null); if (pref == null) return null; @@ -396,7 +398,7 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences { } public void setWindowPosition(Class c, Point p) { - PREFNODE.node("windows").put("position." + c.getCanonicalName(), "" + p.x + "," + p.y); + PREFNODE.node(NODE_WINDOWS).put("position." + c.getCanonicalName(), "" + p.x + "," + p.y); storeVersion(); } @@ -405,7 +407,7 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences { public Dimension getWindowSize(Class c) { int x, y; - String pref = PREFNODE.node("windows").get("size." + c.getCanonicalName(), null); + String pref = PREFNODE.node(NODE_WINDOWS).get("size." + c.getCanonicalName(), null); if (pref == null) return null; @@ -424,17 +426,17 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences { public boolean isWindowMaximized(Class c) { - String pref = PREFNODE.node("windows").get("size." + c.getCanonicalName(), null); + String pref = PREFNODE.node(NODE_WINDOWS).get("size." + c.getCanonicalName(), null); return "max".equals(pref); } public void setWindowSize(Class c, Dimension d) { - PREFNODE.node("windows").put("size." + c.getCanonicalName(), "" + d.width + "," + d.height); + PREFNODE.node(NODE_WINDOWS).put("size." + c.getCanonicalName(), "" + d.width + "," + d.height); storeVersion(); } public void setWindowMaximized(Class c) { - PREFNODE.node("windows").put("size." + c.getCanonicalName(), "max"); + PREFNODE.node(NODE_WINDOWS).put("size." + c.getCanonicalName(), "max"); storeVersion(); } From 6a54e97fb4ccc51d9e836288bce8f2b6f3543be4 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Mon, 3 Apr 2023 13:04:24 +0200 Subject: [PATCH 07/15] Fix merge conflict --- .../net/sf/openrocket/startup/Preferences.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/core/src/net/sf/openrocket/startup/Preferences.java b/core/src/net/sf/openrocket/startup/Preferences.java index 8cf591ea6..7e67fa317 100644 --- a/core/src/net/sf/openrocket/startup/Preferences.java +++ b/core/src/net/sf/openrocket/startup/Preferences.java @@ -557,6 +557,22 @@ public abstract class Preferences implements ChangeSource { this.putBoolean(SHOW_DISCARD_CONFIRMATION, enabled); } + /** + * Answer if a confirmation dialog should be shown when canceling a simulation config operation. + * + * @return true if the confirmation dialog should be shown. + */ + public final boolean isShowDiscardSimulationConfirmation() { + return this.getBoolean(SHOW_DISCARD_SIMULATION_CONFIRMATION, true); + } + + /** + * Enable/Disable showing a confirmation warning when canceling a simulation config operation. + */ + public final void setShowDiscardSimulationConfirmation(boolean enabled) { + this.putBoolean(SHOW_DISCARD_SIMULATION_CONFIRMATION, enabled); + } + /** * Answer if the always open leftmost tab is enabled. * From 86b277e9cb8c188c9cfe7d2b2c5ae0ef9ba680a0 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Tue, 4 Apr 2023 00:14:59 +0200 Subject: [PATCH 08/15] Also add table information to window ignoring --- .../src/net/sf/openrocket/gui/util/PreferencesExporter.java | 2 +- swing/src/net/sf/openrocket/gui/util/SwingPreferences.java | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/swing/src/net/sf/openrocket/gui/util/PreferencesExporter.java b/swing/src/net/sf/openrocket/gui/util/PreferencesExporter.java index 72e875e57..7d1104dbf 100644 --- a/swing/src/net/sf/openrocket/gui/util/PreferencesExporter.java +++ b/swing/src/net/sf/openrocket/gui/util/PreferencesExporter.java @@ -32,7 +32,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; -import java.util.function.BiPredicate; import java.util.prefs.BackingStoreException; import java.util.prefs.Preferences; @@ -54,6 +53,7 @@ public abstract class PreferencesExporter { if (!prefs.getExportWindowInformation()) { nodesToIgnore.add(SwingPreferences.NODE_WINDOWS); + nodesToIgnore.add(SwingPreferences.NODE_TABLES); } } diff --git a/swing/src/net/sf/openrocket/gui/util/SwingPreferences.java b/swing/src/net/sf/openrocket/gui/util/SwingPreferences.java index 277edc0b4..63686ffca 100644 --- a/swing/src/net/sf/openrocket/gui/util/SwingPreferences.java +++ b/swing/src/net/sf/openrocket/gui/util/SwingPreferences.java @@ -41,6 +41,7 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences { public static final String NODE_WINDOWS = "windows"; + public static final String NODE_TABLES = "tables"; private static final List SUPPORTED_LOCALES; static { @@ -441,7 +442,7 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences { } public Integer getTableColumnWidth(String keyName, int columnIdx) { - String pref = PREFNODE.node("tables").get( + String pref = PREFNODE.node(NODE_TABLES).get( "cw." + keyName + "." + columnIdx, null); if (pref == null) return null; @@ -459,7 +460,7 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences { } public void setTableColumnWidth(String keyName, int columnIdx, Integer width) { - PREFNODE.node("tables").put( + PREFNODE.node(NODE_TABLES).put( "cw." + keyName + "." + columnIdx, width.toString()); storeVersion(); } From e7e551c090620975e14f523679e6ff21daa55cf0 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Tue, 4 Apr 2023 00:21:35 +0200 Subject: [PATCH 09/15] Ignore update platform in exporting --- .../openrocket/gui/util/PreferencesExporter.java | 2 ++ .../sf/openrocket/gui/util/SwingPreferences.java | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/swing/src/net/sf/openrocket/gui/util/PreferencesExporter.java b/swing/src/net/sf/openrocket/gui/util/PreferencesExporter.java index 7d1104dbf..1dc895587 100644 --- a/swing/src/net/sf/openrocket/gui/util/PreferencesExporter.java +++ b/swing/src/net/sf/openrocket/gui/util/PreferencesExporter.java @@ -55,6 +55,8 @@ public abstract class PreferencesExporter { nodesToIgnore.add(SwingPreferences.NODE_WINDOWS); nodesToIgnore.add(SwingPreferences.NODE_TABLES); } + + keysToIgnore.add(SwingPreferences.UPDATE_PLATFORM); // Don't export platform-specific settings } diff --git a/swing/src/net/sf/openrocket/gui/util/SwingPreferences.java b/swing/src/net/sf/openrocket/gui/util/SwingPreferences.java index 63686ffca..7b69dd85f 100644 --- a/swing/src/net/sf/openrocket/gui/util/SwingPreferences.java +++ b/swing/src/net/sf/openrocket/gui/util/SwingPreferences.java @@ -42,6 +42,7 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences { public static final String NODE_WINDOWS = "windows"; public static final String NODE_TABLES = "tables"; + public static final String UPDATE_PLATFORM = "UpdatePlatform"; private static final List SUPPORTED_LOCALES; static { @@ -271,13 +272,22 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences { return compdir; } + /** + * Set the operating system that the software updater will use to redirect you to an installer download link. + * @param platform the operating system to use + */ public void setUpdatePlatform(UpdatePlatform platform) { if (platform == null) return; - putString("UpdatePlatform", platform.name()); + putString(UPDATE_PLATFORM, platform.name()); } + /** + * Get the operating system that will be selected when asking for a software update. + * E.g. "Windows" will cause the software updater to default to letting you download a Windows installer. + * @return the operating system that is used + */ public UpdatePlatform getUpdatePlatform() { - String p = getString("UpdatePlatform", SystemInfo.getPlatform().name()); + String p = getString(UPDATE_PLATFORM, SystemInfo.getPlatform().name()); if (p == null) return null; return UpdatePlatform.valueOf(p); } From 423295fe524d6aecd5a5277a73650e0c30c7063d Mon Sep 17 00:00:00 2001 From: SiboVG Date: Tue, 4 Apr 2023 00:24:41 +0200 Subject: [PATCH 10/15] Update trans keys --- core/resources/l10n/messages.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index 73d919e16..77971c240 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -385,9 +385,9 @@ PreferencesImporter.chooser.title = Import a Preferences File PreferencesOptionPanel.title = Export settings PreferencesOptionPanel.checkbox.userDirectories = Export user directories -PreferencesOptionPanel.checkbox.userDirectories.ttip = If checked, user directories (possible sensitive information) will be exported. +PreferencesOptionPanel.checkbox.userDirectories.ttip = If unchecked, user directories (possibly sensitive information) will not be exported. PreferencesOptionPanel.checkbox.windowInfo = Export window information (position, size\u2026) -PreferencesOptionPanel.checkbox.windowInfo.ttip = If checked, window information (position, size\u2026) will be exported. +PreferencesOptionPanel.checkbox.windowInfo.ttip = If unchecked, window information (position, size\u2026) will not be exported. ! Welcome dialog welcome.dlg.title = Welcome to OpenRocket From abb742bcc6b2e80fe423803665b83a87f78326ed Mon Sep 17 00:00:00 2001 From: SiboVG Date: Fri, 7 Apr 2023 01:06:15 +0200 Subject: [PATCH 11/15] Save preference key if it didn't exist before --- .../openrocket/gui/util/SwingPreferences.java | 63 ++++++++++++++++++- 1 file changed, 60 insertions(+), 3 deletions(-) diff --git a/swing/src/net/sf/openrocket/gui/util/SwingPreferences.java b/swing/src/net/sf/openrocket/gui/util/SwingPreferences.java index 7b69dd85f..dc7146bac 100644 --- a/swing/src/net/sf/openrocket/gui/util/SwingPreferences.java +++ b/swing/src/net/sf/openrocket/gui/util/SwingPreferences.java @@ -124,7 +124,22 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences { private void storeVersion() { PREFNODE.put("OpenRocketVersion", BuildProperties.getVersion()); } - + + /** + * Checks if a certain key exists in the node + * @param node node to check the keys of. + * @param key key to check + * @return true if the key is stored in the preferences, false otherwise + */ + private boolean keyExists(Preferences node, String key) { + try { + return Arrays.asList(node.keys()).contains(key); + } catch (BackingStoreException e) { + e.printStackTrace(); + return false; + } + } + /** * Return a string preference. * @@ -134,12 +149,28 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences { */ @Override public String getString(String key, String def) { + if (!keyExists(PREFNODE, key) && key != null && def != null) { + PREFNODE.put(key, def); + try { + PREFNODE.flush(); + } catch (BackingStoreException e) { + e.printStackTrace(); + } + } return PREFNODE.get(key, def); } @Override public String getString(String directory, String key, String defaultValue) { Preferences p = PREFNODE.node(directory); + if (!keyExists(p, key) && key != null && defaultValue != null) { + p.put(key, defaultValue); + try { + p.flush(); + } catch (BackingStoreException e) { + e.printStackTrace(); + } + } return p.get(key, defaultValue); } @@ -179,6 +210,16 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences { */ @Override public boolean getBoolean(String key, boolean def) { + // Check if the key exists + if (!keyExists(PREFNODE, key) && key != null) { + // Save the default value + PREFNODE.putBoolean(key, def); + try { + PREFNODE.flush(); + } catch (BackingStoreException e) { + e.printStackTrace(); + } + } return PREFNODE.getBoolean(key, def); } @@ -193,9 +234,17 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences { PREFNODE.putBoolean(key, value); storeVersion(); } - + @Override public int getInt(String key, int defaultValue) { + if (!keyExists(PREFNODE, key) && key != null) { + PREFNODE.putInt(key, defaultValue); + try { + PREFNODE.flush(); + } catch (BackingStoreException e) { + e.printStackTrace(); + } + } return PREFNODE.getInt(key, defaultValue); } @@ -204,9 +253,17 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences { PREFNODE.putInt(key, value); storeVersion(); } - + @Override public double getDouble(String key, double defaultValue) { + if (!keyExists(PREFNODE, key) && key != null) { + PREFNODE.putDouble(key, defaultValue); + try { + PREFNODE.flush(); + } catch (BackingStoreException e) { + e.printStackTrace(); + } + } return PREFNODE.getDouble(key, defaultValue); } From 0f094972751b662af42e5e5551bd1c33af23cce8 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Fri, 7 Apr 2023 01:47:29 +0200 Subject: [PATCH 12/15] Fix options not updating after different tries --- .../components/PreferencesOptionPanel.java | 15 ++++++- .../gui/util/PreferencesExporter.java | 43 +++++++++++-------- 2 files changed, 39 insertions(+), 19 deletions(-) diff --git a/swing/src/net/sf/openrocket/gui/components/PreferencesOptionPanel.java b/swing/src/net/sf/openrocket/gui/components/PreferencesOptionPanel.java index 63790e681..a87e7a19b 100644 --- a/swing/src/net/sf/openrocket/gui/components/PreferencesOptionPanel.java +++ b/swing/src/net/sf/openrocket/gui/components/PreferencesOptionPanel.java @@ -18,6 +18,9 @@ public class PreferencesOptionPanel extends JPanel { private static final Translator trans = Application.getTranslator(); private static final Preferences prefs = Application.getPreferences(); + private final JCheckBox exportUserDirectories; + private final JCheckBox exportWindowInfo; + public PreferencesOptionPanel() { super(new MigLayout("fill, ins 0")); @@ -25,7 +28,7 @@ public class PreferencesOptionPanel extends JPanel { panel.setBorder(BorderFactory.createTitledBorder(trans.get("PreferencesOptionPanel.title"))); // Export user directories - JCheckBox exportUserDirectories = new JCheckBox(trans.get("PreferencesOptionPanel.checkbox.userDirectories")); + exportUserDirectories = new JCheckBox(trans.get("PreferencesOptionPanel.checkbox.userDirectories")); exportUserDirectories.setToolTipText(trans.get("PreferencesOptionPanel.checkbox.userDirectories.ttip")); exportUserDirectories.setSelected(prefs.getExportUserDirectories()); exportUserDirectories.addItemListener(new ItemListener() { @@ -37,7 +40,7 @@ public class PreferencesOptionPanel extends JPanel { panel.add(exportUserDirectories, "wrap"); // Export window information (position, size...) - JCheckBox exportWindowInfo = new JCheckBox(trans.get("PreferencesOptionPanel.checkbox.windowInfo")); + exportWindowInfo = new JCheckBox(trans.get("PreferencesOptionPanel.checkbox.windowInfo")); exportWindowInfo.setToolTipText(trans.get("PreferencesOptionPanel.checkbox.windowInfo.ttip")); exportWindowInfo.setSelected(prefs.getExportWindowInformation()); exportWindowInfo.addItemListener(new ItemListener() { @@ -51,4 +54,12 @@ public class PreferencesOptionPanel extends JPanel { this.add(panel, "growx, north"); } + + public boolean isIgnoreUserDirectories() { + return !exportUserDirectories.isSelected(); + } + + public boolean isIgnoreWindowInformation() { + return !exportWindowInfo.isSelected(); + } } diff --git a/swing/src/net/sf/openrocket/gui/util/PreferencesExporter.java b/swing/src/net/sf/openrocket/gui/util/PreferencesExporter.java index 1dc895587..ab40b7114 100644 --- a/swing/src/net/sf/openrocket/gui/util/PreferencesExporter.java +++ b/swing/src/net/sf/openrocket/gui/util/PreferencesExporter.java @@ -44,29 +44,14 @@ public abstract class PreferencesExporter { private static final List prefixKeysToIgnore = new ArrayList<>(); // Preference keys to ignore when exporting user directories (= keys that start with these prefixes), e.g. private static final List nodesToIgnore = new ArrayList<>(); // Preferences nodes that should not be exported - static { - if (!prefs.getExportUserDirectories()) { - keysToIgnore.add(net.sf.openrocket.startup.Preferences.USER_THRUST_CURVES_KEY); - keysToIgnore.add(net.sf.openrocket.startup.Preferences.DEFAULT_DIRECTORY); - prefixKeysToIgnore.add(MRUDesignFile.MRU_FILE_LIST_PROPERTY); - } - - if (!prefs.getExportWindowInformation()) { - nodesToIgnore.add(SwingPreferences.NODE_WINDOWS); - nodesToIgnore.add(SwingPreferences.NODE_TABLES); - } - - keysToIgnore.add(SwingPreferences.UPDATE_PLATFORM); // Don't export platform-specific settings - } - - public static boolean exportPreferences(Window parent, Preferences preferences) { JFileChooser chooser = new SaveFileChooser(); chooser.setDialogTitle(trans.get("PreferencesExporter.chooser.title")); chooser.setAcceptAllFileFilterUsed(false); chooser.setFileFilter(FileHelper.XML_FILTER); chooser.setCurrentDirectory(((SwingPreferences) Application.getPreferences()).getDefaultDirectory()); - chooser.setAccessory(new PreferencesOptionPanel()); + PreferencesOptionPanel options = new PreferencesOptionPanel(); + chooser.setAccessory(options); // TODO: update this dynamically instead of hard-coded values // The macOS file chooser has an issue where it does not update its size when the accessory is added. @@ -96,6 +81,11 @@ public abstract class PreferencesExporter { return false; } + // Decide which keys/nodes to ignore + boolean ignoreUserDirectories = options.isIgnoreUserDirectories(); + boolean ignoreWindowInformation = options.isIgnoreWindowInformation(); + fillIgnoreKeys(ignoreUserDirectories, ignoreWindowInformation); + try (FileOutputStream fos = new FileOutputStream(newFile)) { if (keysToIgnore.isEmpty() && nodesToIgnore.isEmpty() && prefixKeysToIgnore.isEmpty()) { // Export all preferences @@ -112,6 +102,25 @@ public abstract class PreferencesExporter { return true; } + private static void fillIgnoreKeys(boolean ignoreUserDirectories, boolean ignoreWindowInformation) { + keysToIgnore.clear(); + prefixKeysToIgnore.clear(); + nodesToIgnore.clear(); + + if (ignoreUserDirectories) { + keysToIgnore.add(net.sf.openrocket.startup.Preferences.USER_THRUST_CURVES_KEY); + keysToIgnore.add(net.sf.openrocket.startup.Preferences.DEFAULT_DIRECTORY); + prefixKeysToIgnore.add(MRUDesignFile.MRU_FILE_LIST_PROPERTY); + } + + if (ignoreWindowInformation) { + nodesToIgnore.add(SwingPreferences.NODE_WINDOWS); + nodesToIgnore.add(SwingPreferences.NODE_TABLES); + } + + keysToIgnore.add(SwingPreferences.UPDATE_PLATFORM); // Don't export platform-specific settings + } + private static void exportFilteredPreferences(Preferences preferences, FileOutputStream fos) throws BackingStoreException, IOException { // Filter out user directories Preferences root = Preferences.userRoot(); From 8a521853226e3cf20f9efae31706ea325638fa39 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Fri, 7 Apr 2023 01:56:11 +0200 Subject: [PATCH 13/15] Show warning dialog about restarting OR after preferences import --- core/resources/l10n/messages.properties | 2 ++ .../preferences/GeneralPreferencesPanel.java | 20 ++++++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index 77971c240..31afed57a 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -378,6 +378,8 @@ PreferencesDialog.lbl.languageEffect = The language will change the next time yo generalprefs.lbl.language = Interface language generalprefs.languages.default = System default generalprefs.lbl.languageEffect = The language will change the next time you start OpenRocket. +generalprefs.ImportWarning.title = Reload OpenRocket +generalprefs.ImportWarning.msg = You may need to restart OpenRocket for some of the changes to take effect. PreferencesExporter.chooser.title = Export the Preferences File diff --git a/swing/src/net/sf/openrocket/gui/dialogs/preferences/GeneralPreferencesPanel.java b/swing/src/net/sf/openrocket/gui/dialogs/preferences/GeneralPreferencesPanel.java index 09e1ef7d1..484c0b9b4 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/preferences/GeneralPreferencesPanel.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/preferences/GeneralPreferencesPanel.java @@ -264,13 +264,19 @@ public class GeneralPreferencesPanel extends PreferencesPanel { importPreferences.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - PreferencesImporter.importPreferences(parent); - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - PreferencesDialog.showPreferences(parent.getParentFrame()); // Refresh the preferences dialog - } - }); + boolean imported = PreferencesImporter.importPreferences(parent); + if (imported) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + JOptionPane.showMessageDialog(parent, + trans.get("generalprefs.ImportWarning.msg"), + trans.get("generalprefs.ImportWarning.title"), + JOptionPane.WARNING_MESSAGE); + PreferencesDialog.showPreferences(parent.getParentFrame()); // Refresh the preferences dialog + } + }); + } } }); buttonPanel.add(importPreferences); From ed7a3a2a726179f6d814533dfd49717ec4df0c32 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Fri, 7 Apr 2023 08:19:55 +0200 Subject: [PATCH 14/15] Re-open prefs dialog after preferences reset --- .../gui/dialogs/preferences/GeneralPreferencesPanel.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/swing/src/net/sf/openrocket/gui/dialogs/preferences/GeneralPreferencesPanel.java b/swing/src/net/sf/openrocket/gui/dialogs/preferences/GeneralPreferencesPanel.java index 484c0b9b4..b06a282c3 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/preferences/GeneralPreferencesPanel.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/preferences/GeneralPreferencesPanel.java @@ -291,6 +291,12 @@ public class GeneralPreferencesPanel extends PreferencesPanel { trans.get("pref.dlg.clearCachedPreferences.title"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); if (resultYesNo == JOptionPane.YES_OPTION) { preferences.clearPreferences(); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + PreferencesDialog.showPreferences(parent.getParentFrame()); // Refresh the preferences dialog + } + }); } } }); From 09494e5b17abf39ca87cf187c511150bc9d0fe4c Mon Sep 17 00:00:00 2001 From: SiboVG Date: Fri, 7 Apr 2023 08:21:14 +0200 Subject: [PATCH 15/15] Also add warning dialog --- .../gui/dialogs/preferences/GeneralPreferencesPanel.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/swing/src/net/sf/openrocket/gui/dialogs/preferences/GeneralPreferencesPanel.java b/swing/src/net/sf/openrocket/gui/dialogs/preferences/GeneralPreferencesPanel.java index b06a282c3..fceb57731 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/preferences/GeneralPreferencesPanel.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/preferences/GeneralPreferencesPanel.java @@ -294,6 +294,10 @@ public class GeneralPreferencesPanel extends PreferencesPanel { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { + JOptionPane.showMessageDialog(parent, + trans.get("generalprefs.ImportWarning.msg"), + trans.get("generalprefs.ImportWarning.title"), + JOptionPane.WARNING_MESSAGE); PreferencesDialog.showPreferences(parent.getParentFrame()); // Refresh the preferences dialog } });