[#2226] Add Ok/Cancel buttons in preference dialog
This commit is contained in:
parent
80558fbf43
commit
5af6827e92
@ -380,6 +380,8 @@ pref.dlg.DescriptionArea.Adddirectories = Add directories, RASP motor files (*.e
|
||||
PreferencesDialog.lbl.language = Interface language:
|
||||
PreferencesDialog.languages.default = System default
|
||||
PreferencesDialog.lbl.languageEffect = The language will change the next time you start OpenRocket.
|
||||
PreferencesDialog.CancelOperation.title = Discard Preference Changes
|
||||
PreferencesDialog.CancelOperation.msg.discardChanges = <html>Are you sure you want to <b>discard the preference changes</b>?</html>
|
||||
|
||||
generalprefs.lbl.language = Interface language
|
||||
generalprefs.languages.default = System default
|
||||
|
@ -79,6 +79,7 @@ public abstract class Preferences implements ChangeSource {
|
||||
private static final String OPEN_LEFTMOST_DESIGN_TAB = "OpenLeftmostDesignTab";
|
||||
private static final String SHOW_DISCARD_CONFIRMATION = "IgnoreDiscardEditingWarning";
|
||||
private static final String SHOW_DISCARD_SIMULATION_CONFIRMATION = "IgnoreDiscardSimulationEditingWarning";
|
||||
private static final String SHOW_DISCARD_PREFERENCES_CONFIRMATION = "IgnoreDiscardPreferencesWarning";
|
||||
public static final String MARKER_STYLE_ICON = "MARKER_STYLE_ICON";
|
||||
private static final String SHOW_MARKERS = "SHOW_MARKERS";
|
||||
private static final String SHOW_RASAERO_FORMAT_WARNING = "SHOW_RASAERO_FORMAT_WARNING";
|
||||
@ -582,6 +583,22 @@ public abstract class Preferences implements ChangeSource {
|
||||
this.putBoolean(SHOW_DISCARD_SIMULATION_CONFIRMATION, enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Answer if a confirmation dialog should be shown when canceling preferences changes.
|
||||
*
|
||||
* @return true if the confirmation dialog should be shown.
|
||||
*/
|
||||
public final boolean isShowDiscardPreferencesConfirmation() {
|
||||
return this.getBoolean(SHOW_DISCARD_PREFERENCES_CONFIRMATION, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/Disable showing a confirmation warning when canceling preferences changes.
|
||||
*/
|
||||
public final void setShowDiscardPreferencesConfirmation(boolean enabled) {
|
||||
this.putBoolean(SHOW_DISCARD_PREFERENCES_CONFIRMATION, enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Answer if the always open leftmost tab is enabled.
|
||||
*
|
||||
|
@ -1,21 +1,31 @@
|
||||
package net.sf.openrocket.gui.dialogs.preferences;
|
||||
|
||||
import java.awt.Dialog;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.prefs.BackingStoreException;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTabbedPane;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.gui.main.BasicFrame;
|
||||
import net.sf.openrocket.gui.util.GUIUtil;
|
||||
import net.sf.openrocket.gui.util.PreferencesExporter;
|
||||
import net.sf.openrocket.gui.util.PreferencesImporter;
|
||||
import net.sf.openrocket.gui.util.SwingPreferences;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
@ -35,6 +45,9 @@ public class PreferencesDialog extends JDialog {
|
||||
|
||||
private BasicFrame parentFrame;
|
||||
|
||||
private boolean storePreferences = true;
|
||||
private File initPrefsFile = null;
|
||||
|
||||
private PreferencesDialog(BasicFrame parent) {
|
||||
// // Preferences
|
||||
super(parent, trans.get("pref.dlg.title.Preferences"),
|
||||
@ -42,6 +55,9 @@ public class PreferencesDialog extends JDialog {
|
||||
|
||||
this.parentFrame = parent;
|
||||
|
||||
// First store the initial preferences
|
||||
initPrefsFile = storeInitPreferences();
|
||||
|
||||
JPanel panel = new JPanel(new MigLayout("fill, gap unrel", "[grow]",
|
||||
"[grow][]"));
|
||||
|
||||
@ -78,16 +94,42 @@ public class PreferencesDialog extends JDialog {
|
||||
// tabbedPane.addTab(trans.get("pref.dlg.tab.Colors"),
|
||||
// new DisplayPreferencesPanel());
|
||||
|
||||
// Close button
|
||||
JButton close = new SelectColorButton(trans.get("dlg.but.close"));
|
||||
close.addActionListener(new ActionListener() {
|
||||
|
||||
//// Cancel button
|
||||
JButton cancelButton = new SelectColorButton(trans.get("dlg.but.cancel"));
|
||||
cancelButton.setToolTipText(trans.get("SimulationEditDialog.btn.Cancel.ttip"));
|
||||
cancelButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
PreferencesDialog.this.setVisible(false);
|
||||
PreferencesDialog.this.dispose();
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
// Apply the cancel operation if set to auto discard in preferences
|
||||
if (!preferences.isShowDiscardPreferencesConfirmation()) {
|
||||
closeDialog(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Yes/No dialog: Are you sure you want to discard your changes?
|
||||
JPanel msg = createCancelOperationContent();
|
||||
int resultYesNo = JOptionPane.showConfirmDialog(PreferencesDialog.this, msg,
|
||||
trans.get("PreferencesDialog.CancelOperation.title"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
|
||||
if (resultYesNo == JOptionPane.YES_OPTION) {
|
||||
closeDialog(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
panel.add(close, "span, right, tag close");
|
||||
panel.add(cancelButton, "span, split 2, right, tag cancel");
|
||||
|
||||
//// Ok button
|
||||
JButton okButton = new SelectColorButton(trans.get("dlg.but.ok"));
|
||||
okButton.setToolTipText(trans.get("SimulationEditDialog.btn.OK.ttip"));
|
||||
okButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
closeDialog(true);
|
||||
}
|
||||
});
|
||||
panel.add(okButton, "tag ok");
|
||||
|
||||
|
||||
|
||||
this.setContentPane(panel);
|
||||
pack();
|
||||
@ -96,7 +138,25 @@ public class PreferencesDialog extends JDialog {
|
||||
this.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosed(WindowEvent e) {
|
||||
// We don't want to lose the preference for the confirmation dialog
|
||||
boolean isShowDiscardConfirmation = preferences.isShowDiscardPreferencesConfirmation();
|
||||
|
||||
// Reload initial preferences
|
||||
if (!storePreferences) {
|
||||
loadInitPreferences();
|
||||
}
|
||||
|
||||
// Store the preference for showing the confirmation dialog
|
||||
preferences.setShowDiscardPreferencesConfirmation(isShowDiscardConfirmation);
|
||||
|
||||
// Delete the init prefs
|
||||
if (initPrefsFile != null) {
|
||||
initPrefsFile.delete();
|
||||
}
|
||||
|
||||
// Ensure the units are properly stored
|
||||
preferences.storeDefaultUnits();
|
||||
|
||||
// Make sure unit change applies to the rocket figure
|
||||
if (parent != null) {
|
||||
parent.getRocketPanel().updateExtras();
|
||||
@ -106,13 +166,72 @@ public class PreferencesDialog extends JDialog {
|
||||
}
|
||||
});
|
||||
|
||||
GUIUtil.setDisposableDialogOptions(this, close);
|
||||
GUIUtil.setDisposableDialogOptions(this, okButton);
|
||||
}
|
||||
|
||||
public BasicFrame getParentFrame() {
|
||||
return parentFrame;
|
||||
}
|
||||
|
||||
private void closeDialog(boolean storeChanges) {
|
||||
storePreferences = storeChanges;
|
||||
PreferencesDialog.this.setVisible(false);
|
||||
PreferencesDialog.this.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the intial preferences in a temporary file, and return that file.
|
||||
* @return the file containing the initial preferences, or null if something went wrong
|
||||
*/
|
||||
private File storeInitPreferences() {
|
||||
try {
|
||||
File outputFile = Files.createTempFile("ORInitPrefs_" + System.currentTimeMillis(), ".xml").toFile();
|
||||
try (FileOutputStream outputFos = new FileOutputStream(outputFile)) {
|
||||
PreferencesExporter.exportPreferencesToFile(preferences.getPreferences(), outputFos, false);
|
||||
log.debug("Initial preferences stored in temporary file: " + outputFile.getAbsolutePath());
|
||||
} catch (BackingStoreException e) {
|
||||
log.error("Could not store initial preferences", e);
|
||||
return null;
|
||||
}
|
||||
return outputFile;
|
||||
} catch (IOException e) {
|
||||
log.error("Could not create temporary preferences file", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the initial stored preferences back (restores preferences).
|
||||
*/
|
||||
private void loadInitPreferences() {
|
||||
if (initPrefsFile == null) {
|
||||
return;
|
||||
}
|
||||
PreferencesImporter.importPreferences(initPrefsFile);
|
||||
}
|
||||
|
||||
private JPanel createCancelOperationContent() {
|
||||
JPanel panel = new JPanel(new MigLayout());
|
||||
String msg = trans.get("PreferencesDialog.CancelOperation.msg.discardChanges");
|
||||
JLabel msgLabel = new JLabel(msg);
|
||||
JCheckBox dontAskAgain = new JCheckBox(trans.get("SimulationEditDialog.CancelOperation.checkbox.dontAskAgain"));
|
||||
dontAskAgain.setSelected(false);
|
||||
dontAskAgain.addItemListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
if (e.getStateChange() == ItemEvent.SELECTED) {
|
||||
preferences.setShowDiscardPreferencesConfirmation(false);
|
||||
}
|
||||
// Unselected state should be not be possible and thus not be handled
|
||||
}
|
||||
});
|
||||
|
||||
panel.add(msgLabel, "left, wrap");
|
||||
panel.add(dontAskAgain, "left, gaptop para");
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
// ////// Singleton implementation ////////
|
||||
|
||||
private static PreferencesDialog dialog = null;
|
||||
|
@ -121,25 +121,32 @@ public abstract class PreferencesExporter {
|
||||
keysToIgnore.add(SwingPreferences.UPDATE_PLATFORM); // Don't export platform-specific settings
|
||||
}
|
||||
|
||||
private static void exportFilteredPreferences(Preferences preferences, FileOutputStream fos) throws BackingStoreException, IOException {
|
||||
public static void exportPreferencesToFile(Preferences preferences, FileOutputStream fos, boolean filterPreferences)
|
||||
throws BackingStoreException, IOException {
|
||||
// If no filtering is required, just export the preferences
|
||||
if (!filterPreferences) {
|
||||
preferences.exportSubtree(fos);
|
||||
return;
|
||||
}
|
||||
|
||||
// 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();
|
||||
String filteredPrefsNodeName = originalNodeName + "-filtered";
|
||||
if (root.nodeExists(filteredPrefsNodeName)) {
|
||||
root.node(filteredPrefsNodeName).removeNode();
|
||||
}
|
||||
Preferences tempPrefs = root.node(nodeName);
|
||||
Preferences filteredPrefs = root.node(filteredPrefsNodeName);
|
||||
|
||||
// Fill in all parameters to the temporary preferences, except for user directories
|
||||
copyFilteredPreferences(preferences, tempPrefs, nodesToIgnore, keysToIgnore, prefixKeysToIgnore);
|
||||
copyFilteredPreferences(preferences, filteredPrefs, nodesToIgnore, keysToIgnore, prefixKeysToIgnore);
|
||||
|
||||
// Export the filtered preferences
|
||||
try {
|
||||
// Export the filtered preferences to a temporary file
|
||||
Path tempFile = Files.createTempFile("ORprefs_" + System.currentTimeMillis(), ".xml");
|
||||
Path tempFile = Files.createTempFile("ORPrefs_" + System.currentTimeMillis(), ".xml");
|
||||
try (FileOutputStream tempFos = new FileOutputStream(tempFile.toFile())) {
|
||||
tempPrefs.exportSubtree(tempFos);
|
||||
filteredPrefs.exportSubtree(tempFos);
|
||||
}
|
||||
|
||||
// Read and parse the temporary file
|
||||
@ -149,11 +156,11 @@ public abstract class PreferencesExporter {
|
||||
doc = factory.newDocumentBuilder().parse(tempFis);
|
||||
}
|
||||
|
||||
// Find and rename the node
|
||||
// Find and rename the filtered prefs 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)) {
|
||||
if (element.getAttribute("name").equals(filteredPrefsNodeName)) {
|
||||
element.setAttribute("name", ((SwingPreferences) prefs).getNodename());
|
||||
break;
|
||||
}
|
||||
@ -176,10 +183,14 @@ public abstract class PreferencesExporter {
|
||||
} catch (ParserConfigurationException | TransformerException | SAXException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
root.node(nodeName).removeNode();
|
||||
root.node(filteredPrefsNodeName).removeNode();
|
||||
}
|
||||
}
|
||||
|
||||
private static void exportFilteredPreferences(Preferences preferences, FileOutputStream fos) throws BackingStoreException, IOException {
|
||||
exportPreferencesToFile(preferences, fos, true);
|
||||
}
|
||||
|
||||
private static void copyFilteredPreferences(Preferences src, Preferences dest,
|
||||
List<String> nodesToIgnore, List<String> keysToIgnore, List<String> prefixKeysToIgnore) throws BackingStoreException {
|
||||
for (String key : src.keys()) {
|
||||
|
@ -17,6 +17,11 @@ public abstract class PreferencesImporter {
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
private static final Logger log = LoggerFactory.getLogger(PreferencesImporter.class);
|
||||
|
||||
/**
|
||||
* Import the preferences by first showing a file chooser dialog to locate the preferences file.
|
||||
* @param parent The parent window for the file chooser dialog.
|
||||
* @return true if the preferences were imported successfully, false otherwise.
|
||||
*/
|
||||
public static boolean importPreferences(Window parent) {
|
||||
final JFileChooser chooser = new JFileChooser();
|
||||
chooser.setDialogTitle(trans.get("PreferencesImporter.chooser.title"));
|
||||
@ -33,13 +38,22 @@ public abstract class PreferencesImporter {
|
||||
((SwingPreferences) Application.getPreferences()).setDefaultDirectory(chooser.getCurrentDirectory());
|
||||
|
||||
File importFile = chooser.getSelectedFile();
|
||||
return importPreferences(importFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Import preferences from an XML file.
|
||||
* @param importFile The XML file to import preferences from.
|
||||
* @return true if the preferences were imported successfully, false otherwise.
|
||||
*/
|
||||
public static boolean importPreferences(File importFile) {
|
||||
try (FileInputStream fis = new FileInputStream(importFile)) {
|
||||
Preferences.importPreferences(fis);
|
||||
log.info("Preferences imported successfully.");
|
||||
return true;
|
||||
} catch (IOException | InvalidPreferencesFormatException e) {
|
||||
log.warn("Error while importing preferences: " + e.getMessage());
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user