Changeset 4498 in josm
- Timestamp:
- 2011-10-07T21:55:13+02:00 (13 years ago)
- Location:
- trunk/src/org/openstreetmap/josm/gui/history
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java
r4406 r4498 7 7 import java.util.Collections; 8 8 import java.util.HashSet; 9 import java.util.List; 9 10 import java.util.Observable; 10 11 11 import javax.swing.table. DefaultTableModel;12 import javax.swing.table.AbstractTableModel; 12 13 13 14 import org.openstreetmap.josm.Main; … … 15 16 import org.openstreetmap.josm.data.osm.OsmPrimitive; 16 17 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 17 import org.openstreetmap.josm.data.osm.PrimitiveId;18 18 import org.openstreetmap.josm.data.osm.Relation; 19 19 import org.openstreetmap.josm.data.osm.RelationMember; 20 import org.openstreetmap.josm.data.osm.SimplePrimitiveId;21 20 import org.openstreetmap.josm.data.osm.Way; 22 21 import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent; … … 40 39 import org.openstreetmap.josm.gui.layer.OsmDataLayer; 41 40 import org.openstreetmap.josm.tools.CheckParameterUtil; 41 import org.openstreetmap.josm.tools.Diff; 42 42 43 43 /** … … 80 80 private TagTableModel currentTagTableModel; 81 81 private TagTableModel referenceTagTableModel; 82 private NodeListTableModel currentNodeListTableModel;83 private NodeListTableModel referenceNodeListTableModel;84 82 private RelationMemberTableModel currentRelationMemberTableModel; 85 83 private RelationMemberTableModel referenceRelationMemberTableModel; 84 private DiffTableModel referenceNodeListTableModel; 85 private DiffTableModel currentNodeListTableModel; 86 86 87 87 /** … … 92 92 currentTagTableModel = new TagTableModel(PointInTimeType.CURRENT_POINT_IN_TIME); 93 93 referenceTagTableModel = new TagTableModel(PointInTimeType.REFERENCE_POINT_IN_TIME); 94 currentNodeListTableModel = new NodeListTableModel(PointInTimeType.CURRENT_POINT_IN_TIME);95 referenceNodeListTableModel = new NodeListTableModel(PointInTimeType.REFERENCE_POINT_IN_TIME);94 referenceNodeListTableModel = new DiffTableModel(); 95 currentNodeListTableModel = new DiffTableModel(); 96 96 currentRelationMemberTableModel = new RelationMemberTableModel(PointInTimeType.CURRENT_POINT_IN_TIME); 97 97 referenceRelationMemberTableModel = new RelationMemberTableModel(PointInTimeType.REFERENCE_POINT_IN_TIME); … … 146 146 if (primitive == null) return false; 147 147 if (primitive.isNew() || !primitive.isUsable()) return false; 148 148 149 149 //try creating a history primitive. if that fails, the primitive cannot be used. 150 150 try { … … 196 196 197 197 protected void fireModelChange() { 198 initNodeListTableModels(); 198 199 setChanged(); 199 200 notifyObservers(); … … 216 217 } 217 218 218 protected void initNodeListTabeModels() { 219 /** 220 * Should be called everytime either reference of current changes to update the diff. 221 * TODO: Maybe rename to reflect this? eg. updateNodeListTableModels 222 */ 223 protected void initNodeListTableModels() { 224 225 if(current.getType() != OsmPrimitiveType.WAY || reference.getType() != OsmPrimitiveType.WAY) 226 return; 227 TwoColumnDiff diff = new TwoColumnDiff( 228 ((HistoryWay)reference).getNodes().toArray(), 229 ((HistoryWay)current).getNodes().toArray()); 230 referenceNodeListTableModel.setRows(diff.referenceDiff); 231 currentNodeListTableModel.setRows(diff.currentDiff); 232 233 referenceNodeListTableModel.fireTableDataChanged(); 219 234 currentNodeListTableModel.fireTableDataChanged(); 220 referenceNodeListTableModel.fireTableDataChanged();221 235 } 222 236 … … 244 258 } 245 259 246 public NodeListTableModel getNodeListTableModel(PointInTimeType pointInTimeType) throws IllegalArgumentException {260 public DiffTableModel getNodeListTableModel(PointInTimeType pointInTimeType) throws IllegalArgumentException { 247 261 CheckParameterUtil.ensureParameterNotNull(pointInTimeType, "pointInTimeType"); 248 262 if (pointInTimeType.equals(PointInTimeType.CURRENT_POINT_IN_TIME)) … … 290 304 this.reference = reference; 291 305 initTagTableModels(); 292 initNodeListTab eModels();306 initNodeListTableModels(); 293 307 initMemberListTableModels(); 294 308 setChanged(); … … 319 333 this.current = current; 320 334 initTagTableModels(); 321 initNodeListTab eModels();335 initNodeListTableModels(); 322 336 initMemberListTableModels(); 323 337 setChanged(); … … 378 392 * 379 393 */ 380 public class VersionTableModel extends DefaultTableModel{394 public class VersionTableModel extends AbstractTableModel { 381 395 382 396 private VersionTableModel() { … … 459 473 return p; 460 474 } 475 476 @Override 477 public int getColumnCount() { 478 return 1; 479 } 461 480 } 462 481 … … 466 485 * 467 486 */ 468 public class TagTableModel extends DefaultTableModel {487 public class TagTableModel extends AbstractTableModel { 469 488 470 489 private ArrayList<String> keys; … … 554 573 return pointInTimeType.equals(PointInTimeType.REFERENCE_POINT_IN_TIME); 555 574 } 556 } 557 558 /** 559 * The table model for the nodes of the version at {@see PointInTimeType#REFERENCE_POINT_IN_TIME} 560 * or {@see PointInTimeType#CURRENT_POINT_IN_TIME} 561 * 562 */ 563 public class NodeListTableModel extends DefaultTableModel { 564 565 private PointInTimeType pointInTimeType; 566 567 private NodeListTableModel(PointInTimeType pointInTimeType) { 568 this.pointInTimeType = pointInTimeType; 569 } 570 571 @Override 572 public int getRowCount() { 573 int n = 0; 574 if (current != null && current.getType().equals(OsmPrimitiveType.WAY)) { 575 n = ((HistoryWay)current).getNumNodes(); 576 } 577 if (reference != null && reference.getType().equals(OsmPrimitiveType.WAY)) { 578 n = Math.max(n,((HistoryWay)reference).getNumNodes()); 579 } 580 return n; 581 } 582 583 protected HistoryWay getWay() { 584 if (pointInTimeType.equals(PointInTimeType.CURRENT_POINT_IN_TIME)) { 585 if (! current.getType().equals(OsmPrimitiveType.WAY)) 586 return null; 587 return (HistoryWay)current; 588 } 589 if (pointInTimeType.equals(PointInTimeType.REFERENCE_POINT_IN_TIME)) { 590 if (! reference.getType().equals(OsmPrimitiveType.WAY)) 591 return null; 592 return (HistoryWay)reference; 593 } 594 595 // should not happen 596 return null; 597 } 598 599 protected HistoryWay getOppositeWay() { 600 PointInTimeType opposite = pointInTimeType.opposite(); 601 if (opposite.equals(PointInTimeType.CURRENT_POINT_IN_TIME)) { 602 if (! current.getType().equals(OsmPrimitiveType.WAY)) 603 return null; 604 return (HistoryWay)current; 605 } 606 if (opposite.equals(PointInTimeType.REFERENCE_POINT_IN_TIME)) { 607 if (! reference.getType().equals(OsmPrimitiveType.WAY)) 608 return null; 609 return (HistoryWay)reference; 610 } 611 612 // should not happen 613 return null; 614 } 615 616 @Override 617 public Object getValueAt(int row, int column) { 618 HistoryWay way = getWay(); 619 if (way == null) 620 return null; 621 if (row >= way.getNumNodes()) 622 return null; 623 return way.getNodes().get(row); 624 } 625 626 public PrimitiveId getNodeId(int row) { 627 HistoryWay way = getWay(); 628 if (way == null) return null; 629 if (row > way.getNumNodes()) return null; 630 return new SimplePrimitiveId(way.getNodeId(row), OsmPrimitiveType.NODE); 631 } 632 633 @Override 634 public boolean isCellEditable(int row, int column) { 635 return false; 636 } 637 638 public boolean isSameInOppositeWay(int row) { 639 HistoryWay thisWay = getWay(); 640 HistoryWay oppositeWay = getOppositeWay(); 641 if (thisWay == null || oppositeWay == null) 642 return false; 643 if (row >= oppositeWay.getNumNodes()) 644 return false; 645 return thisWay.getNodeId(row) == oppositeWay.getNodeId(row); 646 } 647 648 public boolean isInOppositeWay(int row) { 649 HistoryWay thisWay = getWay(); 650 HistoryWay oppositeWay = getOppositeWay(); 651 if (thisWay == null || oppositeWay == null) 652 return false; 653 return oppositeWay.getNodes().contains(thisWay.getNodeId(row)); 575 576 @Override 577 public int getColumnCount() { 578 return 1; 654 579 } 655 580 } … … 661 586 */ 662 587 663 public class RelationMemberTableModel extends DefaultTableModel {588 public class RelationMemberTableModel extends AbstractTableModel { 664 589 665 590 private PointInTimeType pointInTimeType; … … 748 673 return oppositeRelation.getMembers().contains(thisRelation.getMembers().get(row)); 749 674 } 675 676 @Override 677 public int getColumnCount() { 678 return 1; 679 } 750 680 } 751 681 … … 918 848 } 919 849 } 850 851 /** 852 * Simple model storing "diff cells" in a list. Could probably have used a DefaultTableModel instead.. 853 * 854 * {@see NodeListDiffTableCellRenderer} 855 */ 856 class DiffTableModel extends AbstractTableModel { 857 private List<TwoColumnDiff.Item> rows; 858 859 public void setRows(List<TwoColumnDiff.Item> rows) { 860 this.rows = rows; 861 } 862 863 public DiffTableModel(List<TwoColumnDiff.Item> rows) { 864 this.rows = rows; 865 } 866 public DiffTableModel() { 867 this.rows = new ArrayList<TwoColumnDiff.Item>(); 868 } 869 @Override 870 public int getRowCount() { 871 return rows.size(); 872 } 873 874 @Override 875 public int getColumnCount() { 876 return 1; 877 } 878 879 @Override 880 public TwoColumnDiff.Item getValueAt(int rowIndex, int columnIndex) { 881 return rows.get(rowIndex); 882 } 883 } 884 885 886 /// Feel free to move me somewhere else. Maybe a bit specific for josm.tools? 887 /** 888 * Produces a "two column diff" of two lists. (same as diff -y) 889 * 890 * Each list is annotated with the changes relative to the other, and "empty" cells are inserted so the lists are comparable item by item. 891 * 892 * diff on [1 2 3 4] [1 a 4 5] yields: 893 * 894 * item(SAME, 1) item(SAME, 1) 895 * item(CHANGED, 2) item(CHANGED, 2) 896 * item(DELETED, 3) item(EMPTY) 897 * item(SAME, 4) item(SAME, 4) 898 * item(EMPTY) item(INSERTED, 5) 899 * 900 * @author olejorgenb 901 */ 902 class TwoColumnDiff { 903 public static class Item { 904 public static final int INSERTED = 1; 905 public static final int DELETED = 2; 906 public static final int CHANGED = 3; 907 public static final int SAME = 4; 908 public static final int EMPTY = 5; // value should be null 909 public Item(int state, Object value) { 910 this.state = state; 911 this.value = state == EMPTY ? null : value; 912 } 913 914 public final Object value; 915 public final int state; 916 } 917 918 public ArrayList<Item> referenceDiff; 919 public ArrayList<Item> currentDiff; 920 Object[] reference; 921 Object[] current; 922 923 /** 924 * The arguments will _not_ be modified 925 */ 926 public TwoColumnDiff(Object[] reference, Object[] current) { 927 this.reference = reference; 928 this.current = current; 929 referenceDiff = new ArrayList<Item>(); 930 currentDiff = new ArrayList<Item>(); 931 diff(); 932 } 933 private void diff() { 934 Diff diff = new Diff(reference, current); 935 Diff.change script = diff.diff_2(false); 936 twoColumnDiffFromScript(script, reference, current); 937 } 938 939 /** 940 * The result from the diff algorithm is a "script" (a compressed description of the changes) 941 * This method expands this script into a full two column description. 942 */ 943 private void twoColumnDiffFromScript(Diff.change script, Object[] a, Object[] b) { 944 int ia = 0; 945 int ib = 0; 946 947 while(script != null) { 948 int deleted = script.deleted; 949 int inserted = script.inserted; 950 while(ia < script.line0 && ib < script.line1){ 951 // System.out.println(" "+a[ia] + "\t "+b[ib]); 952 Item cell = new Item(Item.SAME, a[ia]); 953 referenceDiff.add(cell); 954 currentDiff.add(cell); 955 ia++; 956 ib++; 957 } 958 959 while(inserted > 0 || deleted > 0) { 960 if(inserted > 0 && deleted > 0) { 961 // System.out.println("="+a[ia] + "\t="+b[ib]); 962 referenceDiff.add(new Item(Item.CHANGED, a[ia++])); 963 currentDiff.add(new Item(Item.CHANGED, b[ib++])); 964 } else if(inserted > 0) { 965 // System.out.println("\t+" + b[ib]); 966 referenceDiff.add(new Item(Item.EMPTY, null)); 967 currentDiff.add(new Item(Item.INSERTED, b[ib++])); 968 } else if(deleted > 0) { 969 // System.out.println("-"+a[ia]); 970 referenceDiff.add(new Item(Item.DELETED, a[ia++])); 971 currentDiff.add(new Item(Item.EMPTY, null)); 972 } 973 inserted--; 974 deleted--; 975 } 976 script = script.link; 977 } 978 while(ia < a.length && ib < b.length) { 979 // System.out.println((ia < a.length ? " "+a[ia]+"\t" : "\t") + (ib < b.length ? " "+b[ib] : "")); 980 referenceDiff.add(new Item(Item.SAME, a[ia++])); 981 currentDiff.add(new Item(Item.SAME, b[ib++])); 982 } 983 } 984 } -
trunk/src/org/openstreetmap/josm/gui/history/NodeListTableCellRenderer.java
r4072 r4498 14 14 import org.openstreetmap.josm.tools.ImageProvider; 15 15 16 /**17 * The {@see TableCellRenderer} for a list of nodes in [@see HistoryBrower}18 *19 *20 */21 16 public class NodeListTableCellRenderer extends JLabel implements TableCellRenderer { 22 17 23 18 public final static Color BGCOLOR_EMPTY_ROW = new Color(234,234,234); 24 public final static Color BGCOLOR_NOT_IN_OPPOSITE = new Color(255,197,197); 25 public final static Color BGCOLOR_IN_OPPOSITE = new Color(255,234,213); 19 public final static Color BGCOLOR_DELETED = new Color(255,197,197); 20 public final static Color BGCOLOR_INSERTED = new Color(0xDD, 0xFF, 0xDD); 21 public final static Color BGCOLOR_CHANGED = new Color(255,234,213); 26 22 public final static Color BGCOLOR_SELECTED = new Color(143,170,255); 27 23 … … 34 30 } 35 31 36 protected void renderNode( HistoryBrowserModel.NodeListTableModel model, Long nodeId, int row, boolean isSelected) {32 protected void renderNode(TwoColumnDiff.Item item, boolean isSelected) { 37 33 String text = ""; 38 34 Color bgColor = Color.WHITE; 39 if (nodeId == null) { 35 setIcon(nodeIcon); 36 if (item.value != null) { 37 text = tr("Node {0}", item.value.toString()); 38 } 39 switch(item.state) { 40 case TwoColumnDiff.Item.EMPTY: 40 41 text = ""; 41 42 bgColor = BGCOLOR_EMPTY_ROW; 42 43 setIcon(null); 43 } else { 44 text = tr("Node {0}", nodeId.toString()); 45 setIcon(nodeIcon); 46 if (model.isSameInOppositeWay(row)) { 47 bgColor = Color.WHITE; 48 } else if (model.isInOppositeWay(row)) { 49 bgColor = BGCOLOR_IN_OPPOSITE; 50 } else { 51 bgColor = BGCOLOR_NOT_IN_OPPOSITE; 52 } 44 break; 45 case TwoColumnDiff.Item.CHANGED: 46 bgColor = BGCOLOR_CHANGED; 47 break; 48 case TwoColumnDiff.Item.INSERTED: 49 bgColor = BGCOLOR_INSERTED; 50 break; 51 case TwoColumnDiff.Item.DELETED: 52 bgColor = BGCOLOR_DELETED; 53 break; 54 default: 55 bgColor = BGCOLOR_EMPTY_ROW; 53 56 } 54 57 if (isSelected) { … … 64 67 return this; 65 68 66 HistoryBrowserModel.NodeListTableModel model = getNodeListTableModel(table); 67 Long nodeId = (Long)value; 68 renderNode(model, nodeId, row, isSelected); 69 renderNode((TwoColumnDiff.Item)value, isSelected); 69 70 return this; 70 71 } 71 72 protected HistoryBrowserModel.NodeListTableModel getNodeListTableModel(JTable table) {73 return (HistoryBrowserModel.NodeListTableModel) table.getModel();74 }75 72 } -
trunk/src/org/openstreetmap/josm/gui/history/NodeListTableColumnModel.java
r3083 r4498 6 6 import javax.swing.table.DefaultTableColumnModel; 7 7 import javax.swing.table.TableColumn; 8 8 9 9 10 /** -
trunk/src/org/openstreetmap/josm/gui/history/NodeListViewer.java
r3327 r4498 18 18 import javax.swing.JTable; 19 19 import javax.swing.ListSelectionModel; 20 import javax.swing.table.TableModel; 20 21 21 22 import org.openstreetmap.josm.Main; 22 23 import org.openstreetmap.josm.actions.AutoScaleAction; 23 24 import org.openstreetmap.josm.data.osm.OsmPrimitive; 25 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 24 26 import org.openstreetmap.josm.data.osm.PrimitiveId; 27 import org.openstreetmap.josm.data.osm.SimplePrimitiveId; 25 28 import org.openstreetmap.josm.data.osm.history.History; 26 29 import org.openstreetmap.josm.data.osm.history.HistoryDataSet; 27 import org.openstreetmap.josm.gui.history.HistoryBrowserModel.NodeListTableModel;28 30 import org.openstreetmap.josm.gui.layer.OsmDataLayer; 29 31 import org.openstreetmap.josm.tools.ImageProvider; … … 274 276 } 275 277 278 static private PrimitiveId primitiveIdAtRow(TableModel model, int row) { 279 DiffTableModel castedModel = (DiffTableModel) model; 280 Long id = (Long)castedModel.getValueAt(row, 0).value; 281 if(id == null) return null; 282 return new SimplePrimitiveId(id, OsmPrimitiveType.NODE); 283 } 284 276 285 class PopupMenuLauncher extends MouseAdapter { 277 286 private JTable table; … … 295 304 Point p = e.getPoint(); 296 305 int row = table.rowAtPoint(p); 297 NodeListTableModel model = (NodeListTableModel) table.getModel(); 298 PrimitiveId pid = model.getNodeId(row); 306 307 PrimitiveId pid = primitiveIdAtRow(table.getModel(), row); 308 if (pid == null) 309 return; 299 310 popupMenu.prepare(pid); 300 311 popupMenu.show(e.getComponent(), e.getX(), e.getY()); … … 309 320 this.table = table; 310 321 showHistoryAction = new ShowHistoryAction(); 311 }312 313 protected NodeListTableModel getModel() {314 return (NodeListTableModel)table.getModel();315 322 } 316 323 … … 319 326 if (e.getClickCount() < 2) return; 320 327 int row = table.rowAtPoint(e.getPoint()); 321 PrimitiveId pid = getModel().getNodeId(row); 328 if(row <= 0) return; 329 PrimitiveId pid = primitiveIdAtRow(table.getModel(), row); 322 330 if (pid == null) 323 331 return; -
trunk/src/org/openstreetmap/josm/gui/history/VersionTable.java
r4406 r4498 72 72 public void valueChanged(ListSelectionEvent e) { 73 73 DefaultListSelectionModel model = (DefaultListSelectionModel)e.getSource(); 74 if (model.getMinSelectionIndex() >= 0) { 74 // For some reason we receive multiple "adjusting" events here even when the source is a simple "set selection" action 75 // The last and proper event will have getValueIsAdjusting() == false 76 if (model.getMinSelectionIndex() >= 0 && e.getValueIsAdjusting() == false) { 75 77 handleSelectCurrentPointInTime(model.getMinSelectionIndex()); 76 78 }
Note:
See TracChangeset
for help on using the changeset viewer.