Merge pull request #2135 from SiboVG/issue-2131
[#2131] Throw warning message when save filename contains illegal characters
This commit is contained in:
commit
a93a20611b
@ -1343,6 +1343,10 @@ saveAs.openrocket.title = Save as OpenRocket ork file
|
||||
saveAs.rocksim.title = Export as RockSim rkt file
|
||||
saveAs.rasaero.title = Export as RASAero CDX1 file
|
||||
|
||||
! SaveAsFileChooser
|
||||
SaveAsFileChooser.illegalFilename.title = Illegal filename
|
||||
SaveAsFileChooser.illegalFilename.message = The filename '%s' may not contain the character ' %c '. Please remove it.
|
||||
|
||||
! StorageOptionChooser
|
||||
StorageOptChooser.lbl.Simdatatostore = Simulated data to store:
|
||||
StorageOptChooser.rdbut.Allsimdata = All simulated data
|
||||
|
@ -27,6 +27,7 @@ import javax.swing.event.TreeSelectionListener;
|
||||
import javax.swing.tree.TreeNode;
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
import net.sf.openrocket.gui.widgets.SaveFileChooser;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -363,7 +364,7 @@ public class PrintDialog extends JDialog implements TreeSelectionListener {
|
||||
*/
|
||||
private boolean onSavePDF() {
|
||||
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
JFileChooser chooser = new SaveFileChooser();
|
||||
chooser.setFileFilter(FileHelper.PDF_FILTER);
|
||||
|
||||
// Select initial directory
|
||||
|
@ -52,6 +52,7 @@ import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
import net.sf.openrocket.arch.SystemInfo;
|
||||
import net.sf.openrocket.gui.widgets.SaveFileChooser;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -1154,7 +1155,7 @@ public class GeneralOptimizationDialog extends JDialog {
|
||||
trans.get("export.header"), trans.get("export.header.ttip"));
|
||||
|
||||
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
JFileChooser chooser = new SaveFileChooser();
|
||||
chooser.setFileFilter(FileHelper.CSV_FILTER);
|
||||
chooser.setCurrentDirectory(((SwingPreferences) Application.getPreferences()).getDefaultDirectory());
|
||||
chooser.setAccessory(csvOptions);
|
||||
|
@ -42,6 +42,7 @@ import net.sf.openrocket.gui.util.GUIUtil;
|
||||
import net.sf.openrocket.gui.util.Icons;
|
||||
import net.sf.openrocket.gui.util.SimpleFileFilter;
|
||||
import net.sf.openrocket.gui.util.SwingPreferences;
|
||||
import net.sf.openrocket.gui.widgets.SaveFileChooser;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.logging.LoggingSystemSetup;
|
||||
import net.sf.openrocket.logging.Markers;
|
||||
@ -201,7 +202,7 @@ public class PhotoFrame extends JFrame {
|
||||
final FileFilter png = new SimpleFileFilter(trans.get("PhotoFrame.fileFilter.png"),
|
||||
".png");
|
||||
|
||||
final JFileChooser chooser = new JFileChooser();
|
||||
final JFileChooser chooser = new SaveFileChooser();
|
||||
|
||||
chooser.addChoosableFileFilter(png);
|
||||
chooser.setFileFilter(png);
|
||||
|
@ -87,6 +87,7 @@ import net.sf.openrocket.gui.util.OpenFileWorker;
|
||||
import net.sf.openrocket.gui.util.SaveFileWorker;
|
||||
import net.sf.openrocket.gui.util.SwingPreferences;
|
||||
import net.sf.openrocket.gui.util.URLUtil;
|
||||
import net.sf.openrocket.gui.widgets.SaveFileChooser;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.logging.Markers;
|
||||
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
|
||||
@ -1383,7 +1384,7 @@ public class BasicFrame extends JFrame {
|
||||
public boolean exportRockSimAction() {
|
||||
File file;
|
||||
|
||||
final SaveAsFileChooser chooser = SaveAsFileChooser.build(document, FileType.ROCKSIM);
|
||||
final DesignFileSaveAsFileChooser chooser = DesignFileSaveAsFileChooser.build(document, FileType.ROCKSIM);
|
||||
|
||||
int option = chooser.showSaveDialog(BasicFrame.this);
|
||||
|
||||
@ -1480,7 +1481,7 @@ public class BasicFrame extends JFrame {
|
||||
private boolean saveAsAction() {
|
||||
File file = null;
|
||||
|
||||
final SaveAsFileChooser chooser = SaveAsFileChooser.build(document, FileType.OPENROCKET);
|
||||
final DesignFileSaveAsFileChooser chooser = DesignFileSaveAsFileChooser.build(document, FileType.OPENROCKET);
|
||||
|
||||
int option = chooser.showSaveDialog(BasicFrame.this);
|
||||
|
||||
|
@ -3,9 +3,6 @@ package net.sf.openrocket.gui.main;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.JFileChooser;
|
||||
|
||||
@ -15,10 +12,11 @@ import net.sf.openrocket.document.StorageOptions.FileType;
|
||||
import net.sf.openrocket.gui.util.FileHelper;
|
||||
import net.sf.openrocket.gui.util.SimpleFileFilter;
|
||||
import net.sf.openrocket.gui.util.SwingPreferences;
|
||||
import net.sf.openrocket.gui.widgets.SaveFileChooser;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
|
||||
public class SaveAsFileChooser extends JFileChooser {
|
||||
public class DesignFileSaveAsFileChooser extends SaveFileChooser {
|
||||
|
||||
private final FileType type;
|
||||
private final OpenRocketDocument document;
|
||||
@ -26,11 +24,11 @@ public class SaveAsFileChooser extends JFileChooser {
|
||||
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
public static SaveAsFileChooser build( OpenRocketDocument document, FileType type ) {
|
||||
return new SaveAsFileChooser(document,type);
|
||||
public static DesignFileSaveAsFileChooser build(OpenRocketDocument document, FileType type ) {
|
||||
return new DesignFileSaveAsFileChooser(document,type);
|
||||
}
|
||||
|
||||
private SaveAsFileChooser( OpenRocketDocument document, FileType type ) {
|
||||
private DesignFileSaveAsFileChooser(OpenRocketDocument document, FileType type ) {
|
||||
this.document = document;
|
||||
this.type = type;
|
||||
|
@ -43,6 +43,7 @@ import net.sf.openrocket.arch.SystemInfo;
|
||||
import net.sf.openrocket.gui.components.CsvOptionPanel;
|
||||
import net.sf.openrocket.gui.util.FileHelper;
|
||||
import net.sf.openrocket.gui.util.SwingPreferences;
|
||||
import net.sf.openrocket.gui.widgets.SaveFileChooser;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -403,25 +404,25 @@ public class SimulationPanel extends JPanel {
|
||||
return;
|
||||
}
|
||||
|
||||
JFileChooser fch = setUpSimExportCSVFileChooser();
|
||||
int selectionStatus = fch.showSaveDialog(tableParent);
|
||||
JFileChooser chooser = setUpSimExportCSVFileChooser();
|
||||
int selectionStatus = chooser.showSaveDialog(tableParent);
|
||||
if (selectionStatus != JFileChooser.APPROVE_OPTION) {
|
||||
log.debug("User cancelled CSV export");
|
||||
return;
|
||||
}
|
||||
|
||||
// Fetch the info from the file chooser
|
||||
File CSVFile = fch.getSelectedFile();
|
||||
File CSVFile = chooser.getSelectedFile();
|
||||
CSVFile = FileHelper.forceExtension(CSVFile, "csv");
|
||||
if (!FileHelper.confirmWrite(CSVFile, SimulationPanel.this)) {
|
||||
log.debug("User cancelled CSV export overwrite");
|
||||
return;
|
||||
}
|
||||
|
||||
String separator = ((CsvOptionPanel) fch.getAccessory()).getFieldSeparator();
|
||||
int precision = ((CsvOptionPanel) fch.getAccessory()).getDecimalPlaces();
|
||||
boolean isExponentialNotation = ((CsvOptionPanel) fch.getAccessory()).isExponentialNotation();
|
||||
((CsvOptionPanel) fch.getAccessory()).storePreferences();
|
||||
String separator = ((CsvOptionPanel) chooser.getAccessory()).getFieldSeparator();
|
||||
int precision = ((CsvOptionPanel) chooser.getAccessory()).getDecimalPlaces();
|
||||
boolean isExponentialNotation = ((CsvOptionPanel) chooser.getAccessory()).isExponentialNotation();
|
||||
((CsvOptionPanel) chooser.getAccessory()).storePreferences();
|
||||
|
||||
// Handle some special separator options from CsvOptionPanel
|
||||
if (separator.equals(trans.get("CsvOptionPanel.separator.space"))) {
|
||||
@ -439,29 +440,29 @@ public class SimulationPanel extends JPanel {
|
||||
* @return The file chooser.
|
||||
*/
|
||||
private JFileChooser setUpSimExportCSVFileChooser() {
|
||||
JFileChooser fch = new JFileChooser();
|
||||
fch.setDialogTitle(trans.get("simpanel.pop.exportToCSV.save.dialog.title"));
|
||||
fch.setFileFilter(FileHelper.CSV_FILTER);
|
||||
fch.setCurrentDirectory(((SwingPreferences) Application.getPreferences()).getDefaultDirectory());
|
||||
fch.setAcceptAllFileFilterUsed(false);
|
||||
JFileChooser chooser = new SaveFileChooser();
|
||||
chooser.setDialogTitle(trans.get("simpanel.pop.exportToCSV.save.dialog.title"));
|
||||
chooser.setFileFilter(FileHelper.CSV_FILTER);
|
||||
chooser.setCurrentDirectory(((SwingPreferences) Application.getPreferences()).getDefaultDirectory());
|
||||
chooser.setAcceptAllFileFilterUsed(false);
|
||||
|
||||
// Default output CSV to same name as the document's rocket name.
|
||||
String fileName = document.getRocket().getName() + ".csv";
|
||||
fch.setSelectedFile(new File(fileName));
|
||||
chooser.setSelectedFile(new File(fileName));
|
||||
|
||||
// Add CSV options to FileChooser
|
||||
CsvOptionPanel CSVOptions = new CsvOptionPanel(SimulationTableCSVExport.class);
|
||||
fch.setAccessory(CSVOptions);
|
||||
chooser.setAccessory(CSVOptions);
|
||||
|
||||
// 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 = fch.getPreferredSize();
|
||||
Dimension currentSize = chooser.getPreferredSize();
|
||||
Dimension newSize = new Dimension((int) (1.5 * currentSize.width), (int) (1.3 * currentSize.height));
|
||||
fch.setPreferredSize(newSize);
|
||||
chooser.setPreferredSize(newSize);
|
||||
}
|
||||
|
||||
return fch;
|
||||
return chooser;
|
||||
}
|
||||
|
||||
private Simulation[] getSelectedSimulations() {
|
||||
|
@ -26,6 +26,7 @@ import net.sf.openrocket.gui.util.FileHelper;
|
||||
import net.sf.openrocket.gui.util.GUIUtil;
|
||||
import net.sf.openrocket.gui.util.Icons;
|
||||
import net.sf.openrocket.gui.util.SwingPreferences;
|
||||
import net.sf.openrocket.gui.widgets.SaveFileChooser;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.startup.Preferences;
|
||||
@ -173,7 +174,7 @@ public class SimulationPlotDialog extends JDialog {
|
||||
}
|
||||
|
||||
private boolean doPngExport(ChartPanel chartPanel, JFreeChart chart){
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
JFileChooser chooser = new SaveFileChooser();
|
||||
chooser.setAcceptAllFileFilterUsed(false);
|
||||
chooser.setFileFilter(FileHelper.PNG_FILTER);
|
||||
chooser.setCurrentDirectory(((SwingPreferences) Application.getPreferences()).getDefaultDirectory());
|
||||
|
@ -32,6 +32,7 @@ import net.sf.openrocket.gui.util.FileHelper;
|
||||
import net.sf.openrocket.gui.util.GUIUtil;
|
||||
import net.sf.openrocket.gui.util.SaveCSVWorker;
|
||||
import net.sf.openrocket.gui.util.SwingPreferences;
|
||||
import net.sf.openrocket.gui.widgets.SaveFileChooser;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.simulation.FlightData;
|
||||
import net.sf.openrocket.simulation.FlightDataBranch;
|
||||
@ -219,7 +220,7 @@ public class SimulationExportPanel extends JPanel {
|
||||
}
|
||||
|
||||
public boolean doExport() {
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
JFileChooser chooser = new SaveFileChooser();
|
||||
chooser.setFileFilter(FileHelper.CSV_FILTER);
|
||||
chooser.setCurrentDirectory(((SwingPreferences) Application.getPreferences()).getDefaultDirectory());
|
||||
|
||||
|
100
swing/src/net/sf/openrocket/gui/widgets/SaveFileChooser.java
Normal file
100
swing/src/net/sf/openrocket/gui/widgets/SaveFileChooser.java
Normal file
@ -0,0 +1,100 @@
|
||||
package net.sf.openrocket.gui.widgets;
|
||||
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JOptionPane;
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
public class SaveFileChooser extends JFileChooser {
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
private static final char[] ILLEGAL_CHARS = new char[] { '/', '\\', ':', '*', '?', '"', '<', '>', '|' };
|
||||
|
||||
private File cwd = null;
|
||||
private File currentFile = null;
|
||||
private String fileName = null;
|
||||
|
||||
|
||||
@Override
|
||||
public void setSelectedFile(File file) {
|
||||
currentFile = file;
|
||||
if (file == null) {
|
||||
super.setSelectedFile(null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (file.getParentFile() != getCurrentDirectory()) {
|
||||
cwd = getCurrentDirectory();
|
||||
fileName = getFilenameInput(currentFile, cwd);
|
||||
if (getIllegalChar(fileName) != null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
super.setSelectedFile(file);
|
||||
fileName = file.getName();
|
||||
cwd = getCurrentDirectory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void approveSelection() {
|
||||
Character c = getIllegalChar(fileName);
|
||||
if (c != null) {
|
||||
// Illegal character found
|
||||
JOptionPane.showMessageDialog(getParent(),
|
||||
String.format(trans.get("SaveAsFileChooser.illegalFilename.message"), fileName, c),
|
||||
trans.get("SaveAsFileChooser.illegalFilename.title"),
|
||||
JOptionPane.WARNING_MESSAGE);
|
||||
} else {
|
||||
// Successful filename
|
||||
super.setSelectedFile(currentFile);
|
||||
setCurrentDirectory(cwd);
|
||||
super.approveSelection();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an illegal character if one is found in the filename, otherwise returns null.
|
||||
* @param filename The filename to check
|
||||
* @return The illegal character, or null if none is found
|
||||
*/
|
||||
private Character getIllegalChar(String filename) {
|
||||
if (filename == null || filename.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
for (char c : ILLEGAL_CHARS) {
|
||||
if (filename.indexOf(c) >= 0) {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the filename input by the user, or null if the filename is invalid.
|
||||
* You can't simply use getSelectedFile().getName() because it won't work for malformed filenames.
|
||||
* @param file The file to get the filename from
|
||||
* @param cwd The current working directory
|
||||
* @return The filename input by the user, or null if the filename is invalid
|
||||
*/
|
||||
private String getFilenameInput(File file, File cwd) {
|
||||
if (file == null || cwd == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String fullPath = file.getAbsolutePath();
|
||||
String cwdPath = cwd.getAbsolutePath();
|
||||
|
||||
try {
|
||||
String relativePath = fullPath.replaceFirst(Pattern.quote(cwdPath), "").trim();
|
||||
relativePath = relativePath.replaceFirst(Pattern.quote(File.separator), "");
|
||||
return relativePath;
|
||||
} catch (PatternSyntaxException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -37,6 +37,7 @@ import net.sf.openrocket.gui.preset.PresetResultListener;
|
||||
import net.sf.openrocket.gui.util.FileHelper;
|
||||
import net.sf.openrocket.gui.util.Icons;
|
||||
import net.sf.openrocket.gui.util.SwingPreferences;
|
||||
import net.sf.openrocket.gui.widgets.SaveFileChooser;
|
||||
import net.sf.openrocket.logging.Markers;
|
||||
import net.sf.openrocket.material.Material;
|
||||
import net.sf.openrocket.preset.ComponentPreset;
|
||||
@ -404,7 +405,7 @@ public class ComponentPresetEditor extends JPanel implements PresetResultListene
|
||||
private boolean saveAsORC() throws JAXBException, IOException {
|
||||
File file = null;
|
||||
|
||||
final JFileChooser chooser = new JFileChooser();
|
||||
final JFileChooser chooser = new SaveFileChooser();
|
||||
chooser.addChoosableFileFilter(FileHelper.OPEN_ROCKET_COMPONENT_FILTER);
|
||||
|
||||
chooser.setFileFilter(FileHelper.OPEN_ROCKET_COMPONENT_FILTER);
|
||||
|
Loading…
x
Reference in New Issue
Block a user