- Timestamp:
- 2009-11-14T17:59:10+01:00 (15 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
r2439 r2448 811 811 * @throws IllegalArgumentException thrown if other is null. 812 812 * @throws DataIntegrityProblemException thrown if either this is new and other is not, or other is new and this is not 813 * @throws DataIntegrityProblemException thrown if other is new and other.getId() != this.getId()813 * @throws DataIntegrityProblemException thrown if other isn't new and other.getId() != this.getId() 814 814 */ 815 815 public void mergeFrom(OsmPrimitive other) { … … 1025 1025 public abstract void updatePosition(); 1026 1026 1027 /** 1028 * Replies the unique primitive id for this primitive 1029 * 1030 * @return the unique primitive id for this primitive 1031 */ 1032 public PrimitiveId getPrimitiveId() { 1033 return new SimplePrimitiveId(getUniqueId(), getType()); 1034 } 1027 1035 } 1028 1036 -
trunk/src/org/openstreetmap/josm/data/osm/SimplePrimitiveId.java
r2399 r2448 20 20 } 21 21 22 @Override 23 public int hashCode() { 24 final int prime = 31; 25 int result = 1; 26 result = prime * result + (int) (id ^ (id >>> 32)); 27 result = prime * result + ((type == null) ? 0 : type.hashCode()); 28 return result; 29 } 22 30 23 31 @Override 32 public boolean equals(Object obj) { 33 if (this == obj) 34 return true; 35 if (obj == null) 36 return false; 37 if (getClass() != obj.getClass()) 38 return false; 39 SimplePrimitiveId other = (SimplePrimitiveId) obj; 40 if (id != other.id) 41 return false; 42 if (type == null) { 43 if (other.type != null) 44 return false; 45 } else if (!type.equals(other.type)) 46 return false; 47 return true; 48 } 24 49 } -
trunk/src/org/openstreetmap/josm/data/osm/history/History.java
r2242 r2448 9 9 import java.util.Date; 10 10 import java.util.List; 11 import java.util.NoSuchElementException;12 11 13 12 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 14 13 import org.openstreetmap.josm.data.osm.PrimitiveId; 14 import org.openstreetmap.josm.data.osm.SimplePrimitiveId; 15 16 /** 17 * Represents the history of an OSM primitive. The history consists 18 * of a list of object snapshots with a specific version. 19 * 20 */ 15 21 public class History{ 16 22 private static interface FilterPredicate { … … 25 31 } 26 32 } 27 return new History(history.id, out); 28 } 29 33 return new History(history.id, history.type,out); 34 } 35 36 /** the list of object snapshots */ 30 37 private ArrayList<HistoryOsmPrimitive> versions; 31 long id; 32 33 protected History(long id, List<HistoryOsmPrimitive> versions) { 38 /** the object id */ 39 private long id; 40 private OsmPrimitiveType type; 41 42 /** 43 * Creates a new history for an OSM primitive 44 * 45 * @param id the id. >0 required. 46 * @param type the primitive type. Must not be null. 47 * @param versions a list of versions. Can be null. 48 * @throws IllegalArgumentException thrown if id <= 0 49 * @throws IllegalArgumentException if type is null 50 * 51 */ 52 protected History(long id, OsmPrimitiveType type, List<HistoryOsmPrimitive> versions) { 53 if (id <= 0) 54 throw new IllegalArgumentException(tr("Parameter ''{0}'' > 0 expected, got {1}", "id", id)); 55 if (type == null) 56 throw new IllegalArgumentException(tr("Parameter ''{0}'' must not be null", "type")); 34 57 this.id = id; 58 this.type = type; 35 59 this.versions = new ArrayList<HistoryOsmPrimitive>(); 36 this.versions.addAll(versions); 60 if (versions != null) { 61 this.versions.addAll(versions); 62 } 37 63 } 38 64 … … 47 73 } 48 74 ); 49 return new History(id, copy);75 return new History(id, type, copy); 50 76 } 51 77 … … 60 86 } 61 87 ); 62 return new History(id, copy);88 return new History(id, type,copy); 63 89 } 64 90 … … 139 165 public long getId() { 140 166 return id; 167 } 168 169 /** 170 * Replies the primitive id for this history. 171 * 172 * @return the primitive id 173 */ 174 public PrimitiveId getPrimitmiveId() { 175 return new SimplePrimitiveId(id, type); 141 176 } 142 177 … … 149 184 } 150 185 186 /** 187 * Replies the history primitive with version <code>version</code>. null, 188 * if no such primitive exists. 189 * 190 * @param version the version 191 * @return the history primitive with version <code>version</code> 192 */ 151 193 public HistoryOsmPrimitive getByVersion(long version) { 152 194 for (HistoryOsmPrimitive primitive: versions) { … … 154 196 return primitive; 155 197 } 156 throw new NoSuchElementException(tr("There's no primitive with version {0} in this history.", version));198 return null; 157 199 } 158 200 159 201 public HistoryOsmPrimitive getByDate(Date date) { 160 sortAscending();161 162 if ( versions.isEmpty())163 throw new NoSuchElementException(tr("There's no version valid at date ''{0}'' in this history.", date));164 if ( get(0).getTimestamp().compareTo(date)> 0)165 throw new NoSuchElementException(tr("There's no version valid at date ''{0}'' in this history.", date));166 for (int i = 1; i < versions.size();i++) {167 if ( get(i-1).getTimestamp().compareTo(date) <= 0168 && get(i).getTimestamp().compareTo(date) >= 0)169 return get(i);170 } 171 return getLatest();202 History h = sortAscending(); 203 204 if (h.versions.isEmpty()) 205 return null; 206 if (h.get(0).getTimestamp().compareTo(date)> 0) 207 return null; 208 for (int i = 1; i < h.versions.size();i++) { 209 if (h.get(i-1).getTimestamp().compareTo(date) <= 0 210 && h.get(i).getTimestamp().compareTo(date) >= 0) 211 return h.get(i); 212 } 213 return h.getLatest(); 172 214 } 173 215 … … 180 222 public HistoryOsmPrimitive getEarliest() { 181 223 if (isEmpty()) 182 throw new NoSuchElementException(tr("No earliest version found. History is empty."));224 return null; 183 225 return sortAscending().versions.get(0); 184 226 } … … 186 228 public HistoryOsmPrimitive getLatest() { 187 229 if (isEmpty()) 188 throw new NoSuchElementException(tr("No latest version found. History is empty."));230 return null; 189 231 return sortDescending().versions.get(0); 190 232 } … … 199 241 200 242 public OsmPrimitiveType getType() { 201 if (isEmpty()) 202 throw new NoSuchElementException(tr("No type found. History is empty.")); 203 return versions.get(0).getType(); 243 return type; 204 244 } 205 245 } -
trunk/src/org/openstreetmap/josm/data/osm/history/HistoryDataSet.java
r2163 r2448 6 6 import java.util.ArrayList; 7 7 import java.util.HashMap; 8 import java.util.NoSuchElementException;9 8 import java.util.concurrent.CopyOnWriteArrayList; 9 import java.util.logging.Logger; 10 11 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 12 import org.openstreetmap.josm.data.osm.PrimitiveId; 13 import org.openstreetmap.josm.data.osm.SimplePrimitiveId; 10 14 11 15 /** … … 15 19 */ 16 20 public class HistoryDataSet { 21 private final static Logger logger = Logger.getLogger(HistoryDataSet.class.getName()); 17 22 18 23 /** the unique instance */ … … 32 37 33 38 /** the history data */ 34 private HashMap< Long, ArrayList<HistoryOsmPrimitive>> data;39 private HashMap<PrimitiveId, ArrayList<HistoryOsmPrimitive>> data; 35 40 private CopyOnWriteArrayList<HistoryDataSetListener> listeners; 36 41 37 42 public HistoryDataSet() { 38 data = new HashMap< Long, ArrayList<HistoryOsmPrimitive>>();43 data = new HashMap<PrimitiveId, ArrayList<HistoryOsmPrimitive>>(); 39 44 listeners = new CopyOnWriteArrayList<HistoryDataSetListener>(); 40 45 } … … 56 61 } 57 62 58 protected void fireHistoryUpdated( longid) {63 protected void fireHistoryUpdated(SimplePrimitiveId id) { 59 64 for (HistoryDataSetListener l : listeners) { 60 65 l.historyUpdated(this, id); … … 64 69 /** 65 70 * Replies the history primitive for the primitive with id <code>id</code> 66 * and version <code>version</code> 71 * and version <code>version</code>. null, if no such primitive exists. 67 72 * 68 * @param id the id of the primitive 69 * @param version the version of the primitive 70 * @return the history primitive for the primitive with id <code>id</code> 71 * and version <code>version</code> 72 * @throws NoSuchElementException thrown if this dataset doesn't include the respective 73 * history primitive 73 * @param id the id of the primitive. > 0 required. 74 * @param type the primitive type. Must not be null. 75 * @param version the version of the primitive. > 0 required 76 * @return the history primitive for the primitive with id <code>id</code>, 77 * type <code>type</code>, and version <code>version</code> 74 78 */ 75 public HistoryOsmPrimitive get(long id, long version) throws NoSuchElementException{ 76 ArrayList<HistoryOsmPrimitive> versions = data.get(id); 79 public HistoryOsmPrimitive get(long id, OsmPrimitiveType type, long version){ 80 if (id <= 0) 81 throw new IllegalArgumentException(tr("Parameter ''{0}'' > 0 expected, got {1}", "id", id)); 82 if (type == null) 83 throw new IllegalArgumentException(tr("Parameter ''{0}'' must not be null", "type")); 84 if (version <= 0) 85 throw new IllegalArgumentException(tr("Parameter ''{0}'' > 0 expected, got {1}", "version", version)); 86 87 SimplePrimitiveId pid = new SimplePrimitiveId(id, type); 88 ArrayList<HistoryOsmPrimitive> versions = data.get(pid); 77 89 if (versions == null) 78 throw new NoSuchElementException(tr("Didn't find an primitive with id {0} in this dataset", id)); 79 90 return null; 80 91 for (HistoryOsmPrimitive primitive: versions) { 81 92 if (primitive.matches(id, version)) 82 93 return primitive; 83 94 } 84 throw new NoSuchElementException(tr("Didn't find an primitive with id {0} and version {1} in this dataset", id, version));95 return null; 85 96 } 86 97 … … 91 102 */ 92 103 public void put(HistoryOsmPrimitive primitive) { 93 if (data.get(primitive.getId()) == null) { 94 data.put(primitive.getId(), new ArrayList<HistoryOsmPrimitive>()); 104 SimplePrimitiveId id = new SimplePrimitiveId(primitive.getId(), primitive.getType()); 105 if (data.get(id) == null) { 106 data.put(id, new ArrayList<HistoryOsmPrimitive>()); 95 107 } 96 data.get( primitive.getId()).add(primitive);97 fireHistoryUpdated( primitive.getId());108 data.get(id).add(primitive); 109 fireHistoryUpdated(id); 98 110 } 99 111 100 112 /** 101 113 * Replies the history for a given primitive with id <code>id</code> 114 * and type <code>type</code>. 102 115 * 103 * @param id the id 104 * @return the history 116 * @param id the id the if of the primitive. > 0 required 117 * @param type the type of the primitive. Must not be null. 118 * @return the history. null, if there isn't a history for <code>id</code> and 119 * <code>type</code>. 120 * @throws IllegalArgumentException thrown if id <= 0 121 * @throws IllegalArgumentException thrown if type is null 105 122 */ 106 public History getHistory(long id) { 107 ArrayList<HistoryOsmPrimitive> versions = data.get(id); 123 public History getHistory(long id, OsmPrimitiveType type) throws IllegalArgumentException{ 124 if (id <= 0) 125 throw new IllegalArgumentException(tr("Parameter ''{0}'' > 0 expected, got {1}", "id", id)); 126 if (type == null) 127 throw new IllegalArgumentException(tr("Parameter ''{0}'' must not be null", "type")); 128 SimplePrimitiveId pid = new SimplePrimitiveId(id, type); 129 return getHistory(pid); 130 } 131 132 /** 133 * Replies the history for a primitive with id <code>id</code>. null, if no 134 * such history exists. 135 * 136 * @param pid the primitive id. Must not be null. 137 * @return the history for a primitive with id <code>id</code>. null, if no 138 * such history exists 139 * @throws IllegalArgumentException thrown if pid is null 140 */ 141 public History getHistory(PrimitiveId pid) throws IllegalArgumentException{ 142 if (pid == null) 143 throw new IllegalArgumentException(tr("Parameter ''{0}'' must not be null", "pid")); 144 ArrayList<HistoryOsmPrimitive> versions = data.get(pid); 108 145 if (versions == null) 109 146 return null; 110 return new History( id, versions);147 return new History(pid.getUniqueId(), pid.getType(), versions); 111 148 } 112 149 … … 119 156 if (other == null) 120 157 return; 121 for ( Longid : other.data.keySet()) {158 for (PrimitiveId id : other.data.keySet()) { 122 159 this.data.put(id, other.data.get(id)); 123 160 } 124 fireHistoryUpdated( 0);161 fireHistoryUpdated(null); 125 162 } 126 163 } -
trunk/src/org/openstreetmap/josm/data/osm/history/HistoryDataSetListener.java
r2019 r2448 2 2 package org.openstreetmap.josm.data.osm.history; 3 3 4 import org.openstreetmap.josm.data.osm.PrimitiveId; 5 4 6 public interface HistoryDataSetListener { 5 void historyUpdated(HistoryDataSet source, long primitiveId);7 void historyUpdated(HistoryDataSet source, PrimitiveId id); 6 8 } -
trunk/src/org/openstreetmap/josm/data/osm/history/HistoryOsmPrimitive.java
r2242 r2448 10 10 11 11 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 12 import org.openstreetmap.josm.data.osm.PrimitiveId; 13 import org.openstreetmap.josm.data.osm.SimplePrimitiveId; 12 14 13 15 /** … … 45 47 * @param user the user (! null required) 46 48 * @param uid the user id (> 0 required) 47 * @param changesetId the changeset id ( > 0 required)49 * @param changesetId the changeset id (may be null if the changeset isn't known) 48 50 * @param timestamp the timestamp (! null required) 49 51 * … … 53 55 ensurePositiveLong(id, "id"); 54 56 ensurePositiveLong(version, "version"); 55 if(uid != -1) /* allow -1 for anonymous users */57 if(uid != -1) { 56 58 ensurePositiveLong(uid, "uid"); 57 ensurePositiveLong(changesetId, "changesetId");59 } 58 60 ensureNotNull(user, "user"); 59 61 ensureNotNull(timestamp, "timestamp"); … … 63 65 this.user = user; 64 66 this.uid = uid; 67 // FIXME: restrict to IDs > 0 as soon as OsmPrimitive holds the 68 // changeset id too 65 69 this.changesetId = changesetId; 66 70 this.timestamp = timestamp; … … 71 75 return id; 72 76 } 77 78 public PrimitiveId getPrimitiveId() { 79 return new SimplePrimitiveId(id, getType()); 80 } 81 73 82 public boolean isVisible() { 74 83 return visible; … … 103 112 public int compareTo(HistoryOsmPrimitive o) { 104 113 if (this.id != o.id) 105 throw new ClassCastException(tr("Can' t compare primitive with ID ''{0}'' to primitive with ID ''{1}''.", o.id, this.id));114 throw new ClassCastException(tr("Can''t compare primitive with ID ''{0}'' to primitive with ID ''{1}''.", o.id, this.id)); 106 115 return new Long(this.version).compareTo(o.version); 107 116 } … … 121 130 public Map<String,String> getTags() { 122 131 return Collections.unmodifiableMap(tags); 132 } 133 134 /** 135 * Sets the tags for this history primitive. Removes all 136 * tags if <code>tags</code> is null. 137 * 138 * @param tags the tags. May be null. 139 */ 140 public void setTags(Map<String,String> tags) { 141 if (tags == null) { 142 this.tags = new HashMap<String, String>(); 143 } else { 144 this.tags = new HashMap<String, String>(tags); 145 } 123 146 } 124 147 -
trunk/src/org/openstreetmap/josm/gui/dialogs/HistoryDialog.java
r2273 r2448 37 37 import org.openstreetmap.josm.data.osm.DataSet; 38 38 import org.openstreetmap.josm.data.osm.OsmPrimitive; 39 import org.openstreetmap.josm.data.osm.PrimitiveId; 39 40 import org.openstreetmap.josm.data.osm.history.History; 40 41 import org.openstreetmap.josm.data.osm.history.HistoryDataSet; … … 42 43 import org.openstreetmap.josm.gui.OsmPrimitivRenderer; 43 44 import org.openstreetmap.josm.gui.SideButton; 44 import org.openstreetmap.josm.gui.history.HistoryBrowserDialog;45 45 import org.openstreetmap.josm.gui.history.HistoryBrowserDialogManager; 46 46 import org.openstreetmap.josm.gui.history.HistoryLoadTask; … … 136 136 } 137 137 138 public void historyUpdated(HistoryDataSet source, longprimitiveId) {138 public void historyUpdated(HistoryDataSet source, PrimitiveId primitiveId) { 139 139 model.refresh(); 140 140 } … … 206 206 207 207 public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) { 208 refresh(); 208 data.clear(); 209 selectionModel.clearSelection(); 210 if (newSelection == null || newSelection.isEmpty()) return; 211 for (OsmPrimitive primitive: newSelection) { 212 if (primitive.isNew()) { 213 continue; 214 } 215 data.add(primitive); 216 } 217 fireTableDataChanged(); 218 selectionModel.addSelectionInterval(0, data.size()-1); 209 219 } 210 220 … … 297 307 ArrayList<OsmPrimitive> ret = new ArrayList<OsmPrimitive>(primitives.size()); 298 308 for (OsmPrimitive p: primitives) { 299 if (HistoryDataSet.getInstance().getHistory(p.get Id()) == null) {309 if (HistoryDataSet.getInstance().getHistory(p.getPrimitiveId()) == null) { 300 310 ret.add(p); 301 311 } 302 312 } 303 313 return ret; 304 }305 306 /**307 * shows the {@see HistoryBrowserDialog} for a given {@see History}308 *309 * @param h the history. Must not be null.310 * @exception IllegalArgumentException thrown, if h is null311 */312 protected void showHistory(History h) throws IllegalArgumentException {313 if (h == null)314 throw new IllegalArgumentException(tr("Parameter ''{0}'' must not be null.", "h"));315 if (HistoryBrowserDialogManager.getInstance().existsDialog(h.getId())) {316 HistoryBrowserDialogManager.getInstance().show(h.getId());317 } else {318 HistoryBrowserDialog dialog = new HistoryBrowserDialog(h);319 HistoryBrowserDialogManager.getInstance().show(h.getId(), dialog);320 }321 314 } 322 315 … … 332 325 public void run() { 333 326 for (OsmPrimitive p : primitives) { 334 History h = HistoryDataSet.getInstance().getHistory(p.get Id());327 History h = HistoryDataSet.getInstance().getHistory(p.getPrimitiveId()); 335 328 if (h == null) { 336 329 continue; 337 330 } 338 showHistory(h);331 HistoryBrowserDialogManager.getInstance().show(h); 339 332 } 340 333 } -
trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTable.java
r2348 r2448 20 20 import javax.swing.event.ListSelectionEvent; 21 21 import javax.swing.event.ListSelectionListener; 22 import javax.swing.table.TableColumnModel;23 22 24 23 import org.openstreetmap.josm.Main; 25 24 import org.openstreetmap.josm.actions.AutoScaleAction; 26 import org.openstreetmap.josm.data.osm.DataSet;27 25 import org.openstreetmap.josm.data.osm.OsmPrimitive; 28 26 import org.openstreetmap.josm.gui.layer.Layer; … … 191 189 public ZoomToAction() { 192 190 putValue(NAME, tr("Zoom to")); 193 putValue(SHORT_DESCRIPTION, tr("Zoom to primitivethe first selected member refers to"));191 putValue(SHORT_DESCRIPTION, tr("Zoom to the object the first selected member refers to")); 194 192 updateEnabledState(); 195 193 } … … 220 218 } 221 219 setEnabled(true); 222 putValue(SHORT_DESCRIPTION, tr("Zoom to primitivethe first selected member refers to"));220 putValue(SHORT_DESCRIPTION, tr("Zoom to the object the first selected member refers to")); 223 221 } 224 222 -
trunk/src/org/openstreetmap/josm/gui/help/HelpBrowser.java
r2308 r2448 175 175 * @return the current URL 176 176 */ 177 178 177 179 public String getUrl() { 178 180 return url; -
trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserDialog.java
r2318 r2448 2 2 package org.openstreetmap.josm.gui.history; 3 3 4 import static org.openstreetmap.josm.gui.help.HelpUtil.ht; 4 5 import static org.openstreetmap.josm.tools.I18n.marktr; 5 6 import static org.openstreetmap.josm.tools.I18n.tr; … … 17 18 18 19 import org.openstreetmap.josm.Main; 20 import org.openstreetmap.josm.data.osm.PrimitiveId; 19 21 import org.openstreetmap.josm.data.osm.history.History; 20 22 import org.openstreetmap.josm.data.osm.history.HistoryDataSet; … … 24 26 import org.openstreetmap.josm.gui.help.HelpUtil; 25 27 import org.openstreetmap.josm.tools.ImageProvider; 26 import static org.openstreetmap.josm.gui.help.HelpUtil.ht;27 28 28 29 /** … … 35 36 /** the embedded browser */ 36 37 private HistoryBrowser browser; 38 private CloseAction closeAction; 37 39 38 40 /** … … 44 46 String title = ""; 45 47 switch(h.getEarliest().getType()) { 46 47 48 48 case NODE: title = marktr("History for node {0}"); break; 49 case WAY: title = marktr("History for way {0}"); break; 50 case RELATION: title = marktr("History for relation {0}"); break; 49 51 } 50 52 setTitle(tr( … … 70 72 pnl.add(btn); 71 73 72 btn = new SideButton( new CloseAction());74 btn = new SideButton(closeAction = new CloseAction()); 73 75 btn.setName("btn.close"); 74 76 pnl.add(btn); … … 106 108 } 107 109 108 public void historyUpdated(HistoryDataSet source, long primitiveId) { 109 if (primitiveId == browser.getHistory().getId()) { 110 public void historyUpdated(HistoryDataSet source, PrimitiveId primitiveId) { 111 if (primitiveId == null) { 112 browser.populate(source.getHistory(browser.getHistory().getPrimitmiveId())); 113 } else if (primitiveId.equals(browser.getHistory().getPrimitmiveId())) { 110 114 browser.populate(source.getHistory(primitiveId)); 111 } else if (primitiveId == 0) {112 browser.populate(source.getHistory(browser.getHistory().getId()));113 115 } 116 } 117 118 public void unlinkAsListener() { 119 getHistoryBrowser().getModel().unlinkAsListener(); 114 120 } 115 121 … … 121 127 } 122 128 123 public void actionPerformed(ActionEvent e) { 129 public void run() { 130 getHistoryBrowser().getModel().unlinkAsListener(); 124 131 HistoryDataSet.getInstance().removeHistoryDataSetListener(HistoryBrowserDialog.this); 125 132 HistoryBrowserDialogManager.getInstance().hide(HistoryBrowserDialog.this); 133 } 134 135 public void actionPerformed(ActionEvent e) { 136 run(); 126 137 } 127 138 } … … 144 155 @Override 145 156 public void windowClosing(WindowEvent e) { 146 HistoryDataSet.getInstance().removeHistoryDataSetListener(HistoryBrowserDialog.this); 147 HistoryBrowserDialogManager.getInstance().hide(HistoryBrowserDialog.this); 157 closeAction.run(); 148 158 } 149 159 } -
trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserDialogManager.java
r2019 r2448 4 4 import java.awt.Dimension; 5 5 import java.awt.Point; 6 import java.util.ArrayList; 6 7 import java.util.HashMap; 7 8 import java.util.Map; 8 9 10 import org.openstreetmap.josm.Main; 11 import org.openstreetmap.josm.data.osm.history.History; 12 import org.openstreetmap.josm.gui.layer.Layer; 13 import org.openstreetmap.josm.gui.layer.Layer.LayerChangeListener; 9 14 import org.openstreetmap.josm.tools.WindowGeometry; 10 15 11 public class HistoryBrowserDialogManager {16 public class HistoryBrowserDialogManager implements LayerChangeListener { 12 17 static private HistoryBrowserDialogManager instance; 13 18 static public HistoryBrowserDialogManager getInstance() { … … 22 27 protected HistoryBrowserDialogManager() { 23 28 dialogs = new HashMap<Long, HistoryBrowserDialog>(); 29 Layer.listeners.add(this); 24 30 } 25 31 … … 79 85 dialog.dispose(); 80 86 } 87 88 /** 89 * Hides and destroys all currently visible history browser dialogs 90 * 91 */ 92 public void hideAll() { 93 ArrayList<HistoryBrowserDialog> dialogs = new ArrayList<HistoryBrowserDialog>(); 94 dialogs.addAll(this.dialogs.values()); 95 for (HistoryBrowserDialog dialog: dialogs) { 96 dialog.unlinkAsListener(); 97 hide(dialog); 98 } 99 } 100 101 public void show(History h) { 102 if (h == null) 103 return; 104 if (existsDialog(h.getId())) { 105 show(h.getId()); 106 } else { 107 HistoryBrowserDialog dialog = new HistoryBrowserDialog(h); 108 show(h.getId(), dialog); 109 } 110 } 111 112 /* ----------------------------------------------------------------------------- */ 113 /* LayerChangeListener */ 114 /* ----------------------------------------------------------------------------- */ 115 public void activeLayerChange(Layer oldLayer, Layer newLayer) {} 116 public void layerAdded(Layer newLayer) {} 117 118 public void layerRemoved(Layer oldLayer) { 119 // remove all history browsers if the number of layers drops to 0 120 // 121 if (Main.map.mapView.getNumLayers() == 0) { 122 hideAll(); 123 } 124 } 81 125 } -
trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java
r2243 r2448 5 5 6 6 import java.util.ArrayList; 7 import java.util.Collection; 7 8 import java.util.Collections; 8 9 import java.util.HashSet; … … 12 13 import javax.swing.table.DefaultTableModel; 13 14 14 import org.openstreetmap.josm.data.coor.CoordinateFormat; 15 import org.openstreetmap.josm.data.coor.LatLon; 15 import org.openstreetmap.josm.Main; 16 import org.openstreetmap.josm.data.osm.DataSetListener; 17 import org.openstreetmap.josm.data.osm.Node; 18 import org.openstreetmap.josm.data.osm.OsmPrimitive; 16 19 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 20 import org.openstreetmap.josm.data.osm.PrimitiveId; 21 import org.openstreetmap.josm.data.osm.Relation; 22 import org.openstreetmap.josm.data.osm.RelationMember; 23 import org.openstreetmap.josm.data.osm.SimplePrimitiveId; 24 import org.openstreetmap.josm.data.osm.Way; 17 25 import org.openstreetmap.josm.data.osm.history.History; 18 26 import org.openstreetmap.josm.data.osm.history.HistoryNode; … … 20 28 import org.openstreetmap.josm.data.osm.history.HistoryRelation; 21 29 import org.openstreetmap.josm.data.osm.history.HistoryWay; 30 import org.openstreetmap.josm.data.osm.visitor.AbstractVisitor; 31 import org.openstreetmap.josm.gui.layer.DataChangeListener; 32 import org.openstreetmap.josm.gui.layer.Layer; 33 import org.openstreetmap.josm.gui.layer.OsmDataLayer; 34 import org.openstreetmap.josm.gui.layer.Layer.LayerChangeListener; 22 35 23 36 /** 24 37 * This is the model used by the history browser. 25 38 * 26 * The state this model managesconsists of the following elements:39 * The model state consists of the following elements: 27 40 * <ul> 28 41 * <li>the {@see History} of a specific {@see OsmPrimitive}</li> … … 46 59 * @see HistoryBrowser 47 60 */ 48 public class HistoryBrowserModel extends Observable {61 public class HistoryBrowserModel extends Observable implements LayerChangeListener, DataSetListener, DataChangeListener { 49 62 50 63 private static Logger logger = Logger.getLogger(HistoryBrowserModel.class.getName()); … … 54 67 private HistoryOsmPrimitive reference; 55 68 private HistoryOsmPrimitive current; 69 /** 70 * latest isn't a reference of history. It's a clone of the currently edited 71 * {@see OsmPrimitive} in the current edit layer. 72 */ 73 private HistoryOsmPrimitive latest; 56 74 57 75 private VersionTableModel versionTableModel; … … 63 81 private RelationMemberTableModel referenceRelationMemberTableModel; 64 82 83 /** 84 * constructor 85 */ 65 86 public HistoryBrowserModel() { 66 87 versionTableModel = new VersionTableModel(); … … 71 92 currentRelationMemberTableModel = new RelationMemberTableModel(PointInTimeType.CURRENT_POINT_IN_TIME); 72 93 referenceRelationMemberTableModel = new RelationMemberTableModel(PointInTimeType.REFERENCE_POINT_IN_TIME); 73 } 74 94 95 if (getEditLayer() != null) { 96 getEditLayer().data.addDataSetListener(this); 97 getEditLayer().listenerDataChanged.add(this); 98 } 99 Layer.listeners.add(this); 100 101 } 102 103 /** 104 * Creates a new history browser model for a given history. 105 * 106 * @param history the history. Must not be null. 107 * @throws IllegalArgumentException thrown if history is null 108 */ 75 109 public HistoryBrowserModel(History history) { 76 110 this(); 111 if (history == null) 112 throw new IllegalArgumentException(tr("Parameter ''{0}'' must not be null", "history")); 77 113 setHistory(history); 114 } 115 116 /** 117 * Replies the current edit layer; null, if there isn't a current edit layer 118 * of type {@see OsmDataLayer}. 119 * 120 * @return the current edit layer 121 */ 122 protected OsmDataLayer getEditLayer() { 123 try { 124 return Main.map.mapView.getEditLayer(); 125 } catch(NullPointerException e) { 126 return null; 127 } 78 128 } 79 129 … … 84 134 public History getHistory() { 85 135 return history; 136 } 137 138 protected boolean hasNewNodes(Way way) { 139 for (Node n: way.getNodes()) { 140 if (n.isNew()) return true; 141 } 142 return false; 143 } 144 protected boolean canShowAsLatest(OsmPrimitive primitive) { 145 if (primitive == null) return false; 146 if (primitive.isNew()) return false; 147 if (history == null) return false; 148 // only show latest of the same version if it is 149 // modified 150 if (history.getByVersion(primitive.getVersion()) != null) 151 return primitive.isModified(); 152 153 // latest has a higher version than one of the primitives 154 // in the history (probably because the history got out of sync 155 // with uploaded data) -> show the primitive as latest 156 return true; 86 157 } 87 158 … … 97 168 current = history.getEarliest(); 98 169 reference = history.getEarliest(); 170 setLatest(null); 171 if (getEditLayer() != null) { 172 OsmPrimitive p = getEditLayer().data.getPrimitiveById(history.getId(), history.getType()); 173 if (canShowAsLatest(p)) { 174 HistoryOsmPrimitive latest = new HistoryPrimitiveBuilder().build(p); 175 setLatest(latest); 176 } 177 } 99 178 } 100 179 initTagTableModels(); 101 180 fireModelChange(); 102 181 } 103 104 182 105 183 protected void fireModelChange() { … … 177 255 } 178 256 257 /** 258 * Sets the {@see HistoryOsmPrimitive} which plays the role of a reference point 259 * in time (see {@see PointInTimeType}). 260 * 261 * @param reference the reference history primitive. Must not be null. 262 * @throws IllegalArgumentException thrown if reference is null 263 * @throws IllegalStateException thrown if this model isn't a assigned a history yet 264 * @throws IllegalArgumentException if reference isn't an history primitive for the history managed by this mode 265 * 266 * @see #setHistory(History) 267 * @see PointInTimeType 268 */ 179 269 public void setReferencePointInTime(HistoryOsmPrimitive reference) throws IllegalArgumentException, IllegalStateException{ 180 270 if (reference == null) … … 196 286 } 197 287 288 /** 289 * Sets the {@see HistoryOsmPrimitive} which plays the role of the current point 290 * in time (see {@see PointInTimeType}). 291 * 292 * @param reference the reference history primitive. Must not be null. 293 * @throws IllegalArgumentException thrown if reference is null 294 * @throws IllegalStateException thrown if this model isn't a assigned a history yet 295 * @throws IllegalArgumentException if reference isn't an history primitive for the history managed by this mode 296 * 297 * @see #setHistory(History) 298 * @see PointInTimeType 299 */ 198 300 public void setCurrentPointInTime(HistoryOsmPrimitive current) throws IllegalArgumentException, IllegalStateException{ 199 301 if (current == null) … … 252 354 253 355 /** 356 * Returns true if <code>primitive</code> is the latest primitive 357 * representing the version currently edited in the current data 358 * layer. 359 * 360 * @param primitive the primitive to check 361 * @return true if <code>primitive</code> is the latest primitive 362 */ 363 public boolean isLatest(HistoryOsmPrimitive primitive) { 364 if (primitive == null) return false; 365 return primitive == latest; 366 } 367 368 /** 254 369 * The table model for the list of versions in the current history 255 370 * 256 371 */ 257 public class VersionTableModel extends DefaultTableModel 372 public class VersionTableModel extends DefaultTableModel{ 258 373 259 374 private VersionTableModel() { … … 264 379 if (history == null) 265 380 return 0; 266 return history.getNumVersions(); 381 int ret = history.getNumVersions(); 382 if (latest != null) { 383 ret++; 384 } 385 return ret; 267 386 } 268 387 … … 271 390 if(history == null) 272 391 return null; 273 return history.get(row); 392 if (row < history.getNumVersions()) 393 return history.get(row); 394 if (row == history.getNumVersions()) 395 return latest; 396 return null; 274 397 } 275 398 … … 281 404 public void setReferencePointInTime(int row) { 282 405 if (history == null) return; 406 if (row == history.getNumVersions()) { 407 if (latest != null) { 408 HistoryBrowserModel.this.setReferencePointInTime(latest); 409 } 410 return; 411 } 283 412 if (row < 0 || row > history.getNumVersions()) return; 284 413 HistoryOsmPrimitive reference = history.get(row); … … 288 417 public void setCurrentPointInTime(int row) { 289 418 if (history == null) return; 419 if (row == history.getNumVersions()) { 420 if (latest != null) { 421 HistoryBrowserModel.this.setCurrentPointInTime(latest); 422 } 423 return; 424 } 290 425 if (row < 0 || row > history.getNumVersions()) return; 291 426 HistoryOsmPrimitive current = history.get(row); … … 295 430 public boolean isReferencePointInTime(int row) { 296 431 if (history == null) return false; 432 if (row == history.getNumVersions()) 433 return latest == reference; 297 434 if (row < 0 || row > history.getNumVersions()) return false; 298 435 HistoryOsmPrimitive p = history.get(row); 299 return p .equals(reference);436 return p == reference; 300 437 } 301 438 302 439 public HistoryOsmPrimitive getPrimitive(int row) { 303 440 return history.get(row); 441 } 442 443 public boolean isLatest(int row) { 444 return row >= history.getNumVersions(); 445 } 446 447 public OsmPrimitive getLatest() { 448 if (latest == null) return null; 449 if (getEditLayer() == null) return null; 450 OsmPrimitive p = getEditLayer().data.getPrimitiveById(latest.getId(), latest.getType()); 451 return p; 304 452 } 305 453 } … … 467 615 return null; 468 616 return way.getNodes().get(row); 617 } 618 619 public PrimitiveId getNodeId(int row) { 620 HistoryWay way = getWay(); 621 if (way == null) return null; 622 if (row > way.getNumNodes()) return null; 623 return new SimplePrimitiveId(way.getNodeId(row), OsmPrimitiveType.NODE); 469 624 } 470 625 … … 587 742 } 588 743 } 744 745 protected void setLatest(HistoryOsmPrimitive latest) { 746 if (latest == null) { 747 if (this.current == this.latest) { 748 this.current = history.getLatest(); 749 } 750 if (this.reference == this.latest) { 751 this.current = history.getLatest(); 752 } 753 this.latest = null; 754 } else { 755 if (this.current == this.latest) { 756 this.current = latest; 757 } 758 if (this.reference == this.latest) { 759 this.reference = latest; 760 } 761 this.latest = latest; 762 } 763 fireModelChange(); 764 } 765 766 /** 767 * Removes this model as listener for data change and layer change 768 * events. 769 * 770 */ 771 public void unlinkAsListener() { 772 if (getEditLayer() != null) { 773 getEditLayer().data.removeDataSetListener(this); 774 } 775 Layer.listeners.remove(this); 776 777 } 778 779 /* ---------------------------------------------------------------------- */ 780 /* DataSetListener */ 781 /* ---------------------------------------------------------------------- */ 782 public void nodeMoved(Node node) { 783 if (!node.isNew() && node.getId() == history.getId()) { 784 setLatest(new HistoryPrimitiveBuilder().build(node)); 785 } 786 } 787 788 public void primtivesAdded(Collection<? extends OsmPrimitive> added) { 789 if (added == null || added.isEmpty()) return; 790 for (OsmPrimitive p: added) { 791 if (canShowAsLatest(p)) { 792 setLatest(new HistoryPrimitiveBuilder().build(p)); 793 } 794 } 795 } 796 797 public void primtivesRemoved(Collection<? extends OsmPrimitive> removed) { 798 if (removed == null || removed.isEmpty()) return; 799 for (OsmPrimitive p: removed) { 800 if (!p.isNew() && p.getId() == history.getId()) { 801 setLatest(null); 802 } 803 } 804 } 805 806 public void relationMembersChanged(Relation r) { 807 if (!r.isNew() && r.getId() == history.getId()) { 808 setLatest(new HistoryPrimitiveBuilder().build(r)); 809 } 810 } 811 812 public void tagsChanged(OsmPrimitive prim) { 813 if (!prim.isNew() && prim.getId() == history.getId()) { 814 setLatest(new HistoryPrimitiveBuilder().build(prim)); 815 } 816 } 817 818 public void wayNodesChanged(Way way) { 819 if (!way.isNew() && way.getId() == history.getId()) { 820 setLatest(new HistoryPrimitiveBuilder().build(way)); 821 } 822 } 823 824 /* ---------------------------------------------------------------------- */ 825 /* DataChangeListener */ 826 /* ---------------------------------------------------------------------- */ 827 public void dataChanged(OsmDataLayer l) { 828 if (l != getEditLayer()) return; 829 OsmPrimitive primitive = l.data.getPrimitiveById(history.getId(), history.getType()); 830 HistoryOsmPrimitive latest; 831 if (canShowAsLatest(primitive)) { 832 latest = new HistoryPrimitiveBuilder().build(primitive); 833 } else { 834 latest = null; 835 } 836 setLatest(latest); 837 fireModelChange(); 838 } 839 840 /* ---------------------------------------------------------------------- */ 841 /* LayerChangeListener */ 842 /* ---------------------------------------------------------------------- */ 843 public void activeLayerChange(Layer oldLayer, Layer newLayer) { 844 if (oldLayer != null && oldLayer instanceof OsmDataLayer) { 845 OsmDataLayer l = (OsmDataLayer)oldLayer; 846 l.data.removeDataSetListener(this); 847 l.listenerDataChanged.remove(this); 848 } 849 if (newLayer == null || ! (newLayer instanceof OsmDataLayer)) { 850 latest = null; 851 fireModelChange(); 852 return; 853 } 854 OsmDataLayer l = (OsmDataLayer)newLayer; 855 l.data.addDataSetListener(this); 856 l.listenerDataChanged.add(this); 857 OsmPrimitive primitive = l.data.getPrimitiveById(history.getId(), history.getType()); 858 HistoryOsmPrimitive latest; 859 if (canShowAsLatest(primitive)) { 860 latest = new HistoryPrimitiveBuilder().build(primitive); 861 } else { 862 latest = null; 863 } 864 setLatest(latest); 865 fireModelChange(); 866 } 867 868 public void layerAdded(Layer newLayer) {} 869 public void layerRemoved(Layer oldLayer) {} 870 871 /** 872 * Creates a {@see HistoryOsmPrimitive} from a {@see OsmPrimitive} 873 * 874 */ 875 class HistoryPrimitiveBuilder extends AbstractVisitor { 876 private HistoryOsmPrimitive clone; 877 878 public void visit(Node n) { 879 clone = new HistoryNode(n.getId(), n.getVersion(), n.isVisible(),n.getUser().getName(), n.getUser().getId(), 0, n.getTimestamp(), n.getCoor()); 880 clone.setTags(n.getKeys()); 881 } 882 883 public void visit(Relation r) { 884 clone = new HistoryRelation(r.getId(), r.getVersion(), r.isVisible(),r.getUser().getName(), r.getUser().getId(), 0, r.getTimestamp()); 885 clone.setTags(r.getKeys()); 886 HistoryRelation hr = (HistoryRelation)clone; 887 for (RelationMember rm : r.getMembers()) { 888 hr.addMember(new org.openstreetmap.josm.data.osm.history.RelationMember(rm.getRole(), rm.getType(), rm.getUniqueId())); 889 } 890 } 891 892 public void visit(Way w) { 893 clone = new HistoryWay(w.getId(), w.getVersion(), w.isVisible(),w.getUser().getName(), w.getUser().getId(), 0, w.getTimestamp()); 894 clone.setTags(w.getKeys()); 895 for (Node n: w.getNodes()) { 896 ((HistoryWay)clone).addNode(n.getUniqueId()); 897 } 898 } 899 900 public HistoryOsmPrimitive build(OsmPrimitive primitive) { 901 primitive.visit(this); 902 return clone; 903 } 904 } 589 905 } -
trunk/src/org/openstreetmap/josm/gui/history/HistoryLoadTask.java
r2275 r2448 7 7 import java.io.IOException; 8 8 import java.util.Collection; 9 import java.util.HashMap; 10 import java.util.Map; 9 import java.util.HashSet; 11 10 12 11 import org.openstreetmap.josm.data.osm.OsmPrimitive; 13 12 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 13 import org.openstreetmap.josm.data.osm.PrimitiveId; 14 import org.openstreetmap.josm.data.osm.SimplePrimitiveId; 14 15 import org.openstreetmap.josm.data.osm.history.History; 15 16 import org.openstreetmap.josm.data.osm.history.HistoryDataSet; … … 45 46 private boolean cancelled = false; 46 47 private Exception lastException = null; 47 private Map<Long, OsmPrimitiveType> toLoad;48 private HashSet<PrimitiveId> toLoad; 48 49 private HistoryDataSet loadedData; 49 50 50 51 public HistoryLoadTask() { 51 52 super(tr("Load history"), true); 52 toLoad = new Hash Map<Long, OsmPrimitiveType>();53 toLoad = new HashSet<PrimitiveId>(); 53 54 } 54 55 … … 60 61 * @return this task 61 62 */ 62 public HistoryLoadTask add(long id, OsmPrimitiveType type) {63 public HistoryLoadTask add(long id, OsmPrimitiveType type) throws IllegalArgumentException { 63 64 if (id <= 0) 64 throw new IllegalArgumentException(tr(" ID > 0 expected. Got {0}.", id));65 throw new IllegalArgumentException(tr("Parameter ''{0}'' > 0 expected. Got {1}.", "id", id)); 65 66 if (type == null) 66 67 throw new IllegalArgumentException(tr("Parameter ''{0}'' must not be null.", "type")); 67 if (!toLoad.containsKey(id)) { 68 toLoad.put(id, type); 69 } 68 SimplePrimitiveId pid = new SimplePrimitiveId(id, type); 69 toLoad.add(pid); 70 return this; 71 } 72 73 /** 74 * Adds an object whose history is to be loaded. 75 * 76 * @param pid the primitive id. Must not be null. Id > 0 required. 77 * @return this task 78 */ 79 public HistoryLoadTask add(PrimitiveId pid) throws IllegalArgumentException { 80 if (pid == null) 81 throw new IllegalArgumentException(tr("Parameter ''{0}'' must not be null.", "pid")); 82 if (pid.getUniqueId() <= 0) 83 throw new IllegalArgumentException(tr("id in parameter ''{0}'' > 0 expected, got {1}.", "pid", pid.getUniqueId())); 84 toLoad.add(pid); 70 85 return this; 71 86 } … … 81 96 if (primitive == null) 82 97 throw new IllegalArgumentException(tr("Parameter ''{0}'' must not be null.", "primitive")); 83 if (!toLoad.containsKey(primitive.getId())) { 84 toLoad.put(primitive.getId(), primitive.getType()); 85 } 98 toLoad.add(primitive.getPrimitiveId()); 86 99 return this; 87 100 } … … 97 110 if (history == null) 98 111 throw new IllegalArgumentException(tr("Parameter ''{0}'' must not be null.", "history")); 99 if (!toLoad.containsKey(history.getId())) { 100 toLoad.put(history.getId(), history.getEarliest().getType()); 101 } 112 toLoad.add(history.getPrimitmiveId()); 102 113 return this; 103 114 } … … 116 127 if (primitive.getId() <= 0) 117 128 throw new IllegalArgumentException(tr("Object id > 0 expected. Got {0}", primitive.getId())); 118 119 return add(primitive.getId(), OsmPrimitiveType.from(primitive));129 toLoad.add(primitive.getPrimitiveId()); 130 return this; 120 131 } 121 132 … … 161 172 loadedData = new HistoryDataSet(); 162 173 try { 163 for( Map.Entry<Long, OsmPrimitiveType> entry: toLoad.entrySet()) {174 for(PrimitiveId pid: toLoad) { 164 175 if (cancelled) { 165 176 break; 166 177 } 167 if (entry.getKey() == 0) {168 continue;169 }170 178 String msg = ""; 171 switch( entry.getValue()) {172 173 174 179 switch(pid.getType()) { 180 case NODE: msg = marktr("Loading history for node {0}"); break; 181 case WAY: msg = marktr("Loading history for way {0}"); break; 182 case RELATION: msg = marktr("Loading history for relation {0}"); break; 175 183 } 176 184 progressMonitor.indeterminateSubTask(tr(msg, 177 Long.toString( entry.getKey())));185 Long.toString(pid.getUniqueId()))); 178 186 OsmServerHistoryReader reader = null; 179 187 HistoryDataSet ds = null; 180 188 try { 181 reader = new OsmServerHistoryReader( entry.getValue(), entry.getKey());189 reader = new OsmServerHistoryReader(pid.getType(), pid.getUniqueId()); 182 190 ds = reader.parseHistory(progressMonitor.createSubTaskMonitor(1, false)); 183 191 } catch(OsmTransferException e) { -
trunk/src/org/openstreetmap/josm/gui/history/NodeListViewer.java
r2243 r2448 1 1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.gui.history; 3 4 import static org.openstreetmap.josm.tools.I18n.tr; 3 5 4 6 import java.awt.GridBagConstraints; 5 7 import java.awt.GridBagLayout; 6 8 import java.awt.Insets; 7 9 import java.awt.Point; 10 import java.awt.event.ActionEvent; 11 import java.awt.event.MouseAdapter; 12 import java.awt.event.MouseEvent; 13 14 import javax.swing.AbstractAction; 8 15 import javax.swing.JPanel; 16 import javax.swing.JPopupMenu; 9 17 import javax.swing.JScrollPane; 10 18 import javax.swing.JTable; 11 19 import javax.swing.ListSelectionModel; 20 21 import org.openstreetmap.josm.Main; 22 import org.openstreetmap.josm.actions.AutoScaleAction; 23 import org.openstreetmap.josm.data.osm.OsmPrimitive; 24 import org.openstreetmap.josm.data.osm.PrimitiveId; 25 import org.openstreetmap.josm.data.osm.history.History; 26 import org.openstreetmap.josm.data.osm.history.HistoryDataSet; 27 import org.openstreetmap.josm.gui.history.HistoryBrowserModel.NodeListTableModel; 28 import org.openstreetmap.josm.gui.layer.OsmDataLayer; 29 import org.openstreetmap.josm.tools.ImageProvider; 12 30 13 31 /** … … 28 46 private AdjustmentSynchronizer adjustmentSynchronizer; 29 47 private SelectionSynchronizer selectionSynchronizer; 48 private NodeListPopupMenu popupMenu; 30 49 31 50 protected JScrollPane embeddInScrollPane(JTable table) { … … 45 64 table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 46 65 selectionSynchronizer.participateInSynchronizedSelection(table.getSelectionModel()); 66 table.addMouseListener(new PopupMenuLauncher(table)); 67 table.addMouseListener(new DoubleClickAdapter(table)); 47 68 return table; 48 69 } … … 56 77 table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 57 78 selectionSynchronizer.participateInSynchronizedSelection(table.getSelectionModel()); 79 table.addMouseListener(new PopupMenuLauncher(table)); 80 table.addMouseListener(new DoubleClickAdapter(table)); 58 81 return table; 59 82 } … … 110 133 gc.anchor = GridBagConstraints.NORTHWEST; 111 134 add(embeddInScrollPane(buildCurrentNodeListTable()),gc); 135 136 popupMenu = new NodeListPopupMenu(); 112 137 } 113 138 … … 143 168 } 144 169 } 170 171 172 class NodeListPopupMenu extends JPopupMenu { 173 private ZoomToNodeAction zoomToNodeAction; 174 private ShowHistoryAction showHistoryAction; 175 176 public NodeListPopupMenu() { 177 zoomToNodeAction = new ZoomToNodeAction(); 178 add(zoomToNodeAction); 179 showHistoryAction = new ShowHistoryAction(); 180 add(showHistoryAction); 181 } 182 183 public void prepare(PrimitiveId pid){ 184 zoomToNodeAction.setPrimitiveId(pid); 185 zoomToNodeAction.updateEnabledState(); 186 187 showHistoryAction.setPrimitiveId(pid); 188 showHistoryAction.updateEnabledState(); 189 } 190 } 191 192 class ZoomToNodeAction extends AbstractAction { 193 private PrimitiveId primitiveId; 194 195 public ZoomToNodeAction() { 196 putValue(NAME, tr("Zoom to node")); 197 putValue(SHORT_DESCRIPTION, tr("Zoom to this node in the current data layer")); 198 putValue(SMALL_ICON, ImageProvider.get("dialogs", "zoomin")); 199 } 200 201 public void actionPerformed(ActionEvent e) { 202 if (!isEnabled()) return; 203 OsmPrimitive p = getPrimitiveToZoom(); 204 if (p!= null) { 205 getEditLayer().data.setSelected(p.getPrimitiveId()); 206 new AutoScaleAction("selection").autoScale(); 207 } 208 } 209 210 public void setPrimitiveId(PrimitiveId pid) { 211 this.primitiveId = pid; 212 updateEnabledState(); 213 } 214 215 protected OsmDataLayer getEditLayer() { 216 try { 217 return Main.map.mapView.getEditLayer(); 218 } catch(NullPointerException e) { 219 return null; 220 } 221 } 222 223 protected OsmPrimitive getPrimitiveToZoom() { 224 if (primitiveId == null) return null; 225 OsmPrimitive p = getEditLayer().data.getPrimitiveById(primitiveId); 226 return p; 227 } 228 229 public void updateEnabledState() { 230 if (getEditLayer() == null) { 231 setEnabled(false); 232 return; 233 } 234 setEnabled(getPrimitiveToZoom() != null); 235 } 236 } 237 238 class ShowHistoryAction extends AbstractAction { 239 private PrimitiveId primitiveId; 240 241 public ShowHistoryAction() { 242 putValue(NAME, tr("Show history")); 243 putValue(SHORT_DESCRIPTION, tr("Open a history browser with the history of this node")); 244 putValue(SMALL_ICON, ImageProvider.get("dialogs", "history")); 245 } 246 247 public void actionPerformed(ActionEvent e) { 248 if (!isEnabled()) return; 249 run(); 250 } 251 252 public void setPrimitiveId(PrimitiveId pid) { 253 this.primitiveId = pid; 254 updateEnabledState(); 255 } 256 257 public void run() { 258 if (HistoryDataSet.getInstance().getHistory(primitiveId) == null) { 259 Main.worker.submit(new HistoryLoadTask().add(primitiveId)); 260 } 261 Runnable r = new Runnable() { 262 public void run() { 263 History h = HistoryDataSet.getInstance().getHistory(primitiveId); 264 if (h == null) 265 return; 266 HistoryBrowserDialogManager.getInstance().show(h); 267 } 268 }; 269 Main.worker.submit(r); 270 } 271 272 public void updateEnabledState() { 273 setEnabled(primitiveId != null && primitiveId.getUniqueId() > 0); 274 } 275 } 276 277 class PopupMenuLauncher extends MouseAdapter { 278 private JTable table; 279 280 public PopupMenuLauncher(JTable table) { 281 this.table = table; 282 } 283 284 @Override 285 public void mousePressed(MouseEvent e) { 286 showPopup(e); 287 } 288 289 @Override 290 public void mouseReleased(MouseEvent e) { 291 showPopup(e); 292 } 293 294 private void showPopup(MouseEvent e) { 295 if (!e.isPopupTrigger()) return; 296 Point p = e.getPoint(); 297 int row = table.rowAtPoint(p); 298 NodeListTableModel model = (NodeListTableModel) table.getModel(); 299 PrimitiveId pid = model.getNodeId(row); 300 popupMenu.prepare(pid); 301 popupMenu.show(e.getComponent(), e.getX(), e.getY()); 302 } 303 } 304 305 class DoubleClickAdapter extends MouseAdapter { 306 private JTable table; 307 private ShowHistoryAction showHistoryAction; 308 309 public DoubleClickAdapter(JTable table) { 310 this.table = table; 311 showHistoryAction = new ShowHistoryAction(); 312 } 313 314 protected NodeListTableModel getModel() { 315 return (NodeListTableModel)table.getModel(); 316 } 317 318 @Override 319 public void mouseClicked(MouseEvent e) { 320 if (e.getClickCount() < 2) return; 321 int row = table.rowAtPoint(e.getPoint()); 322 PrimitiveId pid = getModel().getNodeId(row); 323 if (pid == null) 324 return; 325 showHistoryAction.setPrimitiveId(pid); 326 showHistoryAction.run(); 327 } 328 } 145 329 } -
trunk/src/org/openstreetmap/josm/gui/history/TagTableCellRenderer.java
r2017 r2448 6 6 import java.awt.Color; 7 7 import java.awt.Component; 8 import java.awt.Font; 8 9 import java.util.logging.Logger; 9 10 10 11 import javax.swing.JLabel; 11 12 import javax.swing.JTable; 13 import javax.swing.UIManager; 12 14 import javax.swing.table.TableCellRenderer; 13 15 … … 20 22 static private Logger logger = Logger.getLogger(TagTableCellRenderer.class.getName()); 21 23 22 public final static Color BGCOLOR_SELECTED = new Color(143,170,255);23 24 public final static Color BGCOLOR_DIFFERENCE = new Color(255,197,197); 24 25 25 26 public TagTableCellRenderer() { 26 27 setOpaque(true); 27 setForeground(Color.BLACK);28 28 } 29 29 30 30 protected void renderName(String key, HistoryBrowserModel.TagTableModel model, boolean isSelected) { 31 31 String text = key; 32 Color bgColor = Color.WHITE; 32 Color bgColor = UIManager.getColor("Table.background"); 33 Color fgColor = UIManager.getColor("Table.foreground"); 34 Font font = UIManager.getFont("Table.font"); 33 35 if (! model.hasTag(key)) { 34 text = tr(" <undefined>");36 text = tr("not present"); 35 37 bgColor = BGCOLOR_DIFFERENCE; 38 font = font.deriveFont(Font.ITALIC); 36 39 } else if (!model.oppositeHasTag(key)) { 37 40 bgColor = BGCOLOR_DIFFERENCE; 38 41 } 39 42 if (isSelected) { 40 bgColor = BGCOLOR_SELECTED; 43 bgColor = UIManager.getColor("Table.backgroundSelected"); 44 fgColor = UIManager.getColor("Table.foregroundSelected"); 41 45 } 46 42 47 setText(text); 43 48 setToolTipText(text); 44 49 setBackground(bgColor); 50 setForeground(fgColor); 51 setFont(font); 45 52 } 46 53 47 54 protected void renderValue(String key, HistoryBrowserModel.TagTableModel model, boolean isSelected) { 48 55 String text = ""; 49 Color bgColor = Color.WHITE; 56 Color bgColor = UIManager.getColor("Table.background"); 57 Color fgColor = UIManager.getColor("Table.foreground"); 58 Font font = UIManager.getFont("Table.font"); 50 59 if (! model.hasTag(key)) { 51 text = tr(" <undefined>");60 text = tr("not present"); 52 61 bgColor = BGCOLOR_DIFFERENCE; 62 font = font.deriveFont(Font.ITALIC); 53 63 } else { 54 64 text = model.getValue(key); … … 58 68 } 59 69 if (isSelected) { 60 bgColor = BGCOLOR_SELECTED; 70 bgColor = UIManager.getColor("Table.backgroundSelected"); 71 fgColor = UIManager.getColor("Table.foregroundSelected"); 61 72 } 62 73 … … 64 75 setToolTipText(text); 65 76 setBackground(bgColor); 77 setForeground(fgColor); 78 setFont(font); 66 79 } 67 80 -
trunk/src/org/openstreetmap/josm/gui/history/VersionInfoPanel.java
r2318 r2448 4 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 5 6 import java.awt.BorderLayout; 6 7 import java.awt.FlowLayout; 7 8 import java.awt.GridBagConstraints; … … 17 18 import javax.swing.JPanel; 18 19 20 import org.openstreetmap.josm.Main; 19 21 import org.openstreetmap.josm.actions.AbstractInfoAction; 20 22 import org.openstreetmap.josm.data.osm.history.HistoryOsmPrimitive; 23 import org.openstreetmap.josm.gui.JMultilineLabel; 24 import org.openstreetmap.josm.gui.layer.OsmDataLayer; 21 25 import org.openstreetmap.josm.tools.UrlLabel; 22 26 … … 31 35 private PointInTimeType pointInTimeType; 32 36 private HistoryBrowserModel model; 33 private J Label lblInfo;37 private JMultilineLabel lblInfo; 34 38 private UrlLabel lblUser; 35 39 private UrlLabel lblChangeset; 40 private JPanel pnlUserAndChangeset; 36 41 37 42 protected void build() { 38 43 JPanel pnl1 = new JPanel(); 39 pnl1.setLayout(new FlowLayout(FlowLayout.LEFT));40 lblInfo = new J Label();41 lblInfo.setHorizontalAlignment(JLabel.LEFT);42 pnl1.add(lblInfo );44 pnl1.setLayout(new BorderLayout()); 45 lblInfo = new JMultilineLabel(""); 46 //lblInfo.setHorizontalAlignment(JLabel.LEFT); 47 pnl1.add(lblInfo, BorderLayout.CENTER); 43 48 44 JPanel pnl2= new JPanel();45 pnl 2.setLayout(new FlowLayout(FlowLayout.LEFT));49 pnlUserAndChangeset = new JPanel(); 50 pnlUserAndChangeset.setLayout(new FlowLayout(FlowLayout.LEFT)); 46 51 lblUser = new UrlLabel(); 47 pnl 2.add(new JLabel(tr("User")));48 pnl 2.add(lblUser);49 pnl 2.add(new JLabel(tr("Changeset")));52 pnlUserAndChangeset.add(new JLabel(tr("User"))); 53 pnlUserAndChangeset.add(lblUser); 54 pnlUserAndChangeset.add(new JLabel(tr("Changeset"))); 50 55 lblChangeset = new UrlLabel(); 51 pnl 2.add(lblChangeset);56 pnlUserAndChangeset.add(lblChangeset); 52 57 53 58 setLayout(new GridBagLayout()); … … 56 61 gc.fill = GridBagConstraints.HORIZONTAL; 57 62 gc.weightx = 1.0; 58 gc.weighty = 0.0;63 gc.weighty = 1.0; 59 64 add(pnl1, gc); 60 65 gc.gridy = 1; 61 add(pnl2, gc); 66 gc.weighty = 0.0; 67 add(pnlUserAndChangeset, gc); 62 68 } 63 69 … … 68 74 } 69 75 76 protected OsmDataLayer getEditLayer() { 77 try { 78 return Main.map.mapView.getEditLayer(); 79 } catch(NullPointerException e) { 80 return null; 81 } 82 } 83 70 84 protected String getInfoText() { 71 85 HistoryOsmPrimitive primitive = getPrimitive(); 72 86 if (primitive == null) 73 87 return ""; 74 String text = tr( 75 "<html>Version <strong>{0}</strong> created on <strong>{1}</strong></html>", 76 Long.toString(primitive.getVersion()), 77 new SimpleDateFormat().format(primitive.getTimestamp()) 78 ); 88 String text; 89 if (model.isLatest(primitive)) { 90 text = tr("<html>Version <strong>{0}</strong> currently edited in layer ''{1}''</html>", 91 Long.toString(primitive.getVersion()), 92 getEditLayer() == null ? tr("unknown") : getEditLayer().getName() 93 ); 94 } else { 95 text = tr( 96 "<html>Version <strong>{0}</strong> created on <strong>{1}</strong></html>", 97 Long.toString(primitive.getVersion()), 98 new SimpleDateFormat().format(primitive.getTimestamp()) 99 ); 100 } 79 101 return text; 80 102 } … … 110 132 lblInfo.setText(getInfoText()); 111 133 112 String url = AbstractInfoAction.getBaseBrowseUrl() + "/changeset/" + getPrimitive().getChangesetId(); 113 lblChangeset.setUrl(url); 114 lblChangeset.setDescription(Long.toString(getPrimitive().getChangesetId())); 134 if (!model.isLatest(getPrimitive())) { 135 String url = AbstractInfoAction.getBaseBrowseUrl() + "/changeset/" + getPrimitive().getChangesetId(); 136 lblChangeset.setUrl(url); 137 lblChangeset.setDescription(Long.toString(getPrimitive().getChangesetId())); 115 138 116 try { 117 if (getPrimitive().getUid() != -1) { 118 url = AbstractInfoAction.getBaseUserUrl() + "/" + URLEncoder.encode(getPrimitive().getUser(), "UTF-8").replaceAll("\\+", "%20"); 119 lblUser.setUrl(url); 120 } else { 139 try { 140 if (getPrimitive().getUid() != -1) { 141 url = AbstractInfoAction.getBaseUserUrl() + "/" + URLEncoder.encode(getPrimitive().getUser(), "UTF-8").replaceAll("\\+", "%20"); 142 lblUser.setUrl(url); 143 } else { 144 lblUser.setUrl(null); 145 } 146 } catch(UnsupportedEncodingException e) { 147 e.printStackTrace(); 121 148 lblUser.setUrl(null); 122 149 } 123 } catch(UnsupportedEncodingException e) { 124 e.printStackTrace(); 125 lblUser.setUrl(null); 150 String username = getPrimitive().getUser(); 151 lblUser.setDescription(username); 152 } else { 153 String user = Main.pref.get("osm-server.username"); 154 if (user == null) { 155 lblUser.setDescription(tr("anonymous")); 156 } else { 157 try { 158 String url = AbstractInfoAction.getBaseUserUrl() + "/" + URLEncoder.encode(user, "UTF-8").replaceAll("\\+", "%20"); 159 lblUser.setUrl(url); 160 } catch(UnsupportedEncodingException e) { 161 e.printStackTrace(); 162 lblUser.setUrl(null); 163 } 164 lblUser.setDescription(user); 165 } 166 lblChangeset.setDescription(tr("none")); 167 lblChangeset.setUrl(null); 126 168 } 127 String username = getPrimitive().getUser();128 lblUser.setDescription(username);129 169 } 130 170 } -
trunk/src/org/openstreetmap/josm/gui/history/VersionTableCellRenderer.java
r2250 r2448 15 15 import javax.swing.table.TableCellRenderer; 16 16 17 import org.openstreetmap.josm.Main; 18 import org.openstreetmap.josm.data.osm.OsmPrimitive; 17 19 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 18 20 import org.openstreetmap.josm.data.osm.history.HistoryOsmPrimitive; 21 import org.openstreetmap.josm.gui.layer.OsmDataLayer; 19 22 import org.openstreetmap.josm.tools.ImageProvider; 20 23 … … 44 47 } 45 48 46 protected void renderIcon(HistoryOsmPrimitive primitive) { 47 ImageIcon icon = null; 48 if (primitive != null) { 49 icon = icons.get(primitive.getType()); 50 } 49 protected void renderIcon(OsmPrimitiveType type) { 50 ImageIcon icon = type == null? null : icons.get(type); 51 51 setIcon(icon); 52 52 } 53 53 54 54 protected void renderText(HistoryOsmPrimitive primitive) { 55 // render lab letext55 // render label text 56 56 // 57 57 StringBuilder sb = new StringBuilder(); … … 86 86 } 87 87 88 protected OsmDataLayer getEditLayer() { 89 try { 90 return Main.map.mapView.getEditLayer(); 91 } catch(NullPointerException e) { 92 return null; 93 } 94 } 95 96 protected void renderLatestText(OsmPrimitive primitive) { 97 // -- label text 98 StringBuffer sb = new StringBuffer(); 99 if (primitive == null) { 100 setText(""); 101 return; 102 } 103 if (primitive.isModified()) { 104 sb.append("*"); 105 } 106 sb.append(tr("Version {0} in editor", primitive.getVersion())); 107 if (primitive.isDeleted()) { 108 sb.append(tr("[deleted]")); 109 } 110 setText(sb.toString()); 111 112 // -- tooltip text 113 sb = new StringBuffer(); 114 OsmDataLayer l = getEditLayer(); 115 116 sb.append( 117 tr( 118 "Version {0} currently edited in data layer ''{1}''", 119 primitive.getId(), 120 l == null ? tr("unknown") : l.getName() 121 ) 122 ); 123 setToolTipText(sb.toString()); 124 } 125 88 126 protected void renderBackground(JTable table, int row, boolean isSelected) { 89 127 Color bgColor = Color.WHITE; … … 96 134 } 97 135 136 public void renderVersionFromHistory(HistoryOsmPrimitive primitive, JTable table, int row, boolean isSelected) { 137 renderIcon(primitive.getType()); 138 renderText(primitive); 139 renderBackground(table, row, isSelected); 140 } 141 142 public void renderLatest(OsmPrimitive primitive, JTable table, int row, boolean isSelected) { 143 renderIcon(primitive.getType()); 144 renderLatestText(getModel(table).getLatest()); 145 renderBackground(table, row, isSelected); 146 } 147 98 148 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, 99 149 int row, int column) { 100 101 HistoryOsmPrimitive primitive = (HistoryOsmPrimitive)value;102 renderIcon(primitive);103 renderText(primitive);104 renderBackground(table, row, isSelected);150 if (getModel(table).isLatest(row)) { 151 renderLatest(getModel(table).getLatest(),table, row, isSelected); 152 } else { 153 renderVersionFromHistory((HistoryOsmPrimitive)value, table, row, isSelected); 154 } 105 155 return this; 106 156 }
Note:
See TracChangeset
for help on using the changeset viewer.