1 package tim.prune.function;
3 import java.awt.BorderLayout;
4 import java.awt.Component;
5 import java.awt.FlowLayout;
6 import java.awt.event.ActionEvent;
7 import java.awt.event.ActionListener;
8 import java.awt.event.KeyAdapter;
9 import java.awt.event.KeyEvent;
10 import java.awt.event.MouseAdapter;
11 import java.awt.event.MouseEvent;
13 import javax.swing.BorderFactory;
14 import javax.swing.JButton;
15 import javax.swing.JDialog;
16 import javax.swing.JLabel;
17 import javax.swing.JOptionPane;
18 import javax.swing.JPanel;
19 import javax.swing.JTextField;
20 import javax.swing.SwingConstants;
23 import tim.prune.GenericFunction;
24 import tim.prune.I18nManager;
25 import tim.prune.data.Field;
26 import tim.prune.function.olc.OlcArea;
27 import tim.prune.function.olc.OlcDecoder;
28 import tim.prune.gui.GuiGridLayout;
31 * Class to provide the function to parse
32 * OpenLocationCodes, or PlusCodes
34 public class PlusCodeFunction extends GenericFunction
36 private JDialog _dialog = null;
37 private JTextField _codeField = null;
38 private JButton _okButton = null;
43 * @param inApp application object for callback
45 public PlusCodeFunction(App inApp)
50 /** Get the name key */
51 public String getNameKey() {
52 return "function.enterpluscode";
63 _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()), true);
64 _dialog.setLocationRelativeTo(_parentFrame);
65 _dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
66 _dialog.getContentPane().add(makeDialogComponents());
69 // MAYBE: Paste clipboard into the edit field
70 _codeField.setText("");
72 _dialog.setVisible(true);
77 * Create dialog components
78 * @return Panel containing all gui elements in dialog
80 private Component makeDialogComponents()
82 JPanel dialogPanel = new JPanel();
83 dialogPanel.setLayout(new BorderLayout(0, 10));
84 dialogPanel.add(new JLabel(I18nManager.getText("dialog.pluscode.desc")), BorderLayout.NORTH);
85 JPanel mainPanel = new JPanel();
86 GuiGridLayout grid = new GuiGridLayout(mainPanel);
87 _codeField = new JTextField("", 12);
88 // Listeners to enable/disable ok button
89 KeyAdapter keyListener = new KeyAdapter() {
91 public void keyReleased(KeyEvent inE) {
93 if (inE.getKeyCode() == KeyEvent.VK_ESCAPE) {
98 MouseAdapter mouseListener = new MouseAdapter() {
99 public void mouseReleased(MouseEvent inE) {
103 _codeField.addKeyListener(keyListener);
104 _codeField.addMouseListener(mouseListener);
105 JLabel codeLabel = new JLabel(I18nManager.getText("dialog.pluscode.code"));
106 codeLabel.setHorizontalAlignment(SwingConstants.RIGHT);
108 grid.add(_codeField);
109 dialogPanel.add(mainPanel, BorderLayout.CENTER);
110 // button panel at bottom
111 JPanel buttonPanel = new JPanel();
112 buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
113 _okButton = new JButton(I18nManager.getText("button.ok"));
114 ActionListener okListener = new ActionListener() {
115 public void actionPerformed(ActionEvent e)
117 if (_okButton.isEnabled()) {finish();}
120 _okButton.addActionListener(okListener);
121 _okButton.setEnabled(false);
122 _codeField.addActionListener(okListener);
123 buttonPanel.add(_okButton);
124 JButton cancelButton = new JButton(I18nManager.getText("button.cancel"));
125 cancelButton.addActionListener(new ActionListener() {
126 public void actionPerformed(ActionEvent e)
131 buttonPanel.add(cancelButton);
132 dialogPanel.add(buttonPanel, BorderLayout.SOUTH);
133 dialogPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 15));
138 * Enable or disable the OK button based on the contents of the text field
140 private void enableOK()
142 String text = _codeField.getText();
143 _okButton.setEnabled(text != null && text.length() > 7
144 && text.indexOf(' ') < 0 && text.indexOf(',') < 0);
148 * Finish the dialog when OK pressed
150 private void finish()
152 OlcArea area = OlcDecoder.decode(_codeField.getText());
156 JOptionPane.showMessageDialog(_parentFrame,
157 I18nManager.getText("dialog.pluscode.nothingfound"),
158 I18nManager.getText(getNameKey()), JOptionPane.ERROR_MESSAGE);
160 else if (loadTrack(area))
167 * Load the generated points from the given area
168 * @param inArea rectangular area
169 * @return true on success
171 private boolean loadTrack(OlcArea inArea)
178 final Field[] fields = {Field.LATITUDE, Field.LONGITUDE, Field.WAYPT_NAME};
179 _app.autoAppendNextFile();
181 if (inArea.minLat == inArea.maxLat && inArea.minLon == inArea.maxLon)
183 String[][] pointData = new String[1][];
184 pointData[0] = new String[3]; // lat, long, name
185 pointData[0][0] = "" + inArea.minLat;
186 pointData[0][1] = "" + inArea.minLon;
187 pointData[0][2] = _codeField.getText();
188 _app.informDataLoaded(fields, pointData, null, null);
192 String[][] pointData = new String[6][];
193 for (int i=0; i<5; i++)
195 pointData[i] = new String[3]; // lat, long, name
196 pointData[i][0] = "" + ((i%4==0 || i==3) ? inArea.minLat : inArea.maxLat);
197 pointData[i][1] = "" + ((i%4==0 || i==1) ? inArea.minLon : inArea.maxLon);
198 pointData[i][2] = null;
200 // Middle point with name
201 pointData[5] = new String[3]; // lat, long, name
202 pointData[5][0] = "" + ((inArea.minLat + inArea.maxLat) / 2.0);
203 pointData[5][1] = "" + ((inArea.minLon + inArea.maxLon) / 2.0);
204 pointData[5][2] = _codeField.getText();
205 _app.informDataLoaded(fields, pointData, null, null);