Merge pull request #2174 from SiboVG/exportPrefs

Add preferences exporting & importing
This commit is contained in:
Sibo Van Gool 2023-04-12 22:05:05 +02:00 committed by GitHub
commit 25240012aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 545 additions and 45 deletions

View File

@ -122,6 +122,7 @@ FileHelper.RASAERO_DESIGN_FILTER = RASAero designs (*.CDX1)
FileHelper.OPEN_ROCKET_COMPONENT_FILTER = OpenRocket presets (*.orc) FileHelper.OPEN_ROCKET_COMPONENT_FILTER = OpenRocket presets (*.orc)
FileHelper.PNG_FILTER = PNG image (*.png) FileHelper.PNG_FILTER = PNG image (*.png)
FileHelper.IMAGES = Image files FileHelper.IMAGES = Image files
FileHelper.XML_FILTER = XML files (*.xml)
! About Dialog ! About Dialog
@ -290,8 +291,12 @@ 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.lbl.RockSimWarning = Show warning when saving in RockSim format
pref.dlg.but.clearCachedPreferences = Reset all preferences pref.dlg.but.resetAllPreferences = Reset all preferences
pref.dlg.but.clearCachedPreferences.ttip = Reset all the preferences, including cached preferences (UI settings, recent files, etc.) 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.title = Reset preferences?
pref.dlg.clearCachedPreferences.message = Are you sure you want to reset all your preferences? pref.dlg.clearCachedPreferences.message = Are you sure you want to reset all your preferences?
@ -373,6 +378,18 @@ PreferencesDialog.lbl.languageEffect = The language will change the next time yo
generalprefs.lbl.language = Interface language generalprefs.lbl.language = Interface language
generalprefs.languages.default = System default generalprefs.languages.default = System default
generalprefs.lbl.languageEffect = The language will change the next time you start OpenRocket. 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
PreferencesImporter.chooser.title = Import a Preferences File
PreferencesOptionPanel.title = Export settings
PreferencesOptionPanel.checkbox.userDirectories = Export user directories
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 unchecked, window information (position, size\u2026) will not be exported.
! Welcome dialog ! Welcome dialog
welcome.dlg.title = Welcome to OpenRocket welcome.dlg.title = Welcome to OpenRocket

View File

@ -276,8 +276,8 @@ pref.dlg.tab.Simulation = محاكاة
pref.dlg.tab.Launch = إطلاق pref.dlg.tab.Launch = إطلاق
pref.dlg.tab.Miscellaneousoptions = الخيارات المتنوعة pref.dlg.tab.Miscellaneousoptions = الخيارات المتنوعة
pref.dlg.lbl.RockSimWarning = إظهار تحذير عند الحفظ بتنسيق روكسيم pref.dlg.lbl.RockSimWarning = إظهار تحذير عند الحفظ بتنسيق روكسيم
pref.dlg.but.clearCachedPreferences = إعادة تعيين كل التفضيلات pref.dlg.but.resetAllPreferences = إعادة تعيين كل التفضيلات
pref.dlg.but.clearCachedPreferences.ttip = (إعدادات واجهة المستخدم والملفات الحديثة وما إلى ذلك)إعادة تعيين جميع التفضيلات ، بما في ذلك التفضيلات المخزنة مؤقتًا pref.dlg.but.resetAllPreferences.ttip = (إعدادات واجهة المستخدم والملفات الحديثة وما إلى ذلك)إعادة تعيين جميع التفضيلات ، بما في ذلك التفضيلات المخزنة مؤقتًا
pref.dlg.clearCachedPreferences.title = هل تريد إعادة تعيين التفضيلات؟ pref.dlg.clearCachedPreferences.title = هل تريد إعادة تعيين التفضيلات؟
pref.dlg.clearCachedPreferences.message = هل أنت متأكد أنك تريد إعادة تعيين كل تفضيلاتك؟ pref.dlg.clearCachedPreferences.message = هل أنت متأكد أنك تريد إعادة تعيين كل تفضيلاتك؟

View File

@ -277,8 +277,8 @@ pref.dlg.tab.Simulation = Simulatie
pref.dlg.tab.Launch = Lanceer pref.dlg.tab.Launch = Lanceer
pref.dlg.tab.Miscellaneousoptions = Diverse opties pref.dlg.tab.Miscellaneousoptions = Diverse opties
pref.dlg.lbl.RockSimWarning = Toon waarschuwingen bij opslaan in RockSim-formaat pref.dlg.lbl.RockSimWarning = Toon waarschuwingen bij opslaan in RockSim-formaat
pref.dlg.but.clearCachedPreferences = Alle voorkeuren opnieuw instellen pref.dlg.but.resetAllPreferences = 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.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.title = Voorkeuren opnieuw instellen?
pref.dlg.clearCachedPreferences.message = Bent u zeker dat u al uw voorkeuren opnieuw wilt instellen? pref.dlg.clearCachedPreferences.message = Bent u zeker dat u al uw voorkeuren opnieuw wilt instellen?

View File

@ -53,7 +53,8 @@ public abstract class Preferences implements ChangeSource {
public static final String EXPORT_EVENT_COMMENTS = "ExportEventComments"; public static final String EXPORT_EVENT_COMMENTS = "ExportEventComments";
public static final String EXPORT_COMMENT_CHARACTER = "ExportCommentCharacter"; public static final String EXPORT_COMMENT_CHARACTER = "ExportCommentCharacter";
public static final String USER_LOCAL = "locale"; public static final String USER_LOCAL = "locale";
public static final String DEFAULT_DIRECTORY = "defaultDirectory";
public static final String PLOT_SHOW_POINTS = "ShowPlotPoints"; public static final String PLOT_SHOW_POINTS = "ShowPlotPoints";
private static final String IGNORE_WELCOME = "IgnoreWelcome"; private static final String IGNORE_WELCOME = "IgnoreWelcome";
@ -73,19 +74,21 @@ public abstract class Preferences implements ChangeSource {
public static final String MATCH_AFT_DIAMETER = "MatchAftDiameter"; public static final String MATCH_AFT_DIAMETER = "MatchAftDiameter";
// 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 = "AutoOpenLastDesign";
private static final String OPEN_LEFTMOST_DESIGN_TAB = "OPEN_LEFTMOST_DESIGN_TAB"; private static final String OPEN_LEFTMOST_DESIGN_TAB = "OpenLeftmostDesignTab";
private static final String SHOW_DISCARD_CONFIRMATION = "IgnoreDiscardEditingWarning"; private static final String SHOW_DISCARD_CONFIRMATION = "IgnoreDiscardEditingWarning";
private static final String SHOW_DISCARD_SIMULATION_CONFIRMATION = "IgnoreDiscardSimulationEditingWarning"; private static final String SHOW_DISCARD_SIMULATION_CONFIRMATION = "IgnoreDiscardSimulationEditingWarning";
public static final String MARKER_STYLE_ICON = "MARKER_STYLE_ICON"; public static final String MARKER_STYLE_ICON = "MarkerStyleIcon";
private static final String SHOW_MARKERS = "SHOW_MARKERS"; private static final String SHOW_MARKERS = "ShowMarkers";
private static final String SHOW_ROCKSIM_FORMAT_WARNING = "SHOW_ROCKSIM_FORMAT_WARNING"; 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 //Preferences related to 3D graphics
public static final String OPENGL_ENABLED = "OpenGL_Is_Enabled"; public static final String OPENGL_ENABLED = "OpenGLIsEnabled";
public static final String OPENGL_ENABLE_AA = "OpenGL_Antialiasing_Is_Enabled"; public static final String OPENGL_ENABLE_AA = "OpenGLAntialiasingIsEnabled";
public static final String OPENGL_USE_FBO = "OpenGL_Use_FBO"; public static final String OPENGL_USE_FBO = "OpenGLUseFBO";
public static final String ROCKET_INFO_FONT_SIZE = "RocketInfoFontSize"; public static final String ROCKET_INFO_FONT_SIZE = "RocketInfoFontSize";
@ -232,7 +235,23 @@ public abstract class Preferences implements ChangeSource {
public final void setShowRockSimFormatWarning(boolean check) { public final void setShowRockSimFormatWarning(boolean check) {
this.putBoolean(SHOW_ROCKSIM_FORMAT_WARNING, 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 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() { 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);
} }

View File

@ -0,0 +1,65 @@
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();
private final JCheckBox exportUserDirectories;
private final JCheckBox exportWindowInfo;
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")));
// Export user directories
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");
// Export window information (position, size...)
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");
}
public boolean isIgnoreUserDirectories() {
return !exportUserDirectories.isSelected();
}
public boolean isIgnoreWindowInformation() {
return !exportWindowInfo.isSelected();
}
}

View File

@ -303,6 +303,7 @@ public class FreeformFinSetConfig extends FinSetConfig {
} }
FreeformFinSetConfig.writeCSVFile(table, selectedFile); 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); trans.get("CustomFinImport.error.title"), JOptionPane.ERROR_MESSAGE);
} finally { } finally {
document.stopUndo(); document.stopUndo();
((SwingPreferences) Application.getPreferences()).setDefaultDirectory(chooser.getCurrentDirectory());
} }
} }
} }

View File

@ -18,6 +18,7 @@ import javax.swing.JScrollPane;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.filechooser.FileNameExtensionFilter;
import net.sf.openrocket.gui.util.SwingPreferences;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; 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."); log.info(Markers.USER_MARKER, "Error opening document to import expressions from.");
} }
updateExpressions(); updateExpressions();
((SwingPreferences) Application.getPreferences()).setDefaultDirectory(fc.getCurrentDirectory());
} }
} }
}); });

View File

@ -43,6 +43,7 @@ public abstract class DecalNotFoundDialog {
if (resultFileChooser == JFileChooser.APPROVE_OPTION) { if (resultFileChooser == JFileChooser.APPROVE_OPTION) {
File file = chooser.getSelectedFile(); File file = chooser.getSelectedFile();
decex.getDecal().setDecalFile(file); decex.getDecal().setDecalFile(file);
((SwingPreferences) Application.getPreferences()).setDefaultDirectory(chooser.getCurrentDirectory());
} }
} }
return (resultYesNo == JOptionPane.YES_OPTION) && (resultFileChooser == JFileChooser.APPROVE_OPTION); return (resultYesNo == JOptionPane.YES_OPTION) && (resultFileChooser == JFileChooser.APPROVE_OPTION);

View File

@ -20,6 +20,7 @@ import javax.swing.event.ChangeListener;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.gui.util.GUIUtil; import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.gui.util.SwingPreferences;
import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.startup.Application; import net.sf.openrocket.startup.Application;
import net.sf.openrocket.gui.widgets.SelectColorButton; import net.sf.openrocket.gui.widgets.SelectColorButton;
@ -75,6 +76,7 @@ public class EditDecalDialog extends JDialog {
int action = fc.showOpenDialog(owner); int action = fc.showOpenDialog(owner);
if (action == JFileChooser.APPROVE_OPTION) { if (action == JFileChooser.APPROVE_OPTION) {
commandText.setText(fc.getSelectedFile().getAbsolutePath()); 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); int action = fc.showOpenDialog(owner);
if (action == JFileChooser.APPROVE_OPTION) { if (action == JFileChooser.APPROVE_OPTION) {
commandText.setText(fc.getSelectedFile().getAbsolutePath()); commandText.setText(fc.getSelectedFile().getAbsolutePath());
((SwingPreferences) Application.getPreferences()).setDefaultDirectory(fc.getCurrentDirectory());
} }
} }

View File

@ -19,6 +19,7 @@ import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JProgressBar; import javax.swing.JProgressBar;
import javax.swing.JTextField; import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.Timer; import javax.swing.Timer;
import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener; import javax.swing.event.DocumentListener;
@ -35,8 +36,11 @@ import net.sf.openrocket.gui.dialogs.UpdateInfoDialog;
import net.sf.openrocket.gui.util.GUIUtil; import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.gui.util.SimpleFileFilter; 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.gui.util.PreferencesExporter;
import net.sf.openrocket.gui.util.PreferencesImporter;
import net.sf.openrocket.l10n.L10N; import net.sf.openrocket.l10n.L10N;
import net.sf.openrocket.logging.Markers; import net.sf.openrocket.logging.Markers;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.startup.Preferences; import net.sf.openrocket.startup.Preferences;
import net.sf.openrocket.util.BuildProperties; import net.sf.openrocket.util.BuildProperties;
import net.sf.openrocket.util.Named; import net.sf.openrocket.util.Named;
@ -46,7 +50,7 @@ import net.sf.openrocket.gui.widgets.SelectColorButton;
@SuppressWarnings("serial") @SuppressWarnings("serial")
public class GeneralPreferencesPanel extends PreferencesPanel { public class GeneralPreferencesPanel extends PreferencesPanel {
public GeneralPreferencesPanel(JDialog parent) { public GeneralPreferencesPanel(PreferencesDialog parent) {
super(parent, new MigLayout("fillx, ins 30lp n n n")); super(parent, new MigLayout("fillx, ins 30lp n n n"));
@ -240,21 +244,69 @@ public class GeneralPreferencesPanel extends PreferencesPanel {
}); });
this.add(rocksimWarningDialogBox,"spanx, wrap"); this.add(rocksimWarningDialogBox,"spanx, wrap");
//// Clear cached preferences // Preference buttons
final JButton clearCachedPreferences = new SelectColorButton(trans.get("pref.dlg.but.clearCachedPreferences")); JPanel buttonPanel = new JPanel(new MigLayout("fillx, ins 0"));
clearCachedPreferences.setToolTipText(trans.get("pref.dlg.but.clearCachedPreferences.ttip"));
clearCachedPreferences.addActionListener(new ActionListener() { //// 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) {
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);
//// 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 @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
int resultYesNo = JOptionPane.showConfirmDialog(parent, trans.get("pref.dlg.clearCachedPreferences.message"), int resultYesNo = JOptionPane.showConfirmDialog(parent, trans.get("pref.dlg.clearCachedPreferences.message"),
trans.get("pref.dlg.clearCachedPreferences.title"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); trans.get("pref.dlg.clearCachedPreferences.title"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
if (resultYesNo == JOptionPane.YES_OPTION) { if (resultYesNo == JOptionPane.YES_OPTION) {
preferences.clearPreferences(); preferences.clearPreferences();
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
}
});
} }
} }
}); });
this.add(clearCachedPreferences, "spanx, pushy, bottom, wrap"); buttonPanel.add(resetAllPreferences, "pushx, right, wrap");
this.add(buttonPanel, "spanx, growx, pushy, bottom, wrap");
} }

View File

@ -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;
import net.sf.openrocket.gui.components.StyledLabel.Style; import net.sf.openrocket.gui.components.StyledLabel.Style;
import net.sf.openrocket.gui.util.GUIUtil; 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.startup.Preferences;
import net.sf.openrocket.gui.widgets.SelectColorButton; import net.sf.openrocket.gui.widgets.SelectColorButton;
@ -119,6 +121,7 @@ public class GraphicsPreferencesPanel extends PreferencesPanel {
String commandLine = fc.getSelectedFile().getAbsolutePath(); String commandLine = fc.getSelectedFile().getAbsolutePath();
commandText.setText(commandLine); commandText.setText(commandLine);
preferences.setDecalEditorPreference(false, commandLine); preferences.setDecalEditorPreference(false, commandLine);
((SwingPreferences) Application.getPreferences()).setDefaultDirectory(fc.getCurrentDirectory());
} }
} }

View File

@ -33,11 +33,15 @@ public class PreferencesDialog extends JDialog {
private final SwingPreferences preferences = (SwingPreferences) Application private final SwingPreferences preferences = (SwingPreferences) Application
.getPreferences(); .getPreferences();
private BasicFrame parentFrame;
private PreferencesDialog(BasicFrame parent) { private PreferencesDialog(BasicFrame parent) {
// // Preferences // // Preferences
super(parent, trans.get("pref.dlg.title.Preferences"), super(parent, trans.get("pref.dlg.title.Preferences"),
Dialog.ModalityType.APPLICATION_MODAL); Dialog.ModalityType.APPLICATION_MODAL);
this.parentFrame = parent;
JPanel panel = new JPanel(new MigLayout("fill, gap unrel", "[grow]", JPanel panel = new JPanel(new MigLayout("fill, gap unrel", "[grow]",
"[grow][]")); "[grow][]"));
@ -105,6 +109,10 @@ public class PreferencesDialog extends JDialog {
GUIUtil.setDisposableDialogOptions(this, close); GUIUtil.setDisposableDialogOptions(this, close);
} }
public BasicFrame getParentFrame() {
return parentFrame;
}
// ////// Singleton implementation //////// // ////// Singleton implementation ////////
private static PreferencesDialog dialog = null; private static PreferencesDialog dialog = null;

View File

@ -90,6 +90,7 @@ public class ExportDecalDialog extends JDialog {
export(selectedDecal, selectedFile); export(selectedDecal, selectedFile);
// If the user doesn't confirm over write, then leave this dialog open. // If the user doesn't confirm over write, then leave this dialog open.
ExportDecalDialog.this.dispose(); ExportDecalDialog.this.dispose();
((SwingPreferences) Application.getPreferences()).setDefaultDirectory(chooser.getCurrentDirectory());
} }
} }
} }

View File

@ -44,6 +44,7 @@ import javax.swing.border.EmptyBorder;
import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.text.JTextComponent; import javax.swing.text.JTextComponent;
import net.sf.openrocket.gui.util.SwingPreferences;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -389,6 +390,7 @@ public class PresetEditorDialog extends JDialog implements ItemListener {
File file = imageChooser.getSelectedFile(); File file = imageChooser.getSelectedFile();
ncImage = scaleImage(new ImageIcon(file.getAbsolutePath()).getImage(), 155); ncImage = scaleImage(new ImageIcon(file.getAbsolutePath()).getImage(), 155);
ncImageBtn.setIcon(ncImage); ncImageBtn.setIcon(ncImage);
((SwingPreferences) Application.getPreferences()).setDefaultDirectory(imageChooser.getCurrentDirectory());
} }
} }
}); });
@ -1318,6 +1320,7 @@ public class PresetEditorDialog extends JDialog implements ItemListener {
*/ */
private JFileChooser createImageChooser() { private JFileChooser createImageChooser() {
final JFileChooser chooser = new JFileChooser(); final JFileChooser chooser = new JFileChooser();
chooser.setCurrentDirectory(((SwingPreferences) Application.getPreferences()).getDefaultDirectory());
ImagePreviewPanel preview = new ImagePreviewPanel(); ImagePreviewPanel preview = new ImagePreviewPanel();
chooser.setAccessory(preview); chooser.setAccessory(preview);
chooser.addPropertyChangeListener(preview); chooser.addPropertyChangeListener(preview);

View File

@ -1,11 +1,6 @@
package net.sf.openrocket.gui.util; 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.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.l10n.Translator;
import net.sf.openrocket.logging.Markers; import net.sf.openrocket.logging.Markers;
import net.sf.openrocket.startup.Application; import net.sf.openrocket.startup.Application;

View File

@ -64,6 +64,10 @@ public final class FileHelper {
public static final FileFilter PNG_FILTER = public static final FileFilter PNG_FILTER =
new SimpleFileFilter(trans.get("FileHelper.PNG_FILTER"), ".png"); 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");

View File

@ -0,0 +1,202 @@
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.ArrayList;
import java.util.List;
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 List<String> keysToIgnore = new ArrayList<>(); // Preference keys to ignore when exporting user directories (= keys that export user directories)
private static final List<String> prefixKeysToIgnore = new ArrayList<>(); // Preference keys to ignore when exporting user directories (= keys that start with these prefixes), e.g.
private static final List<String> nodesToIgnore = new ArrayList<>(); // Preferences nodes that should not be exported
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());
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.
if (SystemInfo.getPlatform() == SystemInfo.Platform.MAC_OS) {
Dimension currentSize = chooser.getPreferredSize();
Dimension newSize = new Dimension((int) (1.35 * currentSize.width), (int) (1.2 * currentSize.height));
chooser.setPreferredSize(newSize);
}
//// Ensures No Problems When Choosing File
if (chooser.showSaveDialog(parent) != JFileChooser.APPROVE_OPTION) {
log.info("Cancelled export of preferences.");
return false;
}
((SwingPreferences) prefs).setDefaultDirectory(chooser.getCurrentDirectory());
File file = chooser.getSelectedFile();
if (file == null) {
log.info("No file selected to export preferences to.");
return false;
}
final File newFile = FileHelper.forceExtension(file, "xml");
if (!FileHelper.confirmWrite(newFile, parent)) {
log.info("Cancelled export of preferences.");
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
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());
}
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();
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, nodesToIgnore, keysToIgnore, 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,
List<String> nodesToIgnore, List<String> keysToIgnore, List<String> prefixKeysToIgnore) throws BackingStoreException {
for (String key : src.keys()) {
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, nodesToIgnore, keysToIgnore, prefixKeysToIgnore);
}
}
}

View File

@ -0,0 +1,45 @@
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)) {
Preferences.importPreferences(fis);
log.info("Preferences imported successfully.");
} catch (IOException | InvalidPreferencesFormatException e) {
log.warn("Error while importing preferences: " + e.getMessage());
}
return true;
}
}

View File

@ -38,7 +38,11 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences {
private static final Logger log = LoggerFactory.getLogger(SwingPreferences.class); private static final Logger log = LoggerFactory.getLogger(SwingPreferences.class);
private static final String SPLIT_CHARACTER = "|"; private static final String SPLIT_CHARACTER = "|";
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<Locale> SUPPORTED_LOCALES; private static final List<Locale> SUPPORTED_LOCALES;
static { static {
@ -88,10 +92,16 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences {
PREFNODE = root.node(NODENAME); PREFNODE = root.node(NODENAME);
} }
public String getNodename() {
return NODENAME;
}
////////////////////// //////////////////////
public Preferences getPreferences() {
return PREFNODE;
}
public void clearPreferences() { public void clearPreferences() {
try { try {
@ -114,7 +124,22 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences {
private void storeVersion() { private void storeVersion() {
PREFNODE.put("OpenRocketVersion", BuildProperties.getVersion()); 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. * Return a string preference.
* *
@ -124,12 +149,28 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences {
*/ */
@Override @Override
public String getString(String key, String def) { 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); return PREFNODE.get(key, def);
} }
@Override @Override
public String getString(String directory, String key, String defaultValue) { public String getString(String directory, String key, String defaultValue) {
Preferences p = PREFNODE.node(directory); 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); return p.get(key, defaultValue);
} }
@ -169,6 +210,16 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences {
*/ */
@Override @Override
public boolean getBoolean(String key, boolean def) { 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); return PREFNODE.getBoolean(key, def);
} }
@ -183,9 +234,17 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences {
PREFNODE.putBoolean(key, value); PREFNODE.putBoolean(key, value);
storeVersion(); storeVersion();
} }
@Override @Override
public int getInt(String key, int defaultValue) { 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); return PREFNODE.getInt(key, defaultValue);
} }
@ -194,9 +253,17 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences {
PREFNODE.putInt(key, value); PREFNODE.putInt(key, value);
storeVersion(); storeVersion();
} }
@Override @Override
public double getDouble(String key, double defaultValue) { 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); return PREFNODE.getDouble(key, defaultValue);
} }
@ -228,7 +295,7 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences {
} }
public File getDefaultDirectory() { public File getDefaultDirectory() {
String file = getString("defaultDirectory", null); String file = getString(net.sf.openrocket.startup.Preferences.DEFAULT_DIRECTORY, null);
if (file == null) if (file == null)
return null; return null;
return new File(file); return new File(file);
@ -241,7 +308,7 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences {
} else { } else {
d = dir.getAbsolutePath(); d = dir.getAbsolutePath();
} }
putString("defaultDirectory", d); putString(net.sf.openrocket.startup.Preferences.DEFAULT_DIRECTORY, d);
storeVersion(); storeVersion();
} }
@ -262,13 +329,22 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences {
return compdir; 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) { public void setUpdatePlatform(UpdatePlatform platform) {
if (platform == null) return; 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() { public UpdatePlatform getUpdatePlatform() {
String p = getString("UpdatePlatform", SystemInfo.getPlatform().name()); String p = getString(UPDATE_PLATFORM, SystemInfo.getPlatform().name());
if (p == null) return null; if (p == null) return null;
return UpdatePlatform.valueOf(p); return UpdatePlatform.valueOf(p);
} }
@ -372,7 +448,7 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences {
public Point getWindowPosition(Class<?> c) { public Point getWindowPosition(Class<?> c) {
int x, y; 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) if (pref == null)
return null; return null;
@ -390,7 +466,7 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences {
} }
public void setWindowPosition(Class<?> c, Point p) { 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(); storeVersion();
} }
@ -399,7 +475,7 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences {
public Dimension getWindowSize(Class<?> c) { public Dimension getWindowSize(Class<?> c) {
int x, y; 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) if (pref == null)
return null; return null;
@ -418,22 +494,22 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences {
public boolean isWindowMaximized(Class<?> c) { 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); return "max".equals(pref);
} }
public void setWindowSize(Class<?> c, Dimension d) { 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(); storeVersion();
} }
public void setWindowMaximized(Class<?> c) { public void setWindowMaximized(Class<?> c) {
PREFNODE.node("windows").put("size." + c.getCanonicalName(), "max"); PREFNODE.node(NODE_WINDOWS).put("size." + c.getCanonicalName(), "max");
storeVersion(); storeVersion();
} }
public Integer getTableColumnWidth(String keyName, int columnIdx) { public Integer getTableColumnWidth(String keyName, int columnIdx) {
String pref = PREFNODE.node("tables").get( String pref = PREFNODE.node(NODE_TABLES).get(
"cw." + keyName + "." + columnIdx, null); "cw." + keyName + "." + columnIdx, null);
if (pref == null) if (pref == null)
return null; return null;
@ -451,7 +527,7 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences {
} }
public void setTableColumnWidth(String keyName, int columnIdx, Integer width) { public void setTableColumnWidth(String keyName, int columnIdx, Integer width) {
PREFNODE.node("tables").put( PREFNODE.node(NODE_TABLES).put(
"cw." + keyName + "." + columnIdx, width.toString()); "cw." + keyName + "." + columnIdx, width.toString());
storeVersion(); storeVersion();
} }

View File

@ -342,6 +342,8 @@ public class ComponentPresetEditor extends JPanel implements PresetResultListene
log.info(Markers.USER_MARKER, "User decided not to open, option=" + option); log.info(Markers.USER_MARKER, "User decided not to open, option=" + option);
return false; return false;
} }
((SwingPreferences) Application.getPreferences()).setDefaultDirectory(chooser.getCurrentDirectory());
File file = chooser.getSelectedFile(); File file = chooser.getSelectedFile();
try { try {