X-Git-Url: http://gitweb.fperrin.net/?p=GpsPrune.git;a=blobdiff_plain;f=src%2Ftim%2Fprune%2Ffunction%2FPasteCoordinates.java;fp=src%2Ftim%2Fprune%2Ffunction%2FPasteCoordinates.java;h=c9b2ad1c7ff3f74da6e8162fbb84d8fa886c1e42;hp=0000000000000000000000000000000000000000;hb=ce6f2161b8596f7018d6a76bff79bc9e571f35fd;hpb=2d8cb72e84d5cc1089ce77baf1e34ea3ea2f8465 diff --git a/src/tim/prune/function/PasteCoordinates.java b/src/tim/prune/function/PasteCoordinates.java new file mode 100644 index 0000000..c9b2ad1 --- /dev/null +++ b/src/tim/prune/function/PasteCoordinates.java @@ -0,0 +1,275 @@ +package tim.prune.function; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.SwingConstants; + +import tim.prune.App; +import tim.prune.GenericFunction; +import tim.prune.I18nManager; +import tim.prune.config.Config; +import tim.prune.data.Altitude; +import tim.prune.data.DataPoint; +import tim.prune.data.Field; +import tim.prune.data.Latitude; +import tim.prune.data.Longitude; +import tim.prune.data.Unit; +import tim.prune.data.UnitSetLibrary; +import tim.prune.gui.GuiGridLayout; + +/** + * Class to provide the function to paste coordinates + * - see wikipedia, opencaching.de, waymarking.com etc + */ +public class PasteCoordinates extends GenericFunction +{ + private JDialog _dialog = null; + private JTextField _nameField = null; + private JTextField _coordField = null; + private JButton _okButton = null; + private JComboBox _altUnitsDropDown; + + + /** + * Constructor + * @param inApp application object for callback + */ + public PasteCoordinates(App inApp) + { + super(inApp); + } + + /** Get the name key */ + public String getNameKey() { + return "function.pastecoordinates"; + } + + /** + * Begin the function + */ + public void begin() + { + // Make dialog window + if (_dialog == null) + { + _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()), true); + _dialog.setLocationRelativeTo(_parentFrame); + _dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); + _dialog.getContentPane().add(makeDialogComponents()); + _dialog.pack(); + } + // MAYBE: Paste clipboard into the edit field + _coordField.setText(""); + _nameField.setText(""); + boolean useMetres = (Config.getUnitSet().getAltitudeUnit() == UnitSetLibrary.UNITS_METRES); + _altUnitsDropDown.setSelectedIndex(useMetres?0:1); + enableOK(); + _dialog.setVisible(true); + } + + + /** + * Create dialog components + * @return Panel containing all gui elements in dialog + */ + private Component makeDialogComponents() + { + JPanel dialogPanel = new JPanel(); + dialogPanel.setLayout(new BorderLayout(0, 10)); + dialogPanel.add(new JLabel(I18nManager.getText("dialog.pastecoordinates.desc")), BorderLayout.NORTH); + JPanel mainPanel = new JPanel(); + GuiGridLayout grid = new GuiGridLayout(mainPanel); + _coordField = new JTextField("", 25); + // Listeners to enable/disable ok button + KeyAdapter keyListener = new KeyAdapter() { + /** Key released */ + public void keyReleased(KeyEvent inE) { + enableOK(); + if (inE.getKeyCode() == KeyEvent.VK_ESCAPE) { + _dialog.dispose(); + } + } + }; + MouseAdapter mouseListener = new MouseAdapter() { + public void mouseReleased(MouseEvent inE) { + enableOK(); + }; + }; + _coordField.addKeyListener(keyListener); + _coordField.addMouseListener(mouseListener); + JLabel coordLabel = new JLabel(I18nManager.getText("dialog.pastecoordinates.coords")); + coordLabel.setHorizontalAlignment(SwingConstants.RIGHT); + grid.add(coordLabel); + grid.add(_coordField); + // Altitude format (if any) + JLabel formatLabel = new JLabel(I18nManager.getText("dialog.openoptions.altitudeunits")); + formatLabel.setHorizontalAlignment(SwingConstants.RIGHT); + grid.add(formatLabel); + final String[] altunits = {I18nManager.getText("units.metres"), I18nManager.getText("units.feet")}; + _altUnitsDropDown = new JComboBox(altunits); + grid.add(_altUnitsDropDown); + // Waypoint name + JLabel nameLabel = new JLabel(I18nManager.getText("dialog.pointnameedit.name")); + nameLabel.setHorizontalAlignment(SwingConstants.RIGHT); + grid.add(nameLabel); + _nameField = new JTextField("", 12); + grid.add(_nameField); + dialogPanel.add(mainPanel, BorderLayout.CENTER); + // button panel at bottom + JPanel buttonPanel = new JPanel(); + buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); + _okButton = new JButton(I18nManager.getText("button.ok")); + ActionListener okListener = new ActionListener() { + public void actionPerformed(ActionEvent e) + { + if (_okButton.isEnabled()) {finish();} + } + }; + _okButton.addActionListener(okListener); + _okButton.setEnabled(false); + _coordField.addActionListener(okListener); + _nameField.addActionListener(okListener); + buttonPanel.add(_okButton); + JButton cancelButton = new JButton(I18nManager.getText("button.cancel")); + cancelButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) + { + _dialog.dispose(); + } + }); + buttonPanel.add(cancelButton); + dialogPanel.add(buttonPanel, BorderLayout.SOUTH); + dialogPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 15)); + return dialogPanel; + } + + /** + * Enable or disable the OK button based on the contents of the text field + */ + private void enableOK() + { + String text = _coordField.getText(); + _okButton.setEnabled(text != null && text.length() > 6 + && (text.indexOf(' ') >= 0 || text.indexOf(',') >= 0)); + } + + /** + * Finish the dialog when OK pressed + */ + private void finish() + { + DataPoint point = null; + // Try to split using commas + String[] items = _coordField.getText().split(","); + if (items.length == 2) { + point = parseValues(items[0].trim(), items[1].trim(), null); + } + else if (items.length == 3) { + point = parseValues(items[0].trim(), items[1].trim(), items[2].trim()); + } + else { + // Splitting with commas didn't work, so try spaces + items = _coordField.getText().split(" "); + if (items.length == 2) { + point = parseValues(items[0], items[1], null); + } + else if (items.length == 3 && items[1].length() == 1) { + point = parseValues(items[0], items[2], null); + } + else if (items.length == 4) { + point = parseValues(items[0] + " " + items[1], + items[2] + " " + items[3], null); + } + else if (items.length == 6) { + point = parseValues(items[0] + " " + items[1] + " " + items[2], + items[3] + " " + items[4] + " " + items[5], null); + } + else if (items.length == 8) { + point = parseValues(items[0] + " " + items[1] + " " + items[2] + " " + items[3], + items[4] + " " + items[5] + " " + items[6] + " " + items[7], null); + } + } + + if (point == null) { + JOptionPane.showMessageDialog(_parentFrame, + I18nManager.getText("dialog.pastecoordinates.nothingfound"), + I18nManager.getText(getNameKey()), JOptionPane.ERROR_MESSAGE); + } + else { + // See if name was entered + String name = _nameField.getText(); + if (name != null && name.length() > 0) { + point.setFieldValue(Field.WAYPT_NAME, name, false); + } + // Pass information back to App to complete function + _app.createPoint(point); + _dialog.dispose(); + } + } + + + /** + * Try to parse the three given Strings into lat, lon and alt + * @param inValue1 first value (either lat/lon) + * @param inValue2 second value (either lon/lat) + * @param inValue3 altitude value or null if absent + * @return DataPoint object or null if failed + */ + private DataPoint parseValues(String inValue1, String inValue2, String inValue3) + { + // Check for parseable altitude + Altitude alt = null; + if (inValue3 != null) + { + // Look at altitude units dropdown + final Unit altUnit = (_altUnitsDropDown.getSelectedIndex()==0? + UnitSetLibrary.UNITS_METRES : UnitSetLibrary.UNITS_FEET); + alt = new Altitude(inValue3, altUnit); + if (!alt.isValid()) {alt = null;} + } + // See if value1 can be lat and value2 lon: + Latitude coord1 = new Latitude(inValue1); + Longitude coord2 = new Longitude(inValue2); + if (coord1.isValid() && !coord1.getCardinalGuessed() + && coord2.isValid() && !coord2.getCardinalGuessed()) + { + return new DataPoint(coord1, coord2, alt); + } + // Now see if lat/lon are reversed + Longitude coord3 = new Longitude(inValue1); + Latitude coord4 = new Latitude(inValue2); + if (coord3.isValid() && !coord3.getCardinalGuessed() + && coord4.isValid() && !coord4.getCardinalGuessed()) + { + // reversed order + return new DataPoint(coord4, coord3, alt); + } + // Didn't work without guessing cardinals, so accept latitude, longitude order (if valid) + if (coord1.isValid() && coord2.isValid()) { + return new DataPoint(coord1, coord2, alt); + } + // Or accept other order (if valid) + if (coord3.isValid() && coord4.isValid()) { + // reversed order + return new DataPoint(coord4, coord3, alt); + } + // Couldn't be parsed either way + return null; + } +}