diff --git a/platform/platform-api/src/com/intellij/openapi/diff/DiffContent.java b/platform/platform-api/src/com/intellij/openapi/diff/DiffContent.java index e3ab91dcf671..ffeabcc88176 100644 --- a/platform/platform-api/src/com/intellij/openapi/diff/DiffContent.java +++ b/platform/platform-api/src/com/intellij/openapi/diff/DiffContent.java @@ -32,6 +32,7 @@ import java.util.List; */ public abstract class DiffContent { private final List 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 diff --git a/platform/platform-api/src/com/intellij/openapi/diff/SimpleContent.java b/platform/platform-api/src/com/intellij/openapi/diff/SimpleContent.java index 42e812a2f3c0..a3ee3b42e9fa 100644 --- a/platform/platform-api/src/com/intellij/openapi/diff/SimpleContent.java +++ b/platform/platform-api/src/com/intellij/openapi/diff/SimpleContent.java @@ -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. */ diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffPanelImpl.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffPanelImpl.java index 68bc9d79333d..33a3cbee1f2e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffPanelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffPanelImpl.java @@ -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(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffSplitterI.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffSplitterI.java index d6b5ebf93c6d..49c7184b8db6 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffSplitterI.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffSplitterI.java @@ -32,4 +32,8 @@ public interface DiffSplitterI { VisibleAreaListener getVisibleAreaListener(); JComponent getComponent(); + + void setProportion(final float proportion); + + void setResizeEnabled(boolean value); } diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/processing/HorisontalDiffSplitter.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/processing/HorizontalDiffSplitter.java similarity index 72% rename from platform/platform-impl/src/com/intellij/openapi/diff/impl/processing/HorisontalDiffSplitter.java rename to platform/platform-impl/src/com/intellij/openapi/diff/impl/processing/HorizontalDiffSplitter.java index d38c2b82e29a..ca6d9df6c745 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/processing/HorisontalDiffSplitter.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/processing/HorizontalDiffSplitter.java @@ -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); + } + } } diff --git a/platform/util/src/com/intellij/openapi/ui/Splitter.java b/platform/util/src/com/intellij/openapi/ui/Splitter.java index 25933d3f5490..8e4b183ed269 100644 --- a/platform/util/src/com/intellij/openapi/ui/Splitter.java +++ b/platform/util/src/com/intellij/openapi/ui/Splitter.java @@ -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)); + } } } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesFragmentedDiffPanel.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesFragmentedDiffPanel.java index a16ac4a00e9a..e6337cf6560e 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesFragmentedDiffPanel.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesFragmentedDiffPanel.java @@ -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); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FragmentedContent.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FragmentedContent.java index cf3d18ec2875..6d13d21a996c 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FragmentedContent.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FragmentedContent.java @@ -30,6 +30,8 @@ public class FragmentedContent { private final Document myBefore; private final Document myAfter; private final List> myRanges; + private boolean myOneSide; + private boolean myIsAddition; public FragmentedContent(Document before, Document after, List> 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; } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FragmentedDiffRequestFromChange.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FragmentedDiffRequestFromChange.java index b4b21879235f..f867efc436ad 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FragmentedDiffRequestFromChange.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FragmentedDiffRequestFromChange.java @@ -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> 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) { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/PreparedFragmentedContent.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/PreparedFragmentedContent.java index e92a050311cb..71c6b4a4acab 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/PreparedFragmentedContent.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/PreparedFragmentedContent.java @@ -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 myAfterFragments; private List> 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> 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; } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ChangeDiffRequestPresentable.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ChangeDiffRequestPresentable.java index 896753e6c56d..c8bb85324281 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ChangeDiffRequestPresentable.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ChangeDiffRequestPresentable.java @@ -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();