diff --git a/platform/lang-impl/src/com/intellij/application/options/ChangesDiffCalculator.java b/platform/lang-impl/src/com/intellij/application/options/ChangesDiffCalculator.java index 26133fdeb5c7..fa2062e1e3d3 100644 --- a/platform/lang-impl/src/com/intellij/application/options/ChangesDiffCalculator.java +++ b/platform/lang-impl/src/com/intellij/application/options/ChangesDiffCalculator.java @@ -28,6 +28,7 @@ import com.intellij.openapi.diff.impl.util.TextDiffTypeEnum; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.colors.TextAttributesKey; import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.util.TextRange; import org.jetbrains.annotations.NotNull; @@ -108,6 +109,12 @@ public class ChangesDiffCalculator { @Override public void highlightText(Fragment fragment, boolean drawBorder) { } + + + @Override + public FileEditor getFileEditor() { + return null; + } } private static class ChangesCollector extends BaseMarkup { @@ -128,6 +135,5 @@ public class ChangesDiffCalculator { ranges.add(currentRange); } } - } } \ No newline at end of file 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 717b836374ea..41b45ec18985 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 @@ -41,6 +41,7 @@ import com.intellij.openapi.editor.ScrollingModel; import com.intellij.openapi.editor.event.VisibleAreaListener; import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.editor.ex.EditorMarkupModel; +import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.fileEditor.OpenFileDescriptor; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.project.Project; @@ -149,6 +150,10 @@ public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSid } } + public void removeStatusBar() { + myPanel.removeStatusBar(); + } + private static DiffHighlighterFactory createHighlighter(FileType contentType, VirtualFile file, Project project) { return new DiffHighlighterFactoryImpl(contentType, file, project); } @@ -246,11 +251,12 @@ public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSid public void onContentChangedIn(EditorSource source) { myDiffUpdater.contentRemoved(source); final EditorEx editor = source.getEditor(); + final FileEditor fileEditor = source.getFileEditor(); if (source.getSide() == FragmentSide.SIDE1 && editor != null) { editor.setVerticalScrollbarOrientation(EditorEx.VERTICAL_SCROLLBAR_LEFT); } DiffSideView viewSide = getSideView(source.getSide()); - viewSide.setEditorSource(source); + viewSide.setEditorSource(getProject(), source); Disposer.dispose(myScrollSupport); if (editor == null) { if (!myDisposed) { @@ -350,6 +356,9 @@ public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSid final JComponent newBottomComponent = data.getBottomComponent(); myPanel.setBottomComponent(newBottomComponent); + if (data.getContents()[0].isBinary() || data.getContents()[1].isBinary()) { + myPanel.removeStatusBar(); + } if (myIsRequestFocus) { if ((isEditor1Focused || isEditor2Focused)) { diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffSideView.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffSideView.java index b194d2938a1b..f7945f9cf2bc 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffSideView.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffSideView.java @@ -15,7 +15,10 @@ */ package com.intellij.openapi.diff.impl; +import com.intellij.ide.DataManager; import com.intellij.openapi.Disposable; +import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.diff.DiffContent; import com.intellij.openapi.diff.impl.highlighting.FragmentSide; import com.intellij.openapi.diff.impl.util.LabeledEditor; @@ -28,9 +31,12 @@ import com.intellij.openapi.editor.event.EditorMouseEventArea; import com.intellij.openapi.editor.event.EditorMouseMotionAdapter; import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.editor.highlighter.EditorHighlighter; +import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.fileEditor.OpenFileDescriptor; import com.intellij.openapi.project.Project; import com.intellij.util.IJSwingUtilities; +import com.intellij.util.ui.ScrollUtil; +import org.jetbrains.annotations.NonNls; import javax.swing.*; import java.awt.*; @@ -64,22 +70,37 @@ public class DiffSideView { return myPanel; } - public void setEditorSource(EditorSource source) { + public void setEditorSource(final Project project, final EditorSource source) { MyState state = new MyState(); myEditorSource = source; myLineMarker.attach(myEditorSource); Editor editor = myEditorSource.getEditor(); + final FileEditor fileEditor = myEditorSource.getFileEditor(); if (editor == null) { - insertComponent(MOCK_COMPONENT); - return; - } - editor.getScrollingModel().scrollHorizontally(0); - insertComponent(editor.getComponent()); - applyHighlighter(); - setMouseListeners(source); - MyEditorFocusListener.install(this); + insertComponent(fileEditor == null ? MOCK_COMPONENT : fileEditor.getComponent()); + DataManager.registerDataProvider(myPanel, new DataProvider() { + @Override + public Object getData(@NonNls String dataId) { + if (PlatformDataKeys.PROJECT.is(dataId)) {return project;} + if (PlatformDataKeys.FILE_EDITOR.is(dataId)) {return fileEditor;} + return null; + } + }); + if (fileEditor != null) { + ScrollUtil.scrollVertically(fileEditor.getComponent(), 0); + ScrollUtil.scrollHorizontally(fileEditor.getComponent(), 0); - state.restore(); + } + } else { + DataManager.removeDataProvider(myPanel); + editor.getScrollingModel().scrollHorizontally(0); + insertComponent(editor.getComponent()); + applyHighlighter(); + setMouseListeners(source); + MyEditorFocusListener.install(this); + + state.restore(); + } } private void insertComponent(JComponent component) { diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/EditorSource.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/EditorSource.java index 470feb3e39f5..20cab36efe86 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/EditorSource.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/EditorSource.java @@ -20,30 +20,47 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.diff.DiffContent; import com.intellij.openapi.diff.impl.highlighting.FragmentSide; import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.fileEditor.FileEditor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +/** + * @author Konstantin Bulenkov + * @author max + */ public interface EditorSource { - FragmentSide getSide(); - DiffContent getContent(); + @Nullable FragmentSide getSide(); + + @Nullable DiffContent getContent(); + + @Nullable EditorEx getEditor(); + + @Nullable FileEditor getFileEditor(); + + void addDisposable(@NotNull Disposable disposable); EditorSource NULL = new EditorSource() { public EditorEx getEditor() { return null; } - public void addDisposable(Disposable disposable) { + @Override + public FileEditor getFileEditor() { + return null; + } + + public void addDisposable(@NotNull Disposable disposable) { Logger.getInstance("#com.intellij.openapi.diff.impl.EditorSource").assertTrue(false); } + @Nullable public FragmentSide getSide() { return null; } + @Nullable public DiffContent getContent() { return null; } }; - - EditorEx getEditor(); - - void addDisposable(Disposable disposable); } diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/BinaryDiffTool.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/BinaryDiffTool.java index a4ea8a1a7162..0ca8e4d13eee 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/BinaryDiffTool.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/BinaryDiffTool.java @@ -16,47 +16,100 @@ package com.intellij.openapi.diff.impl.external; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.diff.DiffContent; -import com.intellij.openapi.diff.DiffRequest; -import com.intellij.openapi.diff.DiffTool; -import com.intellij.openapi.diff.DiffBundle; +import com.intellij.openapi.diff.*; +import com.intellij.openapi.fileEditor.FileEditorProvider; +import com.intellij.openapi.fileEditor.ex.FileEditorProviderManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Disposer; import com.intellij.openapi.vfs.VirtualFile; +import javax.swing.*; import java.io.IOException; import java.util.Arrays; -class BinaryDiffTool implements DiffTool { +/** + * @author Konstantin Bulenkov + * @author max + */ +public class BinaryDiffTool implements DiffTool { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.external.BinaryDiffTool"); public static final DiffTool INSTANCE = new BinaryDiffTool(); - public void show(DiffRequest data) { - DiffContent[] contents = data.getContents(); - try { - compareBinaryFiles(contents[0].getBytes(), contents[1].getBytes()); + + public void show(final DiffRequest data) { + final DiffContent current = data.getContents()[0]; + final DiffContent upToDate = data.getContents()[1]; + final Project project = data.getProject(); + if ((current instanceof FileContent && upToDate instanceof FileContent)) { + final VirtualFile src = current.getFile(); + final VirtualFile trg = upToDate.getFile(); + if (src != null && trg != null) { + final FileEditorProvider[] srcProvider = FileEditorProviderManager.getInstance().getProviders(project, src); + final FileEditorProvider[] trgProvider = FileEditorProviderManager.getInstance().getProviders(project, trg); + if (srcProvider.length > 0 && trgProvider.length > 0) { + new DialogWrapper(project) { + public DiffPanel myPanel; + { + setModal(false); + init(); + } + + @Override + protected String getDimensionServiceKey() { + return "BinaryDiffDialog"; + } + + @Override + protected Action[] createActions() { + final Action close = getCancelAction(); + close.putValue(Action.NAME, "&Close"); + return new Action[]{close}; + } + + @Override + protected void dispose() { + super.dispose(); + Disposer.dispose(myPanel); + } + + @Override + protected JComponent createCenterPanel() { + myPanel = DiffManager.getInstance().createDiffPanel(getWindow(), project); + myPanel.setDiffRequest(data); + myPanel.setTitle1(src.getPath()); + myPanel.setTitle2(trg.getPath()); + return myPanel.getComponent(); + } + }.show(); + return; + } + } } - catch (IOException e) { + try { + final boolean equal = Arrays.equals(current.getBytes(), upToDate.getBytes()); + Messages.showMessageDialog(equal + ? DiffBundle.message("binary.files.are.identical.message") + : DiffBundle.message("binary.files.are.different.message"), + equal + ? DiffBundle.message("files.are.identical.dialog.title") + : DiffBundle.message("files.are.different.dialog.title"), + Messages.getInformationIcon()); + } catch (IOException e) { LOG.error(e); } } - private static void compareBinaryFiles(byte[] currentContent, byte[] upToDateContent) { - if (Arrays.equals(currentContent, upToDateContent)) { - Messages.showMessageDialog(DiffBundle.message("binary.files.are.identical.message"), - DiffBundle.message("files.are.identical.dialog.title"), Messages.getInformationIcon()); + public boolean canShow(final DiffRequest data) { + final DiffContent[] contents = data.getContents(); + if (contents.length != 2) { + return false; } - else { - Messages.showMessageDialog(DiffBundle.message("binary.files.are.different.message"), - DiffBundle.message("files.are.different.dialog.title"), Messages.getInformationIcon()); - } - } - - public boolean canShow(DiffRequest data) { - DiffContent[] contents = data.getContents(); - if (contents.length != 2) return false; - for (int i = 0; i < contents.length; i++) { - DiffContent content = contents[i]; - VirtualFile file = content.getFile(); - if (file != null && file.isDirectory()) return false; + for (DiffContent content : contents) { + final VirtualFile file = content.getFile(); + if (file == null || file.isDirectory()) { + return false; + } } return true; } diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/DiffMarkup.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/DiffMarkup.java index d808029ddf47..b8de9ff6a654 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/DiffMarkup.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/DiffMarkup.java @@ -189,7 +189,7 @@ public abstract class DiffMarkup implements EditorSource { myDisposables.clear(); } - public void addDisposable(Disposable disposable) { + public void addDisposable(@NotNull Disposable disposable) { myDisposables.add(disposable); } diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/EditorPlaceHolder.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/EditorPlaceHolder.java index 6b836eee8392..1551e2855842 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/EditorPlaceHolder.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/EditorPlaceHolder.java @@ -25,7 +25,11 @@ import com.intellij.openapi.diff.impl.util.ContentDocumentListener; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.EditorFactory; import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileEditor.FileEditorProvider; +import com.intellij.openapi.fileEditor.ex.FileEditorProviderManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; class EditorPlaceHolder extends DiffMarkup implements DiffVersionComponent { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.highlighting.EditorWrapper"); @@ -33,6 +37,8 @@ class EditorPlaceHolder extends DiffMarkup implements DiffVersionComponent { private DiffContent myContent; private final FragmentSide mySide; private ContentChangeListener myListener = null; + private FileEditor myFileEditor; + private FileEditorProvider myFileEditorProvider; public EditorPlaceHolder(FragmentSide side, Project project) { super(project); @@ -60,22 +66,45 @@ class EditorPlaceHolder extends DiffMarkup implements DiffVersionComponent { myContent = content; if (myContent != null) { Document document = myContent.getDocument(); - final EditorFactory editorFactory = EditorFactory.getInstance(); - myEditor = DiffUtil.createEditor(document, getProject(), false); - addDisposable(new Disposable() { - public void dispose() { - editorFactory.releaseEditor(myEditor); - myEditor = null; + if (myContent.isBinary() || document == null) { + final VirtualFile file = myContent.getFile(); + if (file != null) { + final FileEditorProvider[] providers = FileEditorProviderManager.getInstance().getProviders(getProject(), file); + if (providers.length > 0) { + myFileEditor = providers[0].createEditor(getProject(), file); + myFileEditorProvider = providers[0]; + addDisposable(new Disposable() { + @Override + public void dispose() { + myFileEditorProvider.disposeEditor(myFileEditor); + myFileEditor = null; + myFileEditorProvider = null; + } + }); + } } - }); - ContentDocumentListener.install(myContent, this); + } else { + final EditorFactory editorFactory = EditorFactory.getInstance(); + myEditor = DiffUtil.createEditor(document, getProject(), false); + addDisposable(new Disposable() { + public void dispose() { + editorFactory.releaseEditor(myEditor); + myEditor = null; + } + }); + ContentDocumentListener.install(myContent, this); + } } fireContentChanged(); } - public EditorEx getEditor() { return myEditor; } + public EditorEx getEditor() { + return myEditor; + } - public FragmentSide getSide() { return mySide; } + public FragmentSide getSide() { + return mySide; + } public DiffContent getContent() { return myContent; @@ -84,4 +113,9 @@ class EditorPlaceHolder extends DiffMarkup implements DiffVersionComponent { public void removeContent() { setContent(null); } + + @Override + public FileEditor getFileEditor() { + return myFileEditor; + } } diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/DiffPanelOutterComponent.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/DiffPanelOutterComponent.java index 373a1917dcb9..44b18108c4a5 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/DiffPanelOutterComponent.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/DiffPanelOutterComponent.java @@ -85,6 +85,10 @@ public class DiffPanelOutterComponent extends JPanel implements DataProvider { return new Dimension(600, 400); } + public void removeStatusBar() { + myBottomContainer.remove(myStatusBar); + } + public Object getData(String dataId) { if (PlatformDataKeys.SOURCE_NAVIGATION_LOCKED.is(dataId)) { return Boolean.TRUE; diff --git a/platform/util/src/com/intellij/util/ui/ScrollUtil.java b/platform/util/src/com/intellij/util/ui/ScrollUtil.java index abc235b87bc0..790a2b9dc692 100644 --- a/platform/util/src/com/intellij/util/ui/ScrollUtil.java +++ b/platform/util/src/com/intellij/util/ui/ScrollUtil.java @@ -16,40 +16,112 @@ package com.intellij.util.ui; +import org.jetbrains.annotations.Nullable; + import javax.swing.*; import java.awt.*; /** - * @author mike + * @author Konstantin Bulenkov */ public class ScrollUtil { - private ScrollUtil() { + private ScrollUtil() {} + + + @Nullable + public static JScrollPane findScrollPane(JComponent c) { + if (c == null) return null; + return UIUtil.findComponentOfType(c, JScrollPane.class); } - public static void center(JComponent c, Rectangle r) { + @Nullable + public static JScrollBar findVerticalScrollBar(JComponent c) { + return findScrollBar(c, Adjustable.VERTICAL); + } + + @Nullable + public static JScrollBar findHorizontalScrollBar(JComponent c) { + return findScrollBar(c, Adjustable.HORIZONTAL); + } + + @Nullable + private static JScrollBar findScrollBar(JComponent c, int orientation) { + if (c == null) return null; + if (c instanceof JScrollBar && ((JScrollBar)c).getOrientation() == orientation) { + return (JScrollBar)c; + } + for (Component comp : c.getComponents()) { + if (comp instanceof JComponent) { + final JScrollBar scrollBar = findScrollBar((JComponent)comp, orientation); + if (scrollBar != null) { + return scrollBar; + } + } + } + return null; + } + + public static void scrollVertically(JComponent c, int position) { + final JScrollPane pane = findScrollPane(c); + if (pane != null) { + final JScrollBar bar = pane.getVerticalScrollBar(); + if (bar != null) { + bar.setValue(position); + } + } else { + final JScrollBar scrollBar = findVerticalScrollBar(c); + if (scrollBar != null) { + scrollBar.setValue(position); + } + } + } + + public static void scrollHorizontally(JComponent c, int position) { + final JScrollPane pane = findScrollPane(c); + if (pane != null) { + final JScrollBar bar = pane.getHorizontalScrollBar(); + if (bar != null) { + bar.setValue(position); + } + } else { + final JScrollBar scrollBar = findHorizontalScrollBar(c); + if (scrollBar != null) { + scrollBar.setValue(position); + } + } + } + + public static void center(final JComponent c, final Rectangle r) { center(c, r, false); } - public static void center(JComponent c, Rectangle r, boolean withInsets) { - Rectangle visible = c.getVisibleRect(); - + public static void center(final JComponent c, final Rectangle r, final boolean withInsets) { + final Rectangle visible = c.getVisibleRect(); visible.x = r.x - (visible.width - r.width) / 2; visible.y = r.y - (visible.height - r.height) / 2; - Rectangle bounds = c.getBounds(); - Insets i = withInsets ? new Insets(0, 0, 0, 0) : c.getInsets(); + final Rectangle bounds = c.getBounds(); + final Insets i = withInsets ? new Insets(0, 0, 0, 0) : c.getInsets(); bounds.x = i.left; bounds.y = i.top; bounds.width -= i.left + i.right; bounds.height -= i.top + i.bottom; - if (visible.x < bounds.x) visible.x = bounds.x; + if (visible.x < bounds.x) { + visible.x = bounds.x; + } - if (visible.x + visible.width > bounds.x + bounds.width) visible.x = bounds.x + bounds.width - visible.width; + if (visible.x + visible.width > bounds.x + bounds.width) { + visible.x = bounds.x + bounds.width - visible.width; + } - if (visible.y < bounds.y) visible.y = bounds.y; + if (visible.y < bounds.y) { + visible.y = bounds.y; + } - if (visible.y + visible.height > bounds.y + bounds.height) visible.y = bounds.y + bounds.height - visible.height; + if (visible.y + visible.height > bounds.y + bounds.height) { + visible.y = bounds.y + bounds.height - visible.height; + } c.scrollRectToVisible(visible); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/history/VcsHistoryUtil.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/VcsHistoryUtil.java index d886b0d1e879..6c528b080267 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/history/VcsHistoryUtil.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/VcsHistoryUtil.java @@ -15,19 +15,27 @@ */ package com.intellij.openapi.vcs.history; +import com.intellij.openapi.Disposable; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diff.*; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.Ref; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vcs.FilePath; import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vfs.CharsetToolkit; +import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.encoding.EncodingManager; import com.intellij.openapi.vfs.encoding.EncodingProjectManager; import com.intellij.util.WaitForProgressToShow; import org.jetbrains.annotations.Nullable; +import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.nio.charset.Charset; @@ -69,7 +77,7 @@ public class VcsHistoryUtil { * @throws com.intellij.openapi.vcs.VcsException * @throws java.io.IOException */ - public static void showDiff(Project project, FilePath filePath, VcsFileRevision revision1, VcsFileRevision revision2, String title1, String title2) throws VcsException, IOException { + public static void showDiff(final Project project, FilePath filePath, VcsFileRevision revision1, VcsFileRevision revision2, String title1, String title2) throws VcsException, IOException { final byte[] content1 = loadRevisionContent(revision1); final byte[] content2 = loadRevisionContent(revision2); @@ -79,11 +87,54 @@ public class VcsHistoryUtil { final Charset charset = filePath.getCharset(); final FileType fileType = filePath.getFileType(); diffData.setContentTitles(title1, title2); - diffData.setContents(createContent(project, content1, revision1, doc, charset, fileType), - createContent(project, content2, revision2, doc, charset, fileType)); + final Ref f1 = new Ref(null); + final Ref f2 = new Ref(null); + + if (fileType.isBinary()) { + final File file1 = FileUtil.createTempFile(revision1.getRevisionNumber().asString(), filePath.getName()); + final File file2 = FileUtil.createTempFile(revision2.getRevisionNumber().asString(), filePath.getName()); + try { + final FileOutputStream fos1 = new FileOutputStream(file1); + fos1.write(content1); + final FileOutputStream fos2 = new FileOutputStream(file2); + fos2.write(content2); + fos1.close(); + fos2.close(); + f1.set(LocalFileSystem.getInstance().findFileByIoFile(file1)); + f2.set(LocalFileSystem.getInstance().findFileByIoFile(file2)); + } catch(Exception e) {// + } + } + if (f1.isNull() || f2.isNull()) { + diffData.setContents(createContent(project, content1, revision1, doc, charset, fileType), + createContent(project, content2, revision2, doc, charset, fileType)); + } else { + diffData.setContents(new FileContent(project, f1.get()), new FileContent(project, f2.get())); + } WaitForProgressToShow.runOrInvokeLaterAboveProgress(new Runnable() { public void run() { DiffManager.getInstance().getDiffTool().show(diffData); + if (!f1.isNull() || !f2.isNull()) { + Disposer.register(project, new Disposable() { + @Override + public void dispose() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + try { + if (!f1.isNull()) { + f1.get().delete(this); + } + if (!f2.isNull()) { + f2.get().delete(this); + } + } + catch (IOException e) {// + } + } + }); + } + }); + } } }, null, project); }