VCS: full, short diff: for addition/deletion, show only one diff panel

This commit is contained in:
irengrig
2012-02-12 20:00:40 +04:00
parent d513dfbdc6
commit b810a0c8be
11 changed files with 113 additions and 9 deletions
@@ -32,6 +32,7 @@ import java.util.List;
*/
public abstract class DiffContent {
private final List<Listener> myListeners = ContainerUtil.createEmptyCOWList();
private boolean myIsEmpty;
public void addListener(Listener listener) { myListeners.add(listener); }
public void removeListener(Listener listener) { myListeners.remove(listener); }
@@ -52,6 +53,14 @@ public abstract class DiffContent {
*/
public boolean isBinary() { return false; }
public void setIsEmpty(boolean isEmpty) {
myIsEmpty = isEmpty;
}
public boolean isEmpty() {
return myIsEmpty;
}
/**
* Called by {@link com.intellij.openapi.diff.DiffTool}
* when document returned by {@link #getDocument()} is opened in editor. Implementors may use this notification to
@@ -67,6 +67,12 @@ public class SimpleContent extends DiffContent {
myType = type;
}
public static SimpleContent createEmpty() {
final SimpleContent content = new SimpleContent("");
content.setIsEmpty(true);
return content;
}
/**
* Make this content editable or not. By default SimpleContent isn't editable.
*/
@@ -34,7 +34,7 @@ import com.intellij.openapi.diff.impl.fragments.Fragment;
import com.intellij.openapi.diff.impl.fragments.FragmentList;
import com.intellij.openapi.diff.impl.highlighting.DiffPanelState;
import com.intellij.openapi.diff.impl.highlighting.FragmentSide;
import com.intellij.openapi.diff.impl.processing.HorisontalDiffSplitter;
import com.intellij.openapi.diff.impl.processing.HorizontalDiffSplitter;
import com.intellij.openapi.diff.impl.splitter.DiffDividerPaint;
import com.intellij.openapi.diff.impl.splitter.LineBlocks;
import com.intellij.openapi.diff.impl.util.*;
@@ -131,7 +131,7 @@ public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSid
new DiffDividerPaint(this, FragmentSide.SIDE1), myData);
}
else {
mySplitter = new HorisontalDiffSplitter(myLeftSide.getComponent(), myRightSide.getComponent());
mySplitter = new HorizontalDiffSplitter(myLeftSide.getComponent(), myRightSide.getComponent());
}
myPanel.insertDiffComponent(mySplitter.getComponent(), new MyScrollingPanel());
@@ -237,12 +237,28 @@ public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSid
}
myLeftSide.setHighlighterFactory(createHighlighter(types[0], baseFile, project));
myRightSide.setHighlighterFactory(createHighlighter(types[1], baseFile, project));
setSplitterProportion(content1, content2);
rediff();
if (myIsRequestFocus) {
myPanel.requestScrollEditors();
}
}
private void setSplitterProportion(DiffContent content1, DiffContent content2) {
if (content1.isEmpty()) {
mySplitter.setProportion(0f);
mySplitter.setResizeEnabled(false);
return;
}
if (content2.isEmpty()) {
mySplitter.setProportion(1.0f);
mySplitter.setResizeEnabled(false);
return;
}
mySplitter.setProportion(0.5f);
mySplitter.setResizeEnabled(true);
}
public void removeStatusBar() {
myPanel.removeStatusBar();
}
@@ -32,4 +32,8 @@ public interface DiffSplitterI {
VisibleAreaListener getVisibleAreaListener();
JComponent getComponent();
void setProportion(final float proportion);
void setResizeEnabled(boolean value);
}
@@ -27,8 +27,8 @@ import javax.swing.*;
* Date: 8/12/11
* Time: 12:05 PM
*/
public class HorisontalDiffSplitter extends Splitter implements DiffSplitterI {
public HorisontalDiffSplitter(final JComponent first, final JComponent second) {
public class HorizontalDiffSplitter extends Splitter implements DiffSplitterI {
public HorizontalDiffSplitter(final JComponent first, final JComponent second) {
super(true);
setFirstComponent(first);
setSecondComponent(second);
@@ -47,4 +47,16 @@ public class HorisontalDiffSplitter extends Splitter implements DiffSplitterI {
public JComponent getComponent() {
return this;
}
@Override
public void setProportion(float proportion) {
super.setProportion(proportion);
// I regret to put this hack here
if (getFirstComponent() != null) {
getFirstComponent().setVisible(proportion > 0.0001f);
}
if (getSecondComponent() != null) {
getSecondComponent().setVisible(proportion < 0.9999f);
}
}
}
@@ -115,6 +115,10 @@ public class Splitter extends JPanel {
setOrientation(myVerticalSplit);
}
public void setResizeEnabled(final boolean value) {
myDivider.setResizeEnabled(value);
}
public boolean isShowDividerIcon() {
return myShowDividerIcon;
}
@@ -591,6 +595,13 @@ public class Splitter extends JPanel {
public void setResizeEnabled(boolean resizeEnabled) {
myResizeEnabled = resizeEnabled;
if (! myResizeEnabled) {
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
} else {
setCursor(getOrientation() ?
Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR) :
Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
}
}
}
}
@@ -313,7 +313,7 @@ public class ChangesFragmentedDiffPanel implements Disposable {
private void adjustPanelData(final DiffPanelImpl diffPanel) {
final FragmentedDiffPanelState diffPanelState = (FragmentedDiffPanelState)diffPanel.getDiffPanelState();
diffPanelState.setRanges(myFragmentedContent.getLineRanges());
diffPanel.setContents(new SimpleContent(myFragmentedContent.getSbOld().toString()), new SimpleContent(myFragmentedContent.getSbNew().toString()));
diffPanel.setContents(myFragmentedContent.createBeforeContent(), myFragmentedContent.createAfterContent());
diffPanel.setLineNumberConvertors(myFragmentedContent.getOldConvertor(), myFragmentedContent.getNewConvertor());
diffPanel.prefferedSizeByContents(-1);
}
@@ -382,6 +382,8 @@ public class ChangesFragmentedDiffPanel implements Disposable {
if (myFragmentedContent != null && ! Comparing.equal(myPresentationState, current)) {
myFragmentedContent.recalculate();
refreshData(myFragmentedContent);
} else {
ensurePresentation();
}
myPreviousDiff.registerCustomShortcutSet(myPreviousDiff.getShortcutSet(), myParent);
myNextDiff.registerCustomShortcutSet(myNextDiff.getShortcutSet(), myParent);
@@ -30,6 +30,8 @@ public class FragmentedContent {
private final Document myBefore;
private final Document myAfter;
private final List<BeforeAfter<TextRange>> myRanges;
private boolean myOneSide;
private boolean myIsAddition;
public FragmentedContent(Document before, Document after, List<BeforeAfter<TextRange>> ranges) {
myBefore = before;
@@ -54,6 +56,18 @@ public class FragmentedContent {
}
public boolean isOneSide() {
return myRanges.size() == 1 && (myRanges.get(0).getAfter().isEmpty() || myRanges.get(0).getBefore().isEmpty());
return myOneSide;
}
public void setOneSide(boolean oneSide) {
myOneSide = oneSide;
}
public boolean isAddition() {
return myIsAddition;
}
public void setIsAddition(boolean isAddition) {
myIsAddition = isAddition;
}
}
@@ -28,6 +28,7 @@ import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.changes.actions.ShowDiffAction;
import com.intellij.openapi.vcs.ex.Range;
@@ -76,8 +77,11 @@ public class FragmentedDiffRequestFromChange {
}
List<BeforeAfter<TextRange>> ranges = calculator.getRanges();
if (ranges == null || ranges.isEmpty()) return null;
final PreparedFragmentedContent preparedFragmentedContent =
new PreparedFragmentedContent(myProject, new FragmentedContent(calculator.getOldDocument(), calculator.getDocument(), ranges),
FragmentedContent fragmentedContent = new FragmentedContent(calculator.getOldDocument(), calculator.getDocument(), ranges);
final FileStatus fs = change.getFileStatus();
fragmentedContent.setIsAddition(FileStatus.ADDED.equals(fs));
fragmentedContent.setOneSide(FileStatus.ADDED.equals(fs) || FileStatus.DELETED.equals(fs));
final PreparedFragmentedContent preparedFragmentedContent = new PreparedFragmentedContent(myProject, fragmentedContent,
filePath.getName(), filePath.getFileType());
VirtualFile file = filePath.getVirtualFile();
if (file == null) {
@@ -15,6 +15,8 @@
*/
package com.intellij.openapi.vcs.changes;
import com.intellij.openapi.diff.DiffContent;
import com.intellij.openapi.diff.SimpleContent;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.highlighter.*;
@@ -48,6 +50,7 @@ public class PreparedFragmentedContent {
private List<TextRange> myAfterFragments;
private List<BeforeAfter<Integer>> myLineRanges;
private boolean myOneSide;
private boolean myIsAddition;
private FragmentedEditorHighlighter myBeforeHighlighter;
private FragmentedEditorHighlighter myAfterHighlighter;
@@ -88,6 +91,7 @@ public class PreparedFragmentedContent {
private void fromFragmentedContent(final FragmentedContent fragmentedContent) {
myOneSide = fragmentedContent.isOneSide();
myIsAddition = fragmentedContent.isAddition();
List<BeforeAfter<TextRange>> expandedRanges =
expand(fragmentedContent.getRanges(), VcsConfiguration.getInstance(myProject).SHORT_DIFF_EXTRA_LINES,
fragmentedContent.getBefore(), fragmentedContent.getAfter());
@@ -145,6 +149,20 @@ public class PreparedFragmentedContent {
return newConvertor;
}
public DiffContent createBeforeContent() {
if (isAddition()) {
return SimpleContent.createEmpty();
}
return new SimpleContent(getSbOld().toString());
}
public DiffContent createAfterContent() {
if (isDeletion()) {
return SimpleContent.createEmpty();
}
return new SimpleContent(getSbNew().toString());
}
public StringBuilder getSbOld() {
return sbOld;
}
@@ -169,6 +187,14 @@ public class PreparedFragmentedContent {
return myOneSide;
}
public boolean isAddition() {
return myOneSide && myIsAddition;
}
public boolean isDeletion() {
return myOneSide && ! myIsAddition;
}
public FragmentedEditorHighlighter getBeforeHighlighter() {
return myBeforeHighlighter;
}
@@ -126,7 +126,7 @@ public class ChangeDiffRequestPresentable implements DiffRequestPresentable {
@NotNull
private DiffContent createContent(final ContentRevision revision) {
ProgressManager.checkCanceled();
if (revision == null) return new SimpleContent("");
if (revision == null) return SimpleContent.createEmpty();
if (revision instanceof CurrentContentRevision) {
final CurrentContentRevision current = (CurrentContentRevision)revision;
final VirtualFile vFile = current.getVirtualFile();