]> gitweb.fperrin.net Git - GpsPrune.git/blobdiff - tim/prune/save/FileSaver.java
Version 14, October 2012
[GpsPrune.git] / tim / prune / save / FileSaver.java
index ea4efb87087f0ca33309b1edb2454ba7564018c7..6be44eb80bc3eb6beb828f0270db15c75255954e 100644 (file)
@@ -32,14 +32,15 @@ import javax.swing.ListSelectionModel;
 import javax.swing.table.TableModel;
 
 import tim.prune.App;
-import tim.prune.Config;
 import tim.prune.I18nManager;
 import tim.prune.UpdateMessageBroker;
+import tim.prune.config.Config;
 import tim.prune.data.Altitude;
 import tim.prune.data.Coordinate;
 import tim.prune.data.DataPoint;
 import tim.prune.data.Field;
 import tim.prune.data.FieldList;
+import tim.prune.data.RecentFile;
 import tim.prune.data.Timestamp;
 import tim.prune.data.Track;
 import tim.prune.load.GenericFileFilter;
@@ -47,13 +48,12 @@ import tim.prune.load.OneCharDocument;
 
 /**
  * Class to manage the saving of track data
- * into a user-specified file
+ * as text into a user-specified file
  */
 public class FileSaver
 {
        private App _app = null;
        private JFrame _parentFrame = null;
-       private Track _track = null;
        private JDialog _dialog = null;
        private JFileChooser _fileChooser = null;
        private JPanel _cards = null;
@@ -65,9 +65,11 @@ public class FileSaver
        private JRadioButton[] _delimiterRadios = null;
        private JTextField _otherDelimiterText = null;
        private JCheckBox _headerRowCheckbox = null;
+       private PointTypeSelector _pointTypeSelector = null;
        private JRadioButton[] _coordUnitsRadios = null;
        private JRadioButton[] _altitudeUnitsRadios = null;
        private JRadioButton[] _timestampUnitsRadios = null;
+
        private static final int[] FORMAT_COORDS = {Coordinate.FORMAT_NONE, Coordinate.FORMAT_DEG_MIN_SEC,
                Coordinate.FORMAT_DEG_MIN, Coordinate.FORMAT_DEG};
        private static final Altitude.Format[] FORMAT_ALTS = {Altitude.Format.NO_FORMAT, Altitude.Format.METRES, Altitude.Format.FEET};
@@ -78,13 +80,11 @@ public class FileSaver
         * Constructor
         * @param inApp application object to inform of success
         * @param inParentFrame parent frame
-        * @param inTrack track object to save
         */
-       public FileSaver(App inApp, JFrame inParentFrame, Track inTrack)
+       public FileSaver(App inApp, JFrame inParentFrame)
        {
                _app = inApp;
                _parentFrame = inParentFrame;
-               _track = inTrack;
        }
 
 
@@ -102,13 +102,14 @@ public class FileSaver
                        _dialog.pack();
                }
                // Check field list
-               FieldList fieldList = _track.getFieldList();
+               Track track = _app.getTrackInfo().getTrack();
+               FieldList fieldList = track.getFieldList();
                int numFields = fieldList.getNumFields();
                _model = new FieldSelectionTableModel(numFields);
                for (int i=0; i<numFields; i++)
                {
                        Field field = fieldList.getField(i);
-                       FieldInfo info = new FieldInfo(field, _track.hasData(field));
+                       FieldInfo info = new FieldInfo(field, track.hasData(field));
                        _model.addFieldInfo(info, i);
                }
                // Initialise dialog and show it
@@ -224,13 +225,18 @@ public class FileSaver
                firstCard.add(Box.createRigidArea(new Dimension(0,10)));
                _headerRowCheckbox = new JCheckBox(I18nManager.getText("dialog.save.headerrow"), true);
                firstCard.add(_headerRowCheckbox);
-
                _cards.add(firstCard, "card1");
 
+               // Second card
                JPanel secondCard = new JPanel();
                secondCard.setLayout(new BorderLayout());
                JPanel secondCardHolder = new JPanel();
                secondCardHolder.setLayout(new BoxLayout(secondCardHolder, BoxLayout.Y_AXIS));
+               // point type selector
+               secondCardHolder.add(Box.createRigidArea(new Dimension(0,10)));
+               _pointTypeSelector = new PointTypeSelector();
+               _pointTypeSelector.setAlignmentX(JLabel.LEFT_ALIGNMENT);
+               secondCardHolder.add(_pointTypeSelector);
                JLabel coordLabel = new JLabel(I18nManager.getText("dialog.save.coordinateunits"));
                coordLabel.setAlignmentX(JLabel.LEFT_ALIGNMENT);
                secondCardHolder.add(coordLabel);
@@ -251,7 +257,7 @@ public class FileSaver
                }
                coordsUnitsPanel.setAlignmentX(JPanel.LEFT_ALIGNMENT);
                secondCardHolder.add(coordsUnitsPanel);
-               secondCardHolder.add(Box.createRigidArea(new Dimension(0,10)));
+               secondCardHolder.add(Box.createRigidArea(new Dimension(0,7)));
                // altitude units
                JLabel altUnitsLabel = new JLabel(I18nManager.getText("dialog.save.altitudeunits"));
                altUnitsLabel.setAlignmentX(JLabel.LEFT_ALIGNMENT);
@@ -272,7 +278,7 @@ public class FileSaver
                }
                altUnitsPanel.setAlignmentX(JPanel.LEFT_ALIGNMENT);
                secondCardHolder.add(altUnitsPanel);
-               secondCardHolder.add(Box.createRigidArea(new Dimension(0,10)));
+               secondCardHolder.add(Box.createRigidArea(new Dimension(0,7)));
                // Selection of format of timestamps
                JLabel timestampLabel = new JLabel(I18nManager.getText("dialog.save.timestampformat"));
                timestampLabel.setAlignmentX(JLabel.LEFT_ALIGNMENT);
@@ -367,6 +373,7 @@ public class FileSaver
                        default   : _delimiterRadios[4].setSelected(true);
                                                _otherDelimiterText.setText("" + inDefaultDelimiter);
                }
+               _pointTypeSelector.init(_app.getTrackInfo());
                // set card and enable buttons
                CardLayout cl = (CardLayout) _cards.getLayout();
                cl.first(_cards);
@@ -376,196 +383,238 @@ public class FileSaver
 
 
        /**
-        * Save the track to file with the chosen options
+        * Start the save process by choosing the file to save to
         * @return true if successful or cancelled, false if failed
         */
        private boolean saveToFile()
        {
-               boolean saveOK = true;
-               FileWriter writer = null;
+               if (!_pointTypeSelector.getAnythingSelected()) {
+                       JOptionPane.showMessageDialog(_parentFrame, I18nManager.getText("dialog.save.notypesselected"),
+                               I18nManager.getText("dialog.saveoptions.title"), JOptionPane.WARNING_MESSAGE);
+                       return false;
+               }
                if (_fileChooser == null)
                {
                        _fileChooser = new JFileChooser();
                        _fileChooser.setDialogType(JFileChooser.SAVE_DIALOG);
                        _fileChooser.addChoosableFileFilter(new GenericFileFilter("filetype.txt", new String[] {"txt", "text"}));
-                       _fileChooser.addChoosableFileFilter(new GenericFileFilter("filetype.gpx", new String[] {"gpx"}));
-                       _fileChooser.addChoosableFileFilter(new GenericFileFilter("filetype.kml", new String[] {"kml"}));
                        _fileChooser.setAcceptAllFileFilterUsed(true);
                        // start from directory in config which should be set
-                       File configDir = Config.getWorkingDirectory();
-                       if (configDir != null) {_fileChooser.setCurrentDirectory(configDir);}
+                       String configDir = Config.getConfigString(Config.KEY_TRACK_DIR);
+                       if (configDir == null) {configDir = Config.getConfigString(Config.KEY_PHOTO_DIR);}
+                       if (configDir != null) {_fileChooser.setCurrentDirectory(new File(configDir));}
                }
                if (_fileChooser.showSaveDialog(_parentFrame) == JFileChooser.APPROVE_OPTION)
                {
-                       File saveFile = _fileChooser.getSelectedFile();
-                       String lineSeparator = System.getProperty("line.separator");
-                       // Get coordinate format and altitude format
-                       int coordFormat = Coordinate.FORMAT_NONE;
-                       for (int i=0; i<_coordUnitsRadios.length; i++)
-                               if (_coordUnitsRadios[i].isSelected())
-                                       coordFormat = FORMAT_COORDS[i];
-                       Altitude.Format altitudeFormat = Altitude.Format.NO_FORMAT;
-                       for (int i=0; i<_altitudeUnitsRadios.length; i++)
-                       {
-                               if (_altitudeUnitsRadios[i].isSelected())
-                               {
-                                       altitudeFormat = FORMAT_ALTS[i];
-                               }
+                       return saveToFile(_fileChooser.getSelectedFile());
+               }
+               return true; // cancelled
+       }
+
+
+       /**
+        * Save the track to the specified file using the chosen options
+        * @param inSaveFile file to save to
+        * @return true if save successful, false if failed
+        */
+       private boolean saveToFile(File inSaveFile)
+       {
+               // TODO: Shorten method
+               FileWriter writer = null;
+               final String lineSeparator = System.getProperty("line.separator");
+               boolean saveOK = true;
+               // Get coordinate format and altitude format
+               int coordFormat = Coordinate.FORMAT_NONE;
+               for (int i=0; i<_coordUnitsRadios.length; i++)
+                       if (_coordUnitsRadios[i].isSelected())
+                               coordFormat = FORMAT_COORDS[i];
+               Altitude.Format altitudeFormat = Altitude.Format.NO_FORMAT;
+               for (int i=0; i<_altitudeUnitsRadios.length; i++)
+               {
+                       if (_altitudeUnitsRadios[i].isSelected()) {
+                               altitudeFormat = FORMAT_ALTS[i];
                        }
-                       // Get timestamp formats
-                       int timestampFormat = Timestamp.FORMAT_ORIGINAL;
-                       for (int i=0; i<_timestampUnitsRadios.length; i++)
-                       {
-                               if (_timestampUnitsRadios[i].isSelected())
-                               {
-                                       timestampFormat = FORMAT_TIMES[i];
-                               }
+               }
+               // Get timestamp format
+               int timestampFormat = Timestamp.FORMAT_ORIGINAL;
+               for (int i=0; i<_timestampUnitsRadios.length; i++)
+               {
+                       if (_timestampUnitsRadios[i].isSelected()) {
+                               timestampFormat = FORMAT_TIMES[i];
                        }
+               }
+
+               // Correct chosen filename if necessary
+               final File saveFile = (isFilenameOk(inSaveFile)?inSaveFile:new File(inSaveFile.getAbsolutePath() + ".txt"));
 
-                       // Check if file exists, and confirm overwrite if necessary
-                       Object[] buttonTexts = {I18nManager.getText("button.overwrite"), I18nManager.getText("button.cancel")};
-                       if (!saveFile.exists() || JOptionPane.showOptionDialog(_parentFrame,
-                                       I18nManager.getText("dialog.save.overwrite.text"),
-                                       I18nManager.getText("dialog.save.overwrite.title"), JOptionPane.YES_NO_OPTION,
-                                       JOptionPane.WARNING_MESSAGE, null, buttonTexts, buttonTexts[1])
-                               == JOptionPane.YES_OPTION)
+               // Check if file exists, and confirm overwrite if necessary
+               Object[] buttonTexts = {I18nManager.getText("button.overwrite"), I18nManager.getText("button.cancel")};
+               if (!saveFile.exists() || JOptionPane.showOptionDialog(_parentFrame,
+                               I18nManager.getText("dialog.save.overwrite.text"),
+                               I18nManager.getText("dialog.save.overwrite.title"), JOptionPane.YES_NO_OPTION,
+                               JOptionPane.WARNING_MESSAGE, null, buttonTexts, buttonTexts[1])
+                       == JOptionPane.YES_OPTION)
+               {
+                       try
                        {
-                               try
-                               {
-                                       // Create output file
-                                       writer = new FileWriter(saveFile);
-                                       // Determine delimiter character to use
-                                       char delimiter = getDelimiter();
-                                       FieldInfo info = null;
-                                       Field field = null;
-
-                                       StringBuffer buffer = null;
-                                       int numFields = _model.getRowCount();
-                                       boolean firstField = true;
-                                       // Write header row if required
-                                       if (_headerRowCheckbox.isSelected())
-                                       {
-                                               buffer = new StringBuffer();
-                                               for (int f=0; f<numFields; f++)
-                                               {
-                                                       info = _model.getFieldInfo(f);
-                                                       if (info.isSelected())
-                                                       {
-                                                               if (!firstField)
-                                                               {
-                                                                       // output field separator
-                                                                       buffer.append(delimiter);
-                                                               }
-                                                               field = info.getField();
-                                                               buffer.append(field.getName());
-                                                               firstField = false;
-                                                       }
-                                               }
-                                               writer.write(buffer.toString());
-                                               writer.write(lineSeparator);
-                                       }
+                               // Create output file
+                               writer = new FileWriter(saveFile);
+                               // Determine delimiter character to use
+                               final char delimiter = getDelimiter();
+                               FieldInfo info = null;
 
-                                       // Loop over points outputting each in turn to buffer
-                                       int numPoints = _track.getNumPoints();
-                                       for (int p=0; p<numPoints; p++)
+                               StringBuffer buffer = null;
+                               int numFields = _model.getRowCount();
+                               boolean firstField = true;
+                               // Write header row if required
+                               if (_headerRowCheckbox.isSelected())
+                               {
+                                       buffer = new StringBuffer();
+                                       for (int f=0; f<numFields; f++)
                                        {
-                                               DataPoint point = _track.getPoint(p);
-                                               firstField = true;
-                                               buffer = new StringBuffer();
-                                               for (int f=0; f<numFields; f++)
+                                               info = _model.getFieldInfo(f);
+                                               if (info.isSelected())
                                                {
-                                                       info = _model.getFieldInfo(f);
-                                                       if (info.isSelected())
-                                                       {
-                                                               if (!firstField)
-                                                               {
-                                                                       // output field separator
-                                                                       buffer.append(delimiter);
-                                                               }
-                                                               field = info.getField();
-                                                               // Output field according to type
-                                                               if (field == Field.LATITUDE)
-                                                               {
-                                                                       buffer.append(point.getLatitude().output(coordFormat));
-                                                               }
-                                                               else if (field == Field.LONGITUDE)
-                                                               {
-                                                                       buffer.append(point.getLongitude().output(coordFormat));
-                                                               }
-                                                               else if (field == Field.ALTITUDE)
-                                                               {
-                                                                       try
-                                                                       {
-                                                                               buffer.append(point.getAltitude().getStringValue(altitudeFormat));
-                                                                       }
-                                                                       catch (NullPointerException npe) {}
-                                                               }
-                                                               else if (field == Field.TIMESTAMP)
-                                                               {
-                                                                       if (point.hasTimestamp())
-                                                                       {
-                                                                               if (timestampFormat == Timestamp.FORMAT_ORIGINAL) {
-                                                                                       // output original string
-                                                                                       buffer.append(point.getFieldValue(Field.TIMESTAMP));
-                                                                               }
-                                                                               else {
-                                                                                       // format value accordingly
-                                                                                       buffer.append(point.getTimestamp().getText(timestampFormat));
-                                                                               }
-                                                                       }
-                                                               }
-                                                               else
-                                                               {
-                                                                       String value = point.getFieldValue(field);
-                                                                       if (value != null)
-                                                                       {
-                                                                               buffer.append(value);
-                                                                       }
-                                                               }
-                                                               firstField = false;
+                                                       // output field separator
+                                                       if (!firstField) {
+                                                               buffer.append(delimiter);
                                                        }
+                                                       buffer.append(info.getField().getName());
+                                                       firstField = false;
                                                }
-                                               // Output to file
-                                               writer.write(buffer.toString());
-                                               writer.write(lineSeparator);
                                        }
-                                       // Store directory in config for later
-                                       Config.setWorkingDirectory(saveFile.getParentFile());
-                                       // Save successful
-                                       UpdateMessageBroker.informSubscribers(I18nManager.getText("confirm.save.ok1")
-                                                + " " + numPoints + " " + I18nManager.getText("confirm.save.ok2")
-                                                + " " + saveFile.getAbsolutePath());
-                                       _app.informDataSaved();
+                                       writer.write(buffer.toString());
+                                       writer.write(lineSeparator);
                                }
-                               catch (IOException ioe)
-                               {
-                                       saveOK = false;
-                                       _app.showErrorMessageNoLookup("error.save.dialogtitle",
-                                               I18nManager.getText("error.save.failed") + " : " + ioe.getMessage());
+
+                               // Examine selection
+                               int selStart = -1, selEnd = -1;
+                               if (_pointTypeSelector.getJustSelection()) {
+                                       selStart = _app.getTrackInfo().getSelection().getStart();
+                                       selEnd = _app.getTrackInfo().getSelection().getEnd();
                                }
-                               finally
+                               // Loop over points outputting each in turn to buffer
+                               Track track = _app.getTrackInfo().getTrack();
+                               final int numPoints = track.getNumPoints();
+                               int numSaved = 0;
+                               for (int p=0; p<numPoints; p++)
                                {
-                                       // try to close file if it's open
-                                       try
+                                       DataPoint point = track.getPoint(p);
+                                       boolean savePoint = ((point.isWaypoint() && _pointTypeSelector.getWaypointsSelected())
+                                               || (!point.isWaypoint() && !point.hasMedia() && _pointTypeSelector.getTrackpointsSelected())
+                                               || (!point.isWaypoint() && point.getPhoto()!=null && _pointTypeSelector.getPhotopointsSelected())
+                                               || (!point.isWaypoint() && point.getAudio()!=null && _pointTypeSelector.getAudiopointsSelected()))
+                                               && (!_pointTypeSelector.getJustSelection() || (p>=selStart && p<=selEnd));
+                                       if (!savePoint) {continue;}
+                                       numSaved++;
+                                       firstField = true;
+                                       buffer = new StringBuffer();
+                                       for (int f=0; f<numFields; f++)
                                        {
-                                               if (writer != null)
+                                               info = _model.getFieldInfo(f);
+                                               if (info.isSelected())
                                                {
-                                                       writer.close();
+                                                       // output field separator
+                                                       if (!firstField) {
+                                                               buffer.append(delimiter);
+                                                       }
+                                                       saveField(buffer, point, info.getField(), coordFormat, altitudeFormat, timestampFormat);
+                                                       firstField = false;
                                                }
                                        }
-                                       catch (Exception e) {}
+                                       // Output to file
+                                       writer.write(buffer.toString());
+                                       writer.write(lineSeparator);
                                }
+                               // Store directory in config for later
+                               Config.setConfigString(Config.KEY_TRACK_DIR, saveFile.getParentFile().getAbsolutePath());
+                               // Add to recent file list
+                               Config.getRecentFileList().addFile(new RecentFile(inSaveFile, true));
+                               // Save successful
+                               UpdateMessageBroker.informSubscribers();
+                               UpdateMessageBroker.informSubscribers(I18nManager.getText("confirm.save.ok1")
+                                        + " " + numSaved + " " + I18nManager.getText("confirm.save.ok2")
+                                        + " " + saveFile.getAbsolutePath());
+                               _app.informDataSaved();
                        }
-                       else
+                       catch (IOException ioe)
                        {
-                               // Overwrite file confirm cancelled
                                saveOK = false;
+                               _app.showErrorMessageNoLookup("error.save.dialogtitle",
+                                       I18nManager.getText("error.save.failed") + " : " + ioe.getMessage());
+                       }
+                       finally
+                       {
+                               // try to close file if it's open
+                               try {
+                                       writer.close();
+                               }
+                               catch (Exception e) {}
                        }
                }
+               else
+               {
+                       // Overwrite file confirm cancelled
+                       saveOK = false;
+               }
                return saveOK;
        }
 
 
+       /**
+        * Format the given field and append to the given buffer for saving
+        * @param inBuffer buffer to append to
+        * @param inPoint point object
+        * @param inField field object
+        * @param inCoordFormat coordinate format
+        * @param inAltitudeFormat altitude format
+        * @param inTimestampFormat timestamp format
+        */
+       private void saveField(StringBuffer inBuffer, DataPoint inPoint, Field inField,
+               int inCoordFormat, Altitude.Format inAltitudeFormat, int inTimestampFormat)
+       {
+               // Output field according to type
+               if (inField == Field.LATITUDE)
+               {
+                       inBuffer.append(inPoint.getLatitude().output(inCoordFormat));
+               }
+               else if (inField == Field.LONGITUDE)
+               {
+                       inBuffer.append(inPoint.getLongitude().output(inCoordFormat));
+               }
+               else if (inField == Field.ALTITUDE)
+               {
+                       try
+                       {
+                               inBuffer.append(inPoint.getAltitude().getStringValue(inAltitudeFormat));
+                       }
+                       catch (NullPointerException npe) {}
+               }
+               else if (inField == Field.TIMESTAMP)
+               {
+                       if (inPoint.hasTimestamp())
+                       {
+                               if (inTimestampFormat == Timestamp.FORMAT_ORIGINAL) {
+                                       // output original string
+                                       inBuffer.append(inPoint.getTimestamp().getText(Timestamp.FORMAT_ORIGINAL));
+                               }
+                               else {
+                                       // format value accordingly
+                                       inBuffer.append(inPoint.getTimestamp().getText(inTimestampFormat));
+                               }
+                       }
+               }
+               else
+               {
+                       String value = inPoint.getFieldValue(inField);
+                       if (value != null)
+                       {
+                               inBuffer.append(value);
+                       }
+               }
+       }
+
+
        /**
         * @return the selected delimiter character
         */
@@ -583,4 +632,17 @@ public class FileSaver
                // Wasn't any of those so must be 'other'
                return _otherDelimiterText.getText().charAt(0);
        }
+
+
+       /**
+        * Check the selected filename to see if it is acceptable
+        * @param inFile chosen file to save
+        * @return true if filename is ok
+        */
+       private static boolean isFilenameOk(File inFile)
+       {
+               String filename = inFile.getName().toLowerCase();
+               return (filename.length() <4 || (!filename.endsWith(".gpx")
+                       && !filename.endsWith(".kml") && !filename.endsWith(".kmz") && !filename.endsWith(".zip")));
+       }
 }