001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.preferences.projection; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.awt.event.ActionListener; 007import java.io.Serializable; 008import java.util.Collection; 009import java.util.Collections; 010import java.util.Comparator; 011import java.util.regex.Matcher; 012import java.util.regex.Pattern; 013 014import javax.swing.JPanel; 015 016import org.openstreetmap.josm.data.projection.Projection; 017import org.openstreetmap.josm.data.projection.Projections; 018 019/** 020 * Projection choice that lists all known projects by code. 021 * @since 5634 022 */ 023public class CodeProjectionChoice extends AbstractProjectionChoice implements SubPrefsOptions { 024 025 private String code; 026 027 /** 028 * Constructs a new {@code CodeProjectionChoice}. 029 */ 030 public CodeProjectionChoice() { 031 super(tr("By Code (EPSG)"), /* NO-ICON */ "core:code"); 032 } 033 034 /** 035 * Comparator that compares the number part of the code numerically. 036 */ 037 public static class CodeComparator implements Comparator<String>, Serializable { 038 private static final long serialVersionUID = 1L; 039 private final Pattern codePattern = Pattern.compile("([a-zA-Z]+):(\\d+)"); 040 041 @Override 042 public int compare(String c1, String c2) { 043 Matcher matcher1 = codePattern.matcher(c1); 044 Matcher matcher2 = codePattern.matcher(c2); 045 if (matcher1.matches()) { 046 if (matcher2.matches()) { 047 int cmp1 = matcher1.group(1).compareTo(matcher2.group(1)); 048 if (cmp1 != 0) 049 return cmp1; 050 int num1 = Integer.parseInt(matcher1.group(2)); 051 int num2 = Integer.parseInt(matcher2.group(2)); 052 return Integer.compare(num1, num2); 053 } else 054 return -1; 055 } else if (matcher2.matches()) 056 return 1; 057 return c1.compareTo(c2); 058 } 059 } 060 061 @Override 062 public Projection getProjection() { 063 return Projections.getProjectionByCode(code); 064 } 065 066 @Override 067 public String getCurrentCode() { 068 // not needed - getProjection() is overridden 069 throw new UnsupportedOperationException(); 070 } 071 072 @Override 073 public String getProjectionName() { 074 // not needed - getProjection() is overridden 075 throw new UnsupportedOperationException(); 076 } 077 078 @Override 079 public void setPreferences(Collection<String> args) { 080 if (args != null && !args.isEmpty()) { 081 code = args.iterator().next(); 082 } 083 } 084 085 @Override 086 public JPanel getPreferencePanel(ActionListener listener) { 087 return new CodeSelectionPanel(code, listener); 088 } 089 090 @Override 091 public Collection<String> getPreferences(JPanel panel) { 092 if (!(panel instanceof CodeSelectionPanel)) { 093 throw new IllegalArgumentException("Unsupported panel: "+panel); 094 } 095 CodeSelectionPanel csPanel = (CodeSelectionPanel) panel; 096 return Collections.singleton(csPanel.getCode()); 097 } 098 099 /* don't return all possible codes - this projection choice it too generic */ 100 @Override 101 public String[] allCodes() { 102 return new String[0]; 103 } 104 105 /* not needed since allCodes() returns empty array */ 106 @Override 107 public Collection<String> getPreferencesFromCode(String code) { 108 return null; 109 } 110 111 @Override 112 public boolean showProjectionCode() { 113 return true; 114 } 115 116 @Override 117 public boolean showProjectionName() { 118 return true; 119 } 120 121}