source: josm/trunk/src/org/openstreetmap/josm/gui/history/TwoColumnDiff.java@ 5627

Last change on this file since 5627 was 5627, checked in by jttt, 11 years ago

use diff to show relation members in history dialog, jump to first change when different version is selected

File size: 4.1 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.history;
3/// Feel free to move me somewhere else. Maybe a bit specific for josm.tools?
4
5import java.awt.Color;
6import java.util.ArrayList;
7
8import org.openstreetmap.josm.gui.history.TwoColumnDiff.Item.DiffItemType;
9import org.openstreetmap.josm.tools.Diff;
10
11/**
12 * Produces a "two column diff" of two lists. (same as diff -y)
13 *
14 * Each list is annotated with the changes relative to the other, and "empty" cells are inserted so the lists are comparable item by item.
15 *
16 * diff on [1 2 3 4] [1 a 4 5] yields:
17 *
18 * item(SAME, 1) item(SAME, 1)
19 * item(CHANGED, 2) item(CHANGED, 2)
20 * item(DELETED, 3) item(EMPTY)
21 * item(SAME, 4) item(SAME, 4)
22 * item(EMPTY) item(INSERTED, 5)
23 *
24 * @author olejorgenb
25 */
26class TwoColumnDiff {
27 public static class Item {
28
29 public enum DiffItemType {
30 INSERTED(new Color(0xDD, 0xFF, 0xDD)), DELETED(new Color(255,197,197)), CHANGED(new Color(255,234,213)),
31 SAME(new Color(234,234,234)), EMPTY(new Color(234,234,234));
32
33 private final Color color;
34 private DiffItemType(Color color) {
35 this.color = color;
36 }
37 public Color getColor() {
38 return color;
39 }
40 }
41
42 public Item(DiffItemType state, Object value) {
43 this.state = state;
44 this.value = state == DiffItemType.EMPTY ? null : value;
45 }
46
47 public final Object value;
48 public final DiffItemType state;
49 }
50
51 public ArrayList<Item> referenceDiff;
52 public ArrayList<Item> currentDiff;
53 Object[] reference;
54 Object[] current;
55
56 /**
57 * The arguments will _not_ be modified
58 */
59 public TwoColumnDiff(Object[] reference, Object[] current) {
60 this.reference = reference;
61 this.current = current;
62 referenceDiff = new ArrayList<Item>();
63 currentDiff = new ArrayList<Item>();
64 diff();
65 }
66 private void diff() {
67 Diff diff = new Diff(reference, current);
68 Diff.change script = diff.diff_2(false);
69 twoColumnDiffFromScript(script, reference, current);
70 }
71
72 /**
73 * The result from the diff algorithm is a "script" (a compressed description of the changes)
74 * This method expands this script into a full two column description.
75 */
76 private void twoColumnDiffFromScript(Diff.change script, Object[] a, Object[] b) {
77 int ia = 0;
78 int ib = 0;
79
80 while(script != null) {
81 int deleted = script.deleted;
82 int inserted = script.inserted;
83 while(ia < script.line0 && ib < script.line1){
84 // System.out.println(" "+a[ia] + "\t "+b[ib]);
85 Item cell = new Item(DiffItemType.SAME, a[ia]);
86 referenceDiff.add(cell);
87 currentDiff.add(cell);
88 ia++;
89 ib++;
90 }
91
92 while(inserted > 0 || deleted > 0) {
93 if(inserted > 0 && deleted > 0) {
94 // System.out.println("="+a[ia] + "\t="+b[ib]);
95 referenceDiff.add(new Item(DiffItemType.CHANGED, a[ia++]));
96 currentDiff.add(new Item(DiffItemType.CHANGED, b[ib++]));
97 } else if(inserted > 0) {
98 // System.out.println("\t+" + b[ib]);
99 referenceDiff.add(new Item(DiffItemType.EMPTY, null));
100 currentDiff.add(new Item(DiffItemType.INSERTED, b[ib++]));
101 } else if(deleted > 0) {
102 // System.out.println("-"+a[ia]);
103 referenceDiff.add(new Item(DiffItemType.DELETED, a[ia++]));
104 currentDiff.add(new Item(DiffItemType.EMPTY, null));
105 }
106 inserted--;
107 deleted--;
108 }
109 script = script.link;
110 }
111 while(ia < a.length && ib < b.length) {
112 // System.out.println((ia < a.length ? " "+a[ia]+"\t" : "\t") + (ib < b.length ? " "+b[ib] : ""));
113 referenceDiff.add(new Item(DiffItemType.SAME, a[ia++]));
114 currentDiff.add(new Item(DiffItemType.SAME, b[ib++]));
115 }
116 }
117}
Note: See TracBrowser for help on using the repository browser.