|
What this is
Other links
The source code/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun * Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.diff.builtin.visualizer; import java.util.*; import java.io.*; import javax.swing.*; import javax.swing.text.*; import java.awt.BorderLayout; import org.openide.util.HelpCtx; import org.openide.windows.*; import org.netbeans.api.diff.Difference; //import org.netbeans.modules.vcscore.util.Debug; //import org.netbeans.modules.vcscore.util.TopComponentCloseListener; /** * This class displays two editor panes with two files and marks the differences * by a different color. * * @author Martin Entlicher */ public class DiffComponent extends org.openide.windows.TopComponent { public static final java.awt.Color COLOR_MISSING = new java.awt.Color(255, 160, 180); public static final java.awt.Color COLOR_ADDED = new java.awt.Color(180, 255, 180); public static final java.awt.Color COLOR_CHANGED = new java.awt.Color(160, 200, 255); //private AbstractDiff diff = null; private Difference[] diffs = null; /** The shift of differences */ private int[][] diffShifts; private DiffPanel diffPanel = null; private java.awt.Color colorMissing = COLOR_MISSING; private java.awt.Color colorAdded = COLOR_ADDED; private java.awt.Color colorChanged = COLOR_CHANGED; //private ArrayList closeListeners = new ArrayList(); private int currentDiffLine = -1; /** * Used for deserialization. */ private boolean diffSetSuccess = true; static final long serialVersionUID =3683458237532937983L; /** * An empty constructor needed by deserialization process. */ public DiffComponent() { putClientProperty("PersistenceType", "Never"); } /** Creates new DiffComponent from list of Difference objects */ public DiffComponent(final Difference[] diffs, final String mainTitle, final String mimeType, final String sourceName1, final String sourceName2, final String title1, final String title2, final Reader r1, final Reader r2) { this(diffs, mainTitle, mimeType, sourceName1, sourceName2, title1, title2, r1, r2, null); } /** Creates new DiffComponent from list of Difference objects */ public DiffComponent(final Difference[] diffs, final String mainTitle, final String mimeType, final String sourceName1, final String sourceName2, final String title1, final String title2, final Reader r1, final Reader r2, java.awt.Color[] colors) { this.diffs = diffs; diffShifts = new int[diffs.length][2]; setLayout(new BorderLayout()); diffPanel = new DiffPanel(); diffPanel.addPrevLineButtonListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { if (diffs.length == 0) return ; currentDiffLine--; if (currentDiffLine < 0) currentDiffLine = diffs.length - 1; showCurrentLine(); } }); diffPanel.addNextLineButtonListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { if (diffs.length == 0) return ; currentDiffLine++; if (currentDiffLine >= diffs.length) currentDiffLine = 0; showCurrentLine(); } }); add(diffPanel, BorderLayout.CENTER); if (colors != null && colors.length >= 3) { colorMissing = colors[0]; colorAdded = colors[1]; colorChanged = colors[2]; } // initComponents (); //setTitle(org.openide.util.NbBundle.getBundle(DiffComponent.class).getString("DiffComponent.title")); if (mainTitle == null) { setName(org.openide.util.NbBundle.getBundle(DiffComponent.class).getString("DiffComponent.title")); } else { setName(mainTitle); } setIcon(org.openide.util.Utilities.loadImage("org/netbeans/modules/diff/diffSettingsIcon.gif")); initContent(mimeType, sourceName1, sourceName2, title1, title2, r1, r2); //HelpCtx.setHelpIDString (getRootPane (), DiffComponent.class.getName ()); putClientProperty("PersistenceType", "Never"); } public HelpCtx getHelpCtx() { return new HelpCtx(DiffComponent.class); } private void showCurrentLine() { Difference diff = diffs[currentDiffLine]; int line = diff.getFirstStart() + diffShifts[currentDiffLine][0]; if (diff.getType() == Difference.ADD) line++; int lf1 = diff.getFirstEnd() - diff.getFirstStart() + 1; int lf2 = diff.getSecondEnd() - diff.getSecondStart() + 1; int length = Math.max(lf1, lf2); diffPanel.setCurrentLine(line, length); } private void initContent(String mimeType, String sourceName1, String sourceName2, String title1, String title2, Reader r1, Reader r2) { setMimeType1(mimeType); setMimeType2(mimeType); try { setSource1(r1); setSource2(r2); } catch (IOException ioex) { org.openide.ErrorManager.getDefault().notify(ioex); } setSource1Title(title1); setSource2Title(title2); insertEmptyLines(true); setDiffHighlight(true); insertEmptyLinesNotReported(); } public void open(Workspace workspace) { super.open(workspace); diffPanel.open(); if (currentDiffLine < 0) { currentDiffLine = 0; showCurrentLine(); } } /** * Transfer the focus to the diff panel. */ public void requestFocus() { super.requestFocus(); diffPanel.requestFocus(); } /** * Transfer the focus to the diff panel. */ public boolean requestFocusInWindow() { super.requestFocusInWindow(); return diffPanel.requestFocusInWindow(); } public void addNotify() { super.addNotify(); if (currentDiffLine < 0) { javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { diffPanel.open(); javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { java.awt.Toolkit.getDefaultToolkit().sync(); javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { if (currentDiffLine < 0) { currentDiffLine = 0; showCurrentLine(); } } }); } }); } }); } } /** * Override for clean up reasons. * Will be moved to the appropriate method when will be made. */ public boolean canClose(Workspace workspace, boolean last) { boolean can = super.canClose(workspace, last); if (last && can) { exitForm(null); } return can; } /* public void removeNotify() { System.out.println("removeNotify() called"); exitForm(null); super.removeNotify(); } */ public void setSource1(Reader r) throws IOException { diffPanel.setSource1(r); } public void setSource2(Reader r) throws IOException { diffPanel.setSource2(r); } public void setSource1Title(String title) { diffPanel.setSource1Title(title); } public void setSource2Title(String title) { diffPanel.setSource2Title(title); } public void setMimeType1(String mime) { diffPanel.setMimeType1(mime); } public void setMimeType2(String mime) { diffPanel.setMimeType2(mime); } public void setDocument1(Document doc) { diffPanel.setDocument1(doc); } public void setDocument2(Document doc) { diffPanel.setDocument2(doc); } private void setHighlight(StyledDocument doc, int line1, int line2, java.awt.Color color) { } private void unhighlight(StyledDocument doc) { } public void unhighlightAll() { diffPanel.unhighlightAll(); } public void highlightRegion1(int line1, int line2, java.awt.Color color) { //D.deb("Highlight region 1"); // NOI18N diffPanel.highlightRegion1(line1, line2, color); } public void highlightRegion2(int line1, int line2, java.awt.Color color) { //D.deb("Highlight region 2"); // NOI18N diffPanel.highlightRegion2(line1, line2, color); } public void addEmptyLines1(int line, int numLines) { diffPanel.addEmptyLines1(line, numLines); } public void addEmptyLines2(int line, int numLines) { diffPanel.addEmptyLines2(line, numLines); } public void writeExternal(ObjectOutput out) throws IOException { super.writeExternal(out); //try { out.writeObject(diffs); /* } catch (IOException exc) { System.out.println("exc = "+exc); exc.printStackTrace(); throw exc; } */ } private void insertEmptyLines(boolean updateActionLines) { int n = diffs.length; //int ins1 = 0; //int ins2 = 0; //D.deb("insertEmptyLines():"); // NOI18N for(int i = 0; i < n; i++) { Difference action = diffs[i]; int n1 = action.getFirstStart() + diffShifts[i][0]; int n2 = action.getFirstEnd() + diffShifts[i][0]; int n3 = action.getSecondStart() + diffShifts[i][1]; int n4 = action.getSecondEnd() + diffShifts[i][1]; //System.out.println("Action = "+action); //System.out.println("ins1 = "+diffShifts[i][0]+", ins2 = "+diffShifts[i][1]); if (updateActionLines && i < n - 1) { diffShifts[i + 1][0] = diffShifts[i][0]; diffShifts[i + 1][1] = diffShifts[i][1]; } switch (action.getType()) { case Difference.DELETE: addEmptyLines2(n3, n2 - n1 + 1); if (updateActionLines && i < n - 1) { diffShifts[i+1][1] += n2 - n1 + 1; } //ins2 += n2 - n1 + 1; break; case Difference.ADD: addEmptyLines1(n1, n4 - n3 + 1); if (updateActionLines && i < n - 1) { diffShifts[i+1][0] += n4 - n3 + 1; } //ins1 += n4 - n3 + 1; break; case Difference.CHANGE: int r1 = n2 - n1; int r2 = n4 - n3; if (r1 < r2) { addEmptyLines1(n2, r2 - r1); if (updateActionLines && i < n - 1) { diffShifts[i+1][0] += r2 - r1; } //ins1 += r2 - r1; } else if (r1 > r2) { addEmptyLines2(n4, r1 - r2); if (updateActionLines && i < n - 1) { diffShifts[i+1][1] += r1 - r2; } //ins2 += r1 - r2; } break; } } } private void setDiffHighlight(boolean set) { int n = diffs.length; //D.deb("Num Actions = "+n); // NOI18N for(int i = 0; i < n; i++) { Difference action = diffs[i]; int n1 = action.getFirstStart() + diffShifts[i][0]; int n2 = action.getFirstEnd() + diffShifts[i][0]; int n3 = action.getSecondStart() + diffShifts[i][1]; int n4 = action.getSecondEnd() + diffShifts[i][1]; //D.deb("Action: "+action.getAction()+": ("+n1+","+n2+","+n3+","+n4+")"); // NOI18N switch (action.getType()) { case Difference.DELETE: if (set) highlightRegion1(n1, n2, colorMissing); else highlightRegion1(n1, n2, java.awt.Color.white); break; case Difference.ADD: if (set) highlightRegion2(n3, n4, colorAdded); else highlightRegion2(n3, n4, java.awt.Color.white); break; case Difference.CHANGE: if (set) { highlightRegion1(n1, n2, colorChanged); highlightRegion2(n3, n4, colorChanged); } else { highlightRegion1(n1, n2, java.awt.Color.white); highlightRegion2(n3, n4, java.awt.Color.white); } break; } } } /** * Read one line from the given text, from the given position. It returns * the end position of this line and the beginning of the next one. * @param begin Contains just one value - IN: the beginning of the line to read. * OUT: the start of the next line. * @param end Contains just one value - OUT: the end of the line. * @param text The text to read. * @return The line. */ private static String readLine(int[] begin, int[] end, String text) { int n = text.length(); for (int i = begin[0]; i < n; i++) { char c = text.charAt(i); if (c == '\n' || c == '\r') { end[0] = i; break; } } if (end[0] < begin[0]) end[0] = n; String line = text.substring(begin[0], end[0]); begin[0] = end[0] + 1; if (begin[0] < n && text.charAt(end[0]) == '\r' && text.charAt(begin[0]) == '\n') begin[0]++; return line; } /** * Find the first diff, that is on or below the given line number. * @return The index of the desired difference in the supplied array or * a value, that is bigger then the array size if such a diff does * not exist. */ private static int findDiffForLine(int lineNumber, int diffIndex, Difference[] diffs, int[][] diffShifts) { while (diffIndex < diffs.length) { if ((diffs[diffIndex].getFirstEnd() + diffShifts[diffIndex][0]) >= lineNumber || (diffs[diffIndex].getSecondEnd() + diffShifts[diffIndex][1]) >= lineNumber) break; diffIndex++; } return diffIndex; } /** * Find out whether the line lies in the difference. * @param lineNumber The number of the line. * @param diff The difference * @param diffShifts The shifts of the difference in the current document * @return true if the line lies in the difference, false if does not. */ private static boolean isLineInDiff(int lineNumber, Difference diff, int[] diffShifts) { int l1 = diff.getFirstStart() + diffShifts[0]; int l2 = diff.getFirstEnd() + diffShifts[0]; int l3 = diff.getSecondStart() + diffShifts[1]; int l4 = diff.getSecondEnd() + diffShifts[1]; return (l1 <= lineNumber && ((l2 >= l1) ? (l2 >= lineNumber) : false)) || (l3 <= lineNumber && ((l4 >= l3) ? (l4 >= lineNumber) : false)); } private static int numEmptyLines(int beginLine, String text, int endLine) { if (endLine >= 0 && endLine <= beginLine) return 0; int numLines = 0; int[] begin = { beginLine }; int[] end = { 0 }; do { String line = readLine(begin, end, text); if (line.trim().length() > 0) break; numLines++; } while ((endLine < 0 || beginLine + numLines < endLine) && begin[0] < text.length()); return numLines; } /** * We have to keep the balance of lines from the first and the second document, * so that corresponding lines will have the same line number in the document. * Because some diff providers can be set not to report changes in empty lines, * we have to use heuristics to balance the corresponding lines manually * if they do not match. * |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.