001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.download; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.awt.Component; 007import java.util.ArrayList; 008import java.util.Arrays; 009import java.util.Collection; 010import java.util.Collections; 011import java.util.LinkedList; 012import java.util.List; 013import java.util.Locale; 014 015import javax.swing.DefaultListModel; 016import javax.swing.JLabel; 017import javax.swing.JList; 018import javax.swing.ListCellRenderer; 019import javax.swing.UIManager; 020 021import org.openstreetmap.josm.Main; 022import org.openstreetmap.josm.data.Bounds; 023import org.openstreetmap.josm.tools.ImageProvider; 024 025/** 026 * List class that read and save its content from the bookmark file. 027 * @since 6340 028 */ 029public class BookmarkList extends JList<BookmarkList.Bookmark> { 030 031 /** 032 * Class holding one bookmarkentry. 033 */ 034 public static class Bookmark implements Comparable<Bookmark> { 035 private String name; 036 private Bounds area; 037 038 /** 039 * Constructs a new {@code Bookmark} with the given contents. 040 * @param list Bookmark contents as a list of 5 elements. 041 * First item is the name, then come bounds arguments (minlat, minlon, maxlat, maxlon) 042 * @throws NumberFormatException if the bounds arguments are not numbers 043 * @throws IllegalArgumentException if list contain less than 5 elements 044 */ 045 public Bookmark(Collection<String> list) { 046 List<String> array = new ArrayList<>(list); 047 if (array.size() < 5) 048 throw new IllegalArgumentException(tr("Wrong number of arguments for bookmark")); 049 name = array.get(0); 050 area = new Bounds(Double.parseDouble(array.get(1)), Double.parseDouble(array.get(2)), 051 Double.parseDouble(array.get(3)), Double.parseDouble(array.get(4))); 052 } 053 054 /** 055 * Constructs a new empty {@code Bookmark}. 056 */ 057 public Bookmark() { 058 area = null; 059 name = null; 060 } 061 062 /** 063 * Constructs a new unamed {@code Bookmark} for the given area. 064 * @param area The bookmark area 065 */ 066 public Bookmark(Bounds area) { 067 this.area = area; 068 } 069 070 @Override public String toString() { 071 return name; 072 } 073 074 @Override 075 public int compareTo(Bookmark b) { 076 return name.toLowerCase(Locale.ENGLISH).compareTo(b.name.toLowerCase(Locale.ENGLISH)); 077 } 078 079 @Override 080 public int hashCode() { 081 final int prime = 31; 082 int result = 1; 083 result = prime * result + ((area == null) ? 0 : area.hashCode()); 084 result = prime * result + ((name == null) ? 0 : name.hashCode()); 085 return result; 086 } 087 088 @Override 089 public boolean equals(Object obj) { 090 if (this == obj) 091 return true; 092 if (obj == null) 093 return false; 094 if (getClass() != obj.getClass()) 095 return false; 096 Bookmark other = (Bookmark) obj; 097 if (area == null) { 098 if (other.area != null) 099 return false; 100 } else if (!area.equals(other.area)) 101 return false; 102 if (name == null) { 103 if (other.name != null) 104 return false; 105 } else if (!name.equals(other.name)) 106 return false; 107 return true; 108 } 109 110 /** 111 * Returns the bookmark area 112 * @return The bookmark area 113 */ 114 public Bounds getArea() { 115 return area; 116 } 117 118 /** 119 * Returns the bookmark name 120 * @return The bookmark name 121 */ 122 public String getName() { 123 return name; 124 } 125 126 /** 127 * Sets the bookmark name 128 * @param name The bookmark name 129 */ 130 public void setName(String name) { 131 this.name = name; 132 } 133 134 /** 135 * Sets the bookmark area 136 * @param area The bookmark area 137 */ 138 public void setArea(Bounds area) { 139 this.area = area; 140 } 141 } 142 143 /** 144 * Creates a bookmark list as well as the Buttons add and remove. 145 */ 146 public BookmarkList() { 147 setModel(new DefaultListModel<Bookmark>()); 148 load(); 149 setVisibleRowCount(7); 150 setCellRenderer(new BookmarkCellRenderer()); 151 } 152 153 /** 154 * Loads the bookmarks from file. 155 */ 156 public final void load() { 157 DefaultListModel<Bookmark> model = (DefaultListModel<Bookmark>) getModel(); 158 model.removeAllElements(); 159 Collection<Collection<String>> args = Main.pref.getArray("bookmarks", null); 160 if (args != null) { 161 List<Bookmark> bookmarks = new LinkedList<>(); 162 for (Collection<String> entry : args) { 163 try { 164 bookmarks.add(new Bookmark(entry)); 165 } catch (Exception e) { 166 Main.error(tr("Error reading bookmark entry: %s", e.getMessage())); 167 } 168 } 169 Collections.sort(bookmarks); 170 for (Bookmark b : bookmarks) { 171 model.addElement(b); 172 } 173 } 174 } 175 176 /** 177 * Saves all bookmarks to the preferences file 178 */ 179 public final void save() { 180 List<Collection<String>> coll = new LinkedList<>(); 181 for (Object o : ((DefaultListModel<Bookmark>) getModel()).toArray()) { 182 String[] array = new String[5]; 183 Bookmark b = (Bookmark) o; 184 array[0] = b.getName(); 185 Bounds area = b.getArea(); 186 array[1] = String.valueOf(area.getMinLat()); 187 array[2] = String.valueOf(area.getMinLon()); 188 array[3] = String.valueOf(area.getMaxLat()); 189 array[4] = String.valueOf(area.getMaxLon()); 190 coll.add(Arrays.asList(array)); 191 } 192 Main.pref.putArray("bookmarks", coll); 193 } 194 195 static class BookmarkCellRenderer extends JLabel implements ListCellRenderer<BookmarkList.Bookmark> { 196 197 /** 198 * Constructs a new {@code BookmarkCellRenderer}. 199 */ 200 BookmarkCellRenderer() { 201 setOpaque(true); 202 setIcon(ImageProvider.get("dialogs", "bookmark")); 203 } 204 205 protected void renderColor(boolean selected) { 206 if (selected) { 207 setBackground(UIManager.getColor("List.selectionBackground")); 208 setForeground(UIManager.getColor("List.selectionForeground")); 209 } else { 210 setBackground(UIManager.getColor("List.background")); 211 setForeground(UIManager.getColor("List.foreground")); 212 } 213 } 214 215 protected String buildToolTipText(Bookmark b) { 216 Bounds area = b.getArea(); 217 StringBuilder sb = new StringBuilder(128); 218 sb.append("<html>min[latitude,longitude]=<strong>[") 219 .append(area.getMinLat()).append(',').append(area.getMinLon()).append("]</strong>"+ 220 "<br>max[latitude,longitude]=<strong>[") 221 .append(area.getMaxLat()).append(',').append(area.getMaxLon()).append("]</strong>"+ 222 "</html>"); 223 return sb.toString(); 224 } 225 226 @Override 227 public Component getListCellRendererComponent(JList<? extends Bookmark> list, Bookmark value, int index, boolean isSelected, 228 boolean cellHasFocus) { 229 renderColor(isSelected); 230 setText(value.getName()); 231 setToolTipText(buildToolTipText(value)); 232 return this; 233 } 234 } 235}