From f8aef591d3edb274db4c33bd48d3e0ae1a90dd50 Mon Sep 17 00:00:00 2001 From: hneemann Date: Tue, 4 Apr 2017 14:54:38 +0200 Subject: [PATCH] consistent handling of overwrite confirmation dialog. --- .../digital/builder/ATF1502/CreateCHN.java | 4 +- .../builder/tt2/StartATF1502Fitter.java | 4 +- .../java/de/neemann/digital/gui/Main.java | 95 +++++--------- .../de/neemann/digital/gui/SaveAsHelper.java | 121 ++++++++++++++++++ .../digital/gui/components/EditorFactory.java | 15 +-- .../gui/components/data/DataSetDialog.java | 16 +-- .../gui/components/table/TableDialog.java | 51 ++------ src/main/resources/lang/lang_de.xml | 1 - src/main/resources/lang/lang_en.xml | 1 - 9 files changed, 176 insertions(+), 132 deletions(-) create mode 100644 src/main/java/de/neemann/digital/gui/SaveAsHelper.java diff --git a/src/main/java/de/neemann/digital/builder/ATF1502/CreateCHN.java b/src/main/java/de/neemann/digital/builder/ATF1502/CreateCHN.java index 62ea1c7b0..0f8b21d77 100644 --- a/src/main/java/de/neemann/digital/builder/ATF1502/CreateCHN.java +++ b/src/main/java/de/neemann/digital/builder/ATF1502/CreateCHN.java @@ -1,7 +1,7 @@ package de.neemann.digital.builder.ATF1502; import de.neemann.digital.builder.ExpressionToFileExporter; -import de.neemann.digital.gui.Main; +import de.neemann.digital.gui.SaveAsHelper; import java.io.*; @@ -25,7 +25,7 @@ public class CreateCHN implements ExpressionToFileExporter.PostProcess { @Override public File execute(File file) throws IOException { - File chnFile = Main.checkSuffix(file, "chn"); + File chnFile = SaveAsHelper.checkSuffix(file, "chn"); try (Writer chn = new OutputStreamWriter(new FileOutputStream(chnFile), "UTF-8")) { chn.write("1 4 1 0 \r\n" diff --git a/src/main/java/de/neemann/digital/builder/tt2/StartATF1502Fitter.java b/src/main/java/de/neemann/digital/builder/tt2/StartATF1502Fitter.java index 82ef0956a..542566870 100644 --- a/src/main/java/de/neemann/digital/builder/tt2/StartATF1502Fitter.java +++ b/src/main/java/de/neemann/digital/builder/tt2/StartATF1502Fitter.java @@ -2,7 +2,7 @@ package de.neemann.digital.builder.tt2; import de.neemann.digital.builder.ExpressionToFileExporter; import de.neemann.digital.core.element.Keys; -import de.neemann.digital.gui.Main; +import de.neemann.digital.gui.SaveAsHelper; import de.neemann.digital.gui.Settings; import de.neemann.digital.lang.Lang; @@ -56,7 +56,7 @@ public class StartATF1502Fitter implements ExpressionToFileExporter.PostProcess SwingUtilities.invokeLater(() -> JOptionPane.showMessageDialog(parent, message, Lang.get("msg_fitterResult"), JOptionPane.INFORMATION_MESSAGE)); - return Main.checkSuffix(file, "jed"); + return SaveAsHelper.checkSuffix(file, "jed"); } catch (IOException e) { throw new IOException(Lang.get("err_errorRunningFitter"), e); } diff --git a/src/main/java/de/neemann/digital/gui/Main.java b/src/main/java/de/neemann/digital/gui/Main.java index 75af97f50..8b7567d6a 100644 --- a/src/main/java/de/neemann/digital/gui/Main.java +++ b/src/main/java/de/neemann/digital/gui/Main.java @@ -409,46 +409,28 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave, E if (lastFilename == null && library.getRootFilePath() != null) fc.setCurrentDirectory(library.getRootFilePath()); - boolean repeat; - do { - repeat = false; - if (fc.showSaveDialog(Main.this) == JFileChooser.APPROVE_OPTION) { - - final File selectedFile = fc.getSelectedFile(); - - if (selectedFile.exists()) { - Object[] options = {Lang.get("btn_overwrite"), Lang.get("btn_newName")}; - int res = JOptionPane.showOptionDialog(Main.this, - Lang.get("msg_fileExists", selectedFile.getName()), - Lang.get("msg_warning"), - JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, - null, options, options[0]); - if (res == 1) { - repeat = true; - continue; + final SaveAsHelper saveAsHelper = new SaveAsHelper(Main.this, fc, "dig"); + saveAsHelper.checkOverwrite( + file -> { + if (library.isFileAccessible(file)) + saveFile(file, false); + else { + Object[] options = {Lang.get("btn_saveAnyway"), Lang.get("btn_newName"), Lang.get("cancel")}; + int res = JOptionPane.showOptionDialog(Main.this, + Lang.get("msg_fileNotAccessible"), + Lang.get("msg_warning"), + JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, + null, options, options[0]); + switch (res) { + case 0: + saveFile(file, true); + break; + case 1: + saveAsHelper.retryFileSelect(); + } } } - - if (library.isFileAccessible(selectedFile)) - saveFile(selectedFile, false); - else { - Object[] options = {Lang.get("btn_saveAnyway"), Lang.get("btn_newName"), Lang.get("cancel")}; - int res = JOptionPane.showOptionDialog(Main.this, - Lang.get("msg_fileNotAccessible"), - Lang.get("msg_warning"), - JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, - null, options, options[0]); - switch (res) { - case 0: - saveFile(selectedFile, true); - break; - case 1: - repeat = true; - break; - } - } - } - } while (repeat); + ); } }.setActive(allowAll); @@ -969,7 +951,6 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave, E } private void saveFile(File filename, boolean toPrefs) { - filename = checkSuffix(filename, "dig"); try { circuitComponent.getCircuit().save(filename); stoppedState.enter(); @@ -996,21 +977,6 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave, E } } - /** - * Adds the given suffix to the file - * - * @param filename filename - * @param suffix suffix - * @return the file name with the given suffix - */ - public static File checkSuffix(File filename, String suffix) { - String name = filename.getName(); - int p = name.lastIndexOf('.'); - if (p >= 0) - name = name.substring(0, p); - return new File(filename.getParentFile(), name + "." + suffix); - } - /** * @return the window position manager */ @@ -1076,23 +1042,20 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave, E public void actionPerformed(ActionEvent e) { JFileChooser fc = new JFileChooser(); if (filename != null) - fc.setSelectedFile(checkSuffix(filename, suffix)); + fc.setSelectedFile(SaveAsHelper.checkSuffix(filename, suffix)); if (lastExportDirectory != null) fc.setCurrentDirectory(lastExportDirectory); fc.addChoosableFileFilter(new FileNameExtensionFilter(name, suffix)); - if (fc.showSaveDialog(Main.this) == JFileChooser.APPROVE_OPTION) { - - lastExportDirectory = fc.getSelectedFile().getParentFile(); - - try (OutputStream out = new FileOutputStream(checkSuffix(fc.getSelectedFile(), suffix))) { - new Export(circuitComponent.getCircuit(), exportFactory).export(out); - - } catch (IOException e1) { - new ErrorMessage(Lang.get("msg_errorWritingFile")).addCause(e1).show(Main.this); - } - } + new SaveAsHelper(Main.this, fc, suffix).checkOverwrite( + file -> { + lastExportDirectory = file.getParentFile(); + try (OutputStream out = new FileOutputStream(file)) { + new Export(circuitComponent.getCircuit(), exportFactory).export(out); + } + } + ); } } diff --git a/src/main/java/de/neemann/digital/gui/SaveAsHelper.java b/src/main/java/de/neemann/digital/gui/SaveAsHelper.java new file mode 100644 index 000000000..107f8e41a --- /dev/null +++ b/src/main/java/de/neemann/digital/gui/SaveAsHelper.java @@ -0,0 +1,121 @@ +package de.neemann.digital.gui; + +import de.neemann.digital.lang.Lang; +import de.neemann.gui.ErrorMessage; + +import javax.swing.*; +import java.awt.*; +import java.io.File; +import java.io.IOException; + +/** + * Helper to handle the overwrite conformation + *

+ * Created by hneemann on 04.04.17. + */ +public final class SaveAsHelper { + private final Component parent; + private final JFileChooser fc; + private final String suffix; + private boolean repeat; + + /** + * Creates a new instance + * + * @param parent the parent + * @param fc the file chooser + */ + public SaveAsHelper(Component parent, JFileChooser fc) { + this(parent, fc, null); + } + + + /** + * Creates a new instance + * + * @param parent the parent + * @param fc the file chooser + * @param suffix the suffix to enforce + */ + public SaveAsHelper(Component parent, JFileChooser fc, String suffix) { + this.parent = parent; + this.fc = fc; + this.suffix = suffix; + } + + /** + * Uses the JFileChooser to select a file and checks, if the file exists. + * Uses the gicen interface to save the file. + * + * @param saveAs used to save the file + */ + public void checkOverwrite(SaveAs saveAs) { + do { + repeat = false; + if (fc.showSaveDialog(parent) == JFileChooser.APPROVE_OPTION) { + + final File selectedFile = checkSuffix(fc.getSelectedFile(), suffix); + + if (selectedFile.exists()) { + Object[] options = {Lang.get("btn_overwrite"), Lang.get("btn_newName")}; + int res = JOptionPane.showOptionDialog(parent, + Lang.get("msg_fileExists", selectedFile.getName()), + Lang.get("msg_warning"), + JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, + null, options, options[0]); + if (res == 1) { + repeat = true; + continue; + } + } + + try { + saveAs.saveAs(selectedFile); + } catch (IOException e) { + new ErrorMessage(Lang.get("msg_errorWritingFile")).addCause(e).show(parent); + } + } + } while (repeat); + } + + /** + * if called user can select an other name + */ + public void retryFileSelect() { + repeat = true; + } + + /** + * Adds the given suffix to the file + * + * @param filename filename + * @param suffix suffix + * @return the file name with the given suffix + */ + public static File checkSuffix(File filename, String suffix) { + if (suffix == null) + return filename; + + String name = filename.getName(); + int p = name.lastIndexOf('.'); + if (p >= 0) + name = name.substring(0, p); + return new File(filename.getParentFile(), name + "." + suffix); + } + + + /** + * Used to encapsulate the save action + */ + public interface SaveAs { + /** + * Interface to implement the save operation + * + * @param file the file to write + * @throws IOException IOException + */ + void saveAs(File file) throws IOException; + + } + +} diff --git a/src/main/java/de/neemann/digital/gui/components/EditorFactory.java b/src/main/java/de/neemann/digital/gui/components/EditorFactory.java index d85a7fd91..40d518282 100644 --- a/src/main/java/de/neemann/digital/gui/components/EditorFactory.java +++ b/src/main/java/de/neemann/digital/gui/components/EditorFactory.java @@ -8,6 +8,7 @@ import de.neemann.digital.core.element.Rotation; import de.neemann.digital.core.io.IntFormat; import de.neemann.digital.core.memory.DataField; import de.neemann.digital.core.memory.ROM; +import de.neemann.digital.gui.SaveAsHelper; import de.neemann.digital.gui.components.testing.TestDataEditor; import de.neemann.digital.gui.sync.NoSync; import de.neemann.digital.lang.Lang; @@ -355,14 +356,12 @@ public final class EditorFactory { JFileChooser fc = new JFileChooser(); fc.setSelectedFile(attr.getFile(ROM.LAST_DATA_FILE_KEY)); fc.setFileFilter(new FileNameExtensionFilter("hex", "hex")); - if (fc.showSaveDialog(panel) == JFileChooser.APPROVE_OPTION) { - attr.setFile(ROM.LAST_DATA_FILE_KEY, fc.getSelectedFile()); - try { - data.saveTo(fc.getSelectedFile()); - } catch (IOException e1) { - new ErrorMessage(Lang.get("msg_errorWritingFile")).addCause(e1).show(panel); - } - } + new SaveAsHelper(panel, fc, "hex").checkOverwrite( + file -> { + attr.setFile(ROM.LAST_DATA_FILE_KEY, file); + data.saveTo(file); + } + ); } }.createJButton()); return panel; diff --git a/src/main/java/de/neemann/digital/gui/components/data/DataSetDialog.java b/src/main/java/de/neemann/digital/gui/components/data/DataSetDialog.java index dd6dded6b..c8f41e6eb 100644 --- a/src/main/java/de/neemann/digital/gui/components/data/DataSetDialog.java +++ b/src/main/java/de/neemann/digital/gui/components/data/DataSetDialog.java @@ -4,10 +4,10 @@ import de.neemann.digital.core.Model; import de.neemann.digital.core.ModelEvent; import de.neemann.digital.core.ModelStateObserver; import de.neemann.digital.core.Signal; +import de.neemann.digital.gui.SaveAsHelper; import de.neemann.digital.gui.components.OrderMerger; import de.neemann.digital.gui.sync.Sync; import de.neemann.digital.lang.Lang; -import de.neemann.gui.ErrorMessage; import de.neemann.gui.ToolTipAction; import javax.swing.*; @@ -16,8 +16,6 @@ import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; -import java.io.File; -import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -86,16 +84,8 @@ public class DataSetDialog extends JDialog implements ModelStateObserver { public void actionPerformed(ActionEvent e) { JFileChooser fileChooser = new JFileChooser(); fileChooser.setFileFilter(new FileNameExtensionFilter("Comma Separated Values", "csv")); - if (fileChooser.showSaveDialog(DataSetDialog.this) == JFileChooser.APPROVE_OPTION) { - File file = fileChooser.getSelectedFile(); - if (!file.getName().endsWith(".csv")) - file = new File(file.getParentFile(), file.getName() + ".csv"); - try { - dataSet.saveCSV(file); - } catch (IOException e1) { - new ErrorMessage(Lang.get("msg_errorSavingData")).addCause(e1).show(DataSetDialog.this); - } - } + new SaveAsHelper(DataSetDialog.this, fileChooser, "csv") + .checkOverwrite(file -> dataSet.saveCSV(file)); } }.setToolTip(Lang.get("menu_saveData_tt")).createJMenuItem()); setJMenuBar(bar); diff --git a/src/main/java/de/neemann/digital/gui/components/table/TableDialog.java b/src/main/java/de/neemann/digital/gui/components/table/TableDialog.java index 40afa3b12..a4cde375c 100644 --- a/src/main/java/de/neemann/digital/gui/components/table/TableDialog.java +++ b/src/main/java/de/neemann/digital/gui/components/table/TableDialog.java @@ -33,6 +33,7 @@ import de.neemann.digital.draw.elements.Circuit; import de.neemann.digital.draw.library.ElementLibrary; import de.neemann.digital.draw.shapes.ShapeFactory; import de.neemann.digital.gui.Main; +import de.neemann.digital.gui.SaveAsHelper; import de.neemann.digital.gui.components.AttributeDialog; import de.neemann.digital.gui.components.ElementOrderer; import de.neemann.digital.lang.Lang; @@ -240,10 +241,10 @@ public class TableDialog extends JDialog { public void actionPerformed(ActionEvent e) { JFileChooser fc = new JFileChooser(); if (TableDialog.this.filename != null) - fc.setSelectedFile(Main.checkSuffix(TableDialog.this.filename, "tru")); + fc.setSelectedFile(SaveAsHelper.checkSuffix(TableDialog.this.filename, "tru")); if (fc.showOpenDialog(TableDialog.this) == JFileChooser.APPROVE_OPTION) { try { - File file = Main.checkSuffix(fc.getSelectedFile(), "tru"); + File file = fc.getSelectedFile(); TruthTable truthTable = TruthTable.readFromFile(file); setModel(new TruthTableTableModel(truthTable)); TableDialog.this.filename = file; @@ -259,36 +260,14 @@ public class TableDialog extends JDialog { public void actionPerformed(ActionEvent e) { JFileChooser fc = new JFileChooser(); if (TableDialog.this.filename != null) - fc.setSelectedFile(Main.checkSuffix(TableDialog.this.filename, "tru")); + fc.setSelectedFile(SaveAsHelper.checkSuffix(TableDialog.this.filename, "tru")); - boolean repeat; - do { - repeat = false; - if (fc.showSaveDialog(TableDialog.this) == JFileChooser.APPROVE_OPTION) { - final File selectedFile = fc.getSelectedFile(); - - if (selectedFile.exists()) { - Object[] options = {Lang.get("btn_overwrite"), Lang.get("btn_newName")}; - int res = JOptionPane.showOptionDialog(TableDialog.this, - Lang.get("msg_fileExists", selectedFile.getName()), - Lang.get("msg_warning"), - JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, - null, options, options[0]); - if (res == 1) { - repeat = true; - continue; - } - } - - try { - File file = Main.checkSuffix(selectedFile, "tru"); + new SaveAsHelper(TableDialog.this, fc, "tru").checkOverwrite( + file -> { model.getTable().save(file); TableDialog.this.filename = file; - } catch (IOException e1) { - new ErrorMessage().addCause(e1).show(TableDialog.this); } - } - } while (repeat); + ); } }); @@ -312,15 +291,9 @@ public class TableDialog extends JDialog { public void actionPerformed(ActionEvent e) { JFileChooser fc = new JFileChooser(); if (TableDialog.this.filename != null) - fc.setSelectedFile(Main.checkSuffix(TableDialog.this.filename, "hex")); - if (fc.showSaveDialog(TableDialog.this) == JFileChooser.APPROVE_OPTION) { - try { - File file = Main.checkSuffix(fc.getSelectedFile(), "hex"); - model.getTable().saveHex(file); - } catch (IOException e1) { - new ErrorMessage().addCause(e1).show(TableDialog.this); - } - } + fc.setSelectedFile(SaveAsHelper.checkSuffix(TableDialog.this.filename, "hex")); + new SaveAsHelper(TableDialog.this, fc, "hex") + .checkOverwrite(file -> model.getTable().saveHex(file)); } }.setToolTip(Lang.get("menu_table_exportHex_tt")).createJMenuItem()); @@ -512,7 +485,7 @@ public class TableDialog extends JDialog { if (filename == null) filename = new File("circuit." + suffix); else - filename = Main.checkSuffix(filename, suffix); + filename = SaveAsHelper.checkSuffix(filename, suffix); JFileChooser fileChooser = new JFileChooser(); fileChooser.setFileFilter(new FileNameExtensionFilter("JEDEC", suffix)); @@ -521,7 +494,7 @@ public class TableDialog extends JDialog { try { expressionExporter.getPinMapping().addAll(model.getTable().getPins()); new BuilderExpressionCreator(expressionExporter.getBuilder(), ExpressionModifier.IDENTITY).create(lastGeneratedExpressions); - expressionExporter.export(Main.checkSuffix(fileChooser.getSelectedFile(), suffix)); + expressionExporter.export(SaveAsHelper.checkSuffix(fileChooser.getSelectedFile(), suffix)); } catch (ExpressionException | FormatterException | IOException | FuseMapFillerException | PinMapException e) { new ErrorMessage(Lang.get("msg_errorDuringCalculation")).addCause(e).show(this); } diff --git a/src/main/resources/lang/lang_de.xml b/src/main/resources/lang/lang_de.xml index b62d0b1e3..0dc437f8b 100644 --- a/src/main/resources/lang/lang_de.xml +++ b/src/main/resources/lang/lang_de.xml @@ -729,7 +729,6 @@ Die Icons stammen aus dem Tango Desktop Project. {0}: ok {0}: Fehler E: {0} / F: {1} - Speichern der Daten fehlgeschlagen! Fehler bei der Erzeugung der Hilfe! In der Zwischenablage befinden sich keine importierbaren Daten! Wählen Sie einen leeren Ordner aus! diff --git a/src/main/resources/lang/lang_en.xml b/src/main/resources/lang/lang_en.xml index 719642a22..66d0036fb 100644 --- a/src/main/resources/lang/lang_en.xml +++ b/src/main/resources/lang/lang_en.xml @@ -716,7 +716,6 @@ The icons are taken from the Tango Desktop Project. {0} passed {0} failed E: {0} / F: {1} - Error writing the data! Error creating the help! The clipboard contains no importable data! Select an empty folder!