Changeset 2448 in josm for trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java
- Timestamp:
- 2009-11-14T17:59:10+01:00 (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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 }
Note:
See TracChangeset
for help on using the changeset viewer.