001 // License: GPL. Copyright 2007 by Immanuel Scholz and others 002 package org.openstreetmap.josm.gui; 003 004 import static org.openstreetmap.josm.tools.I18n.tr; 005 006 import java.awt.Component; 007 import java.io.IOException; 008 import java.io.BufferedReader; 009 import java.io.InputStreamReader; 010 import java.io.File; 011 import java.io.FileInputStream; 012 import java.io.FileOutputStream; 013 import java.io.OutputStreamWriter; 014 import java.io.PrintWriter; 015 import java.util.Arrays; 016 import java.util.ArrayList; 017 import java.util.Collection; 018 import java.util.Collections; 019 import java.util.LinkedList; 020 import java.util.regex.Matcher; 021 import java.util.regex.Pattern; 022 023 import javax.swing.DefaultListModel; 024 import javax.swing.ImageIcon; 025 import javax.swing.JLabel; 026 import javax.swing.JList; 027 import javax.swing.JOptionPane; 028 import javax.swing.ListCellRenderer; 029 import javax.swing.UIManager; 030 031 import org.openstreetmap.josm.Main; 032 import org.openstreetmap.josm.data.Bounds; 033 import org.openstreetmap.josm.tools.ImageProvider; 034 035 /** 036 * List class that read and save its content from the bookmark file. 037 * @author imi 038 */ 039 public class BookmarkList extends JList { 040 041 /** 042 * Class holding one bookmarkentry. 043 * @author imi 044 */ 045 public static class Bookmark implements Comparable<Bookmark> { 046 private String name; 047 private Bounds area; 048 049 public Bookmark(Collection<String> list) throws NumberFormatException, IllegalArgumentException { 050 ArrayList<String> array = new ArrayList<String>(list); 051 if(array.size() < 5) 052 throw new IllegalArgumentException(tr("Wrong number of arguments for bookmark")); 053 name = array.get(0); 054 area = new Bounds(Double.parseDouble(array.get(1)), Double.parseDouble(array.get(2)), 055 Double.parseDouble(array.get(3)), Double.parseDouble(array.get(4))); 056 } 057 058 public Bookmark() { 059 area = null; 060 name = null; 061 } 062 063 public Bookmark(Bounds area) { 064 this.area = area; 065 } 066 067 @Override public String toString() { 068 return name; 069 } 070 071 public int compareTo(Bookmark b) { 072 return name.toLowerCase().compareTo(b.name.toLowerCase()); 073 } 074 075 public Bounds getArea() { 076 return area; 077 } 078 079 public String getName() { 080 return name; 081 } 082 083 public void setName(String name) { 084 this.name = name; 085 } 086 087 public void setArea(Bounds area) { 088 this.area = area; 089 } 090 } 091 092 /** 093 * Create a bookmark list as well as the Buttons add and remove. 094 */ 095 public BookmarkList() { 096 setModel(new DefaultListModel()); 097 load(); 098 setVisibleRowCount(7); 099 setCellRenderer(new BookmarkCellRenderer()); 100 } 101 102 /** 103 * Loads the bookmarks from file. 104 */ 105 public void load() { 106 DefaultListModel model = (DefaultListModel)getModel(); 107 model.removeAllElements(); 108 Collection<Collection<String>> args = Main.pref.getArray("bookmarks", null); 109 if(args != null) { 110 LinkedList<Bookmark> bookmarks = new LinkedList<Bookmark>(); 111 for(Collection<String> entry : args) { 112 try { 113 bookmarks.add(new Bookmark(entry)); 114 } 115 catch(Exception e) { 116 System.err.println(tr("Error reading bookmark entry: %s", e.getMessage())); 117 } 118 } 119 Collections.sort(bookmarks); 120 for (Bookmark b : bookmarks) { 121 model.addElement(b); 122 } 123 } 124 else if(!Main.applet) { /* FIXME: remove else clause after spring 2011, but fix windows installer before */ 125 File bookmarkFile = new File(Main.pref.getPreferencesDir(),"bookmarks"); 126 try { 127 LinkedList<Bookmark> bookmarks = new LinkedList<Bookmark>(); 128 if (bookmarkFile.exists()) { 129 System.out.println("Try loading obsolete bookmarks file"); 130 BufferedReader in = new BufferedReader(new InputStreamReader( 131 new FileInputStream(bookmarkFile), "utf-8")); 132 133 for (String line = in.readLine(); line != null; line = in.readLine()) { 134 Matcher m = Pattern.compile("^(.+)[,\u001e](-?\\d+.\\d+)[,\u001e](-?\\d+.\\d+)[,\u001e](-?\\d+.\\d+)[,\u001e](-?\\d+.\\d+)$").matcher(line); 135 if (!m.matches() || m.groupCount() != 5) { 136 System.err.println(tr("Error: Unexpected line ''{0}'' in bookmark file ''{1}''",line, bookmarkFile.toString())); 137 continue; 138 } 139 Bookmark b = new Bookmark(); 140 b.setName(m.group(1)); 141 double[] values= new double[4]; 142 for (int i = 0; i < 4; ++i) { 143 try { 144 values[i] = Double.parseDouble(m.group(i+2)); 145 } catch(NumberFormatException e) { 146 System.err.println(tr("Error: Illegal double value ''{0}'' on line ''{1}'' in bookmark file ''{2}''",m.group(i+2),line, bookmarkFile.toString())); 147 continue; 148 } 149 } 150 b.setArea(new Bounds(values)); 151 bookmarks.add(b); 152 } 153 in.close(); 154 Collections.sort(bookmarks); 155 for (Bookmark b : bookmarks) { 156 model.addElement(b); 157 } 158 save(); 159 System.out.println("Removing obsolete bookmarks file"); 160 bookmarkFile.delete(); 161 } 162 } catch (IOException e) { 163 e.printStackTrace(); 164 JOptionPane.showMessageDialog( 165 Main.parent, 166 tr("<html>Could not read bookmarks from<br>''{0}''<br>Error was: {1}</html>", 167 bookmarkFile.toString(), 168 e.getMessage() 169 ), 170 tr("Error"), 171 JOptionPane.ERROR_MESSAGE 172 ); 173 } 174 } 175 } 176 177 /** 178 * Save all bookmarks to the preferences file 179 */ 180 public void save() { 181 LinkedList<Collection<String>> coll = new LinkedList<Collection<String>>(); 182 for (Object o : ((DefaultListModel)getModel()).toArray()) { 183 String[] array = new String[5]; 184 Bookmark b = (Bookmark)o; 185 array[0] = b.getName(); 186 Bounds area = b.getArea(); 187 array[1] = String.valueOf(area.getMin().lat()); 188 array[2] = String.valueOf(area.getMin().lon()); 189 array[3] = String.valueOf(area.getMax().lat()); 190 array[4] = String.valueOf(area.getMax().lon()); 191 coll.add(Arrays.asList(array)); 192 } 193 Main.pref.putArray("bookmarks", coll); 194 } 195 196 static class BookmarkCellRenderer extends JLabel implements ListCellRenderer { 197 198 private ImageIcon icon; 199 200 public BookmarkCellRenderer() { 201 setOpaque(true); 202 icon = ImageProvider.get("dialogs", "bookmark"); 203 setIcon(icon); 204 } 205 206 protected void renderColor(boolean selected) { 207 if (selected) { 208 setBackground(UIManager.getColor("List.selectionBackground")); 209 setForeground(UIManager.getColor("List.selectionForeground")); 210 } else { 211 setBackground(UIManager.getColor("List.background")); 212 setForeground(UIManager.getColor("List.foreground")); 213 } 214 } 215 216 protected String buildToolTipText(Bookmark b) { 217 Bounds area = b.getArea(); 218 StringBuffer sb = new StringBuffer(); 219 sb.append("<html>min[latitude,longitude]=<strong>[") 220 .append(area.getMin().lat()).append(",").append(area.getMin().lon()).append("]</strong>") 221 .append("<br>") 222 .append("max[latitude,longitude]=<strong>[") 223 .append(area.getMax().lat()).append(",").append(area.getMax().lon()).append("]</strong>") 224 .append("</html>"); 225 return sb.toString(); 226 227 } 228 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, 229 boolean cellHasFocus) { 230 231 Bookmark b = (Bookmark) value; 232 renderColor(isSelected); 233 setText(b.getName()); 234 setToolTipText(buildToolTipText(b)); 235 return this; 236 } 237 } 238 }