]> gitweb.fperrin.net Git - GpsPrune.git/blobdiff - src/tim/prune/function/settings/AddMapSourceDialog.java
Moved source into separate src directory due to popular request
[GpsPrune.git] / src / tim / prune / function / settings / AddMapSourceDialog.java
diff --git a/src/tim/prune/function/settings/AddMapSourceDialog.java b/src/tim/prune/function/settings/AddMapSourceDialog.java
new file mode 100644 (file)
index 0000000..b9ea26f
--- /dev/null
@@ -0,0 +1,383 @@
+package tim.prune.function.settings;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.FlowLayout;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+
+import javax.swing.BorderFactory;
+import javax.swing.ButtonGroup;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+import javax.swing.JTextField;
+
+import tim.prune.I18nManager;
+import tim.prune.gui.map.MapSource;
+import tim.prune.gui.map.MapSourceLibrary;
+import tim.prune.gui.map.OsmMapSource;
+
+/**
+ * Class to handle the adding of a new map source
+ */
+public class AddMapSourceDialog
+{
+       private SetMapBgFunction _parent = null;
+       private JDialog _addDialog = null;
+       private MapSource _originalSource = null;
+       // controls for osm panel
+       private JTextField _oNameField = null;
+       private JTextField _baseUrlField = null, _topUrlField = null;
+       private JRadioButton[] _baseTypeRadios = null, _topTypeRadios = null;
+       private JComboBox<Integer> _oZoomCombo = null;
+       private JButton _okButton = null;
+
+       /** array of file types */
+       private static final String[] FILE_TYPES = {"png", "jpg", "gif"};
+
+
+       /**
+        * Constructor
+        * @param inParent parent dialog
+        */
+       public AddMapSourceDialog(JDialog inParentDialog, SetMapBgFunction inParentFunction)
+       {
+               _parent = inParentFunction;
+               _addDialog = new JDialog(inParentDialog, I18nManager.getText("dialog.addmapsource.title"), true);
+               _addDialog.add(makeDialogComponents());
+               _addDialog.setLocationRelativeTo(inParentDialog);
+               _addDialog.pack();
+       }
+
+
+       /**
+        * Create dialog components
+        * @return Panel containing all gui elements in dialog
+        */
+       private Component makeDialogComponents()
+       {
+               JPanel dialogPanel = new JPanel();
+               dialogPanel.setLayout(new BorderLayout());
+               // Top panel with spacer
+               dialogPanel.add(new JLabel(" "), BorderLayout.NORTH);
+
+               // listener
+               KeyAdapter keyListener = new KeyAdapter() {
+                       public void keyReleased(KeyEvent e) {
+                               super.keyReleased(e);
+                               if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
+                                       _addDialog.dispose();
+                               }
+                               else {
+                                       enableOK();
+                               }
+                       }
+               };
+               // Listener for any gui changes (to enable ok when anything changes on an edit)
+               ActionListener okEnabler = new ActionListener() {
+                       public void actionPerformed(ActionEvent arg0) {
+                               enableOK();
+                       }
+               };
+
+               // openstreetmap panel
+               JPanel osmPanel = new JPanel();
+               osmPanel.setLayout(new BorderLayout());
+               osmPanel.setBorder(BorderFactory.createEmptyBorder(6, 3, 4, 3));
+               JPanel gbPanel = new JPanel();
+               GridBagLayout gridbag = new GridBagLayout();
+               GridBagConstraints c = new GridBagConstraints();
+               gbPanel.setLayout(gridbag);
+               c.gridx = 0; c.gridy = 0;
+               c.gridheight = 1; c.gridwidth = 1;
+               c.weightx = 0.0; c.weighty = 0.0;
+               c.ipadx = 3; c.ipady = 5;
+               c.insets = new Insets(0, 0, 5, 0);
+               c.anchor = GridBagConstraints.FIRST_LINE_START;
+               gbPanel.add(new JLabel(I18nManager.getText("dialog.addmapsource.sourcename")), c);
+               _oNameField = new JTextField(18);
+               _oNameField.addKeyListener(keyListener);
+               c.gridx = 1; c.weightx = 1.0;
+               gbPanel.add(_oNameField, c);
+               // Base layer
+               c.gridx = 0; c.gridy = 1;
+               c.weightx = 0.0;
+               c.insets = new Insets(0, 0, 0, 0);
+               gbPanel.add(new JLabel(I18nManager.getText("dialog.addmapsource.layer1url")), c);
+               _baseUrlField = new JTextField(18);
+               _baseUrlField.addKeyListener(keyListener);
+               c.gridx = 1; c.weightx = 1.0;
+               gbPanel.add(_baseUrlField, c);
+               _baseTypeRadios = new JRadioButton[3];
+               ButtonGroup radioGroup = new ButtonGroup();
+               for (int i=0; i<3; i++)
+               {
+                       _baseTypeRadios[i] = new JRadioButton(FILE_TYPES[i]);
+                       radioGroup.add(_baseTypeRadios[i]);
+                       c.gridx = 2+i; c.weightx = 0.0;
+                       gbPanel.add(_baseTypeRadios[i], c);
+                       // Each type radio needs listener to call enableOk()
+                       _baseTypeRadios[i].addActionListener(okEnabler);
+               }
+
+               // Top layer
+               c.gridx = 0; c.gridy = 2;
+               gbPanel.add(new JLabel(I18nManager.getText("dialog.addmapsource.layer2url")), c);
+               _topUrlField = new JTextField(18);
+               _topUrlField.addKeyListener(keyListener);
+               c.gridx = 1; c.weightx = 1.0;
+               gbPanel.add(_topUrlField, c);
+               _topTypeRadios = new JRadioButton[3];
+               radioGroup = new ButtonGroup();
+               for (int i=0; i<3; i++)
+               {
+                       _topTypeRadios[i] = new JRadioButton(FILE_TYPES[i]);
+                       radioGroup.add(_topTypeRadios[i]);
+                       c.gridx = 2+i; c.weightx = 0.0;
+                       gbPanel.add(_topTypeRadios[i], c);
+                       // Each type radio needs listener to call enableOk()
+                       _topTypeRadios[i].addActionListener(okEnabler);
+               }
+               // Max zoom
+               c.gridx = 0; c.gridy = 3;
+               gbPanel.add(new JLabel(I18nManager.getText("dialog.addmapsource.maxzoom")), c);
+               _oZoomCombo = new JComboBox<Integer>();
+               for (int i=10; i<=20; i++) {
+                       _oZoomCombo.addItem(i);
+               }
+               // zoom dropdown needs listener to call enableOk()
+               _oZoomCombo.addActionListener(okEnabler);
+               c.gridx = 1;
+               gbPanel.add(_oZoomCombo, c);
+               osmPanel.add(gbPanel, BorderLayout.NORTH);
+
+               // cards
+               JPanel holderPanel = new JPanel();
+               holderPanel.setLayout(new BorderLayout());
+               holderPanel.add(osmPanel, BorderLayout.NORTH);
+               dialogPanel.add(holderPanel, 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)
+                       {
+                               finish();
+                       }
+               };
+               _okButton.addActionListener(okListener);
+               buttonPanel.add(_okButton);
+               JButton cancelButton = new JButton(I18nManager.getText("button.cancel"));
+               cancelButton.addActionListener(new ActionListener() {
+                       public void actionPerformed(ActionEvent e)
+                       {
+                               _addDialog.dispose();
+                       }
+               });
+               buttonPanel.add(cancelButton);
+               dialogPanel.add(buttonPanel, BorderLayout.SOUTH);
+               return dialogPanel;
+       }
+
+
+       /**
+        * Init and show the dialog
+        * @param inSource source object before edit, or null to add
+        */
+       public void showDialog(MapSource inSource)
+       {
+               _originalSource = inSource;
+               populateFields();
+       }
+
+       /**
+        * Clear all the dialog fields to prepare for an add
+        */
+       private void clearAllFields()
+       {
+               _oNameField.setText("");
+               _baseUrlField.setText("");
+               _baseTypeRadios[0].setSelected(true);
+               _topUrlField.setText("");
+               _topTypeRadios[0].setSelected(true);
+               _oZoomCombo.setSelectedIndex(8);
+               _okButton.setEnabled(false);
+               _addDialog.setVisible(true);
+       }
+
+       /**
+        * Init the dialog fields from the given source object
+        */
+       private void populateFields()
+       {
+               if (_originalSource == null)
+               {
+                       clearAllFields();
+                       return;
+               }
+
+               // See if it's an osm source
+               try
+               {
+                       OsmMapSource osmSource = (OsmMapSource) _originalSource;
+                       _oNameField.setText(osmSource.getName());
+                       _baseUrlField.setText(osmSource.getBaseUrl(0));
+                       int baseType = getBaseType(osmSource.getFileExtension(0));
+                       _baseTypeRadios[baseType].setSelected(true);
+                       _topUrlField.setText(osmSource.getNumLayers()==0?"":osmSource.getBaseUrl(1));
+                       int topType = getBaseType(osmSource.getFileExtension(1));
+                       _topTypeRadios[topType].setSelected(true);
+                       _oZoomCombo.setSelectedIndex(getZoomIndex(osmSource.getMaxZoomLevel()));
+               }
+               catch (ClassCastException cce) {} // ignore, sourceFound flag stays false
+
+               _okButton.setEnabled(false);
+               _addDialog.setVisible(true);
+       }
+
+       /**
+        * Check the currently entered details and enable the OK button if it looks OK
+        */
+       private void enableOK()
+       {
+               _okButton.setEnabled(isOsmPanelOk());
+       }
+
+       /**
+        * Check the openstreetmap panel if all details are complete
+        * @return true if details look ok
+        */
+       private boolean isOsmPanelOk()
+       {
+               boolean ok = _oNameField.getText().trim().length() > 1;
+               String baseUrl = null, topUrl = null;
+               // Try to parse base url if given
+               String baseText = _baseUrlField.getText().trim();
+               baseUrl = MapSource.fixBaseUrl(baseText);
+               if (baseText.length() > 0 && baseUrl == null) {ok = false;}
+               // Same again for top url if given
+               String topText = _topUrlField.getText().trim();
+               topUrl = MapSource.fixBaseUrl(topText);
+               if (topText.length() > 0 && topUrl == null) {ok = false;}
+               // looks ok if at least one url given
+               return (ok && (baseUrl != null || topUrl != null));
+       }
+
+       /**
+        * Finish by adding the requested source and refreshing the parent
+        */
+       private void finish()
+       {
+               MapSource newSource = null;
+               String origName = (_originalSource == null ? null : _originalSource.getName());
+
+               if (isOsmPanelOk())
+               {
+                       // Openstreetmap source
+                       String sourceName = getValidSourcename(_oNameField.getText(), origName);
+                       String url1 = _baseUrlField.getText().trim();
+                       String ext1 = getFileExtension(_baseTypeRadios);
+                       String url2 = _topUrlField.getText().trim();
+                       String ext2 = getFileExtension(_topTypeRadios);
+                       newSource = new OsmMapSource(sourceName, url1, ext1, url2, ext2, _oZoomCombo.getSelectedIndex()+10);
+               }
+
+               // Add new source if ok
+               if (newSource != null)
+               {
+                       if (_originalSource == null) {
+                               MapSourceLibrary.addSource(newSource);
+                       }
+                       else {
+                               MapSourceLibrary.editSource(_originalSource, newSource);
+                       }
+                       // inform setmapbg dialog
+                       _parent.updateList();
+                       _addDialog.setVisible(false);
+               }
+       }
+
+       /**
+        * Check the given source name is valid and whether it exists in library already
+        * @param inName name to check
+        * @param inOriginalName name of source before edit (or null for new source)
+        * @return valid name for the new source
+        */
+       private static String getValidSourcename(String inName, String inOriginalName)
+       {
+               String name = inName;
+               if (name == null) {name = "";}
+               else {name = name.trim();}
+               if (name.equals("")) {
+                       name = I18nManager.getText("dialog.addmapsource.noname");
+               }
+               // Check there isn't already a map source with this name
+               if (inOriginalName == null || !inOriginalName.equals(name))
+               {
+                       if (MapSourceLibrary.hasSourceName(name))
+                       {
+                               int suffix = 1;
+                               while (MapSourceLibrary.hasSourceName(name + suffix)) {
+                                       suffix++;
+                               }
+                               name += suffix;
+                       }
+               }
+               return name;
+       }
+
+       /**
+        * Get the selected file extension
+        * @param inRadios array of radio buttons for selection
+        * @return selected file extension
+        */
+       private String getFileExtension(JRadioButton[] inRadios)
+       {
+               if (inRadios != null)
+               {
+                       for (int i=0; i<inRadios.length; i++) {
+                               if (inRadios[i] != null && inRadios[i].isSelected()) {
+                                       return FILE_TYPES[i];
+                               }
+                       }
+               }
+               return FILE_TYPES[0];
+       }
+
+       /**
+        * Get the index of the given image extension
+        * @param inExt file extension, such as "png"
+        * @return index from 0 to 2
+        */
+       private static int getBaseType(String inExt)
+       {
+               for (int i=0; i<FILE_TYPES.length; i++) {
+                       if (FILE_TYPES[i].equals(inExt)) {
+                               return i;
+                       }
+               }
+               // Not found so default to png
+               return 0;
+       }
+
+       /**
+        * Get the dropdown index of the given zoom level
+        * @param inZoomLevel zoom level, eg 18
+        * @return index of dropdown to select
+        */
+       private static int getZoomIndex(int inZoomLevel)
+       {
+               return Math.max(0, inZoomLevel - 10);
+       }
+}