// License: GPL. Copyright 2007 by Immanuel Scholz and others package org.openstreetmap.josm.gui.preferences; import static org.openstreetmap.josm.tools.I18n.tr; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.Collection; import javax.swing.BorderFactory; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSeparator; import org.openstreetmap.josm.Main; import org.openstreetmap.josm.data.Bounds; import org.openstreetmap.josm.data.coor.CoordinateFormat; import org.openstreetmap.josm.data.preferences.CollectionProperty; import org.openstreetmap.josm.data.preferences.ParametrizedCollectionProperty; import org.openstreetmap.josm.data.preferences.StringProperty; import org.openstreetmap.josm.data.projection.Mercator; import org.openstreetmap.josm.data.projection.Projection; import org.openstreetmap.josm.data.projection.ProjectionSubPrefs; import org.openstreetmap.josm.data.projection.Projections; import org.openstreetmap.josm.gui.NavigatableComponent; import org.openstreetmap.josm.plugins.PluginHandler; import org.openstreetmap.josm.tools.GBC; public class ProjectionPreference implements PreferenceSetting { public static class Factory implements PreferenceSettingFactory { public PreferenceSetting createPreferenceSetting() { return new ProjectionPreference(); } } private static final StringProperty PROP_PROJECTION = new StringProperty("projection", Mercator.class.getName()); private static final StringProperty PROP_COORDINATES = new StringProperty("coordinates", null); private static final CollectionProperty PROP_SUB_PROJECTION = new CollectionProperty("projection.sub", null); private static final ParametrizedCollectionProperty PROP_PROJECTION_SUBPROJECTION = new ParametrizedCollectionProperty(null) { @Override protected String getKey(String... params) { String name = params[0]; String sname = name.substring(name.lastIndexOf(".")+1); return "projection.sub."+sname; } }; public static final StringProperty PROP_SYSTEM_OF_MEASUREMENT = new StringProperty("system_of_measurement", "Metric"); private static final String[] unitsValues = (new ArrayList(NavigatableComponent.SYSTEMS_OF_MEASUREMENT.keySet())).toArray(new String[0]); private static final String[] unitsValuesTr = new String[unitsValues.length]; static { for (int i=0; i prefs = null; if(proj instanceof ProjectionSubPrefs) { prefs = ((ProjectionSubPrefs) proj).getPreferences(projSubPrefPanel); } PROP_PROJECTION.put(projname); setProjection(projname, prefs); if(PROP_COORDINATES.put(((CoordinateFormat)coordinatesCombo.getSelectedItem()).name())) { CoordinateFormat.setCoordinateFormat((CoordinateFormat)coordinatesCombo.getSelectedItem()); } int i = unitsCombo.getSelectedIndex(); PROP_SYSTEM_OF_MEASUREMENT.put(unitsValues[i]); return false; } static public void setProjection() { setProjection(PROP_PROJECTION.get(), PROP_SUB_PROJECTION.get()); } static public void setProjection(String name, Collection coll) { Bounds b = (Main.map != null && Main.map.mapView != null) ? Main.map.mapView.getRealBounds() : null; Projection proj = null; for (ClassLoader cl : PluginHandler.getResourceClassLoaders()) { try { proj = (Projection) Class.forName(name, true, cl).newInstance(); } catch (final Exception e) { } if (proj != null) { break; } } if (proj == null) { JOptionPane.showMessageDialog( Main.parent, tr("The projection {0} could not be activated. Using Mercator", name), tr("Error"), JOptionPane.ERROR_MESSAGE ); coll = null; proj = new Mercator(); name = Main.getProjection().getClass().getName(); } PROP_SUB_PROJECTION.put(coll); PROP_PROJECTION_SUBPROJECTION.put(coll, name); if(proj instanceof ProjectionSubPrefs) { ((ProjectionSubPrefs) proj).setPreferences(coll); } Projection oldProj = Main.getProjection(); Main.setProjection(proj); if(b != null && (!proj.getClass().getName().equals(oldProj.getClass().getName()) || proj.hashCode() != oldProj.hashCode())) { Main.map.mapView.zoomTo(b); /* TODO - remove layers with fixed projection */ } } private class SBPanel extends JPanel implements ActionListener { private ProjectionSubPrefs p; public SBPanel(ProjectionSubPrefs pr) { super(); p = pr; } @Override public void actionPerformed(ActionEvent e) { p.setPreferences(p.getPreferences(this)); updateMeta(p); } } /** * Handles all the work related to update the projection-specific * preferences * @param proj */ private void selectedProjectionChanged(Projection proj) { if(!(proj instanceof ProjectionSubPrefs)) { projSubPrefPanel = new JPanel(); } else { ProjectionSubPrefs projPref = (ProjectionSubPrefs) proj; projSubPrefPanel = new SBPanel(projPref); projPref.setupPreferencePanel(projSubPrefPanel, (SBPanel)projSubPrefPanel); } // Don't try to update if we're still starting up int size = projPanel.getComponentCount(); if(size < 1) return; // Replace old panel with new one projSubPrefPanelWrapper.removeAll(); projSubPrefPanelWrapper.add(projSubPrefPanel, projSubPrefPanelGBC); projPanel.revalidate(); projSubPrefPanel.repaint(); updateMeta(proj); } /** * Sets up projection combobox with default values and action listener */ private void setupProjectionCombo() { boolean found = false; for (int i = 0; i < projectionCombo.getItemCount(); ++i) { Projection proj = (Projection)projectionCombo.getItemAt(i); String name = proj.getClass().getName(); if(proj instanceof ProjectionSubPrefs) { ((ProjectionSubPrefs) proj).setPreferences(PROP_PROJECTION_SUBPROJECTION.get(name)); } if (name.equals(PROP_PROJECTION.get())) { projectionCombo.setSelectedIndex(i); selectedProjectionChanged(proj); found = true; break; } } if (!found) throw new RuntimeException("Couldn't find the current projection in the list of available projections!"); projectionCombo.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { JComboBox cb = (JComboBox)e.getSource(); Projection proj = (Projection)cb.getSelectedItem(); selectedProjectionChanged(proj); } }); } }