Java tutorial
/* * Copyright 2000-2013 JetBrains s.r.o. * Copyright 2013 Urs Wolfer * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.urswolfer.intellij.plugin.gerrit.ui.diff; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CustomShortcutSet; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.diff.*; import com.intellij.openapi.diff.impl.ComparisonPolicy; import com.intellij.openapi.diff.impl.DiffPanelImpl; import com.intellij.openapi.diff.impl.DiffUtil; import com.intellij.openapi.diff.impl.external.DiffManagerImpl; import com.intellij.openapi.diff.impl.external.FrameDiffTool; import com.intellij.openapi.keymap.KeymapManager; import com.intellij.openapi.ui.DialogBuilder; import com.intellij.openapi.ui.FrameWrapper; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.ex.MessagesEx; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.io.IOException; import java.util.Arrays; import java.util.Collection; /** * Copy of: * com.intellij.openapi.diff.impl.external.FrameDiffTool * * It allows to intercept DiffPanel creation (everything is private in FrameDiffTool). */ public class CustomizableFrameDiffTool extends FrameDiffTool { public void show(DiffRequest request) { Collection hints = request.getHints(); boolean shouldOpenDialog = shouldOpenDialog(hints); if (shouldOpenDialog) { final DialogBuilder builder = new DialogBuilder(request.getProject()); DiffPanelImpl diffPanel = createDiffPanelIfShouldShow(request, builder.getWindow(), builder, true); if (diffPanel == null) { Disposer.dispose(builder); return; } if (hints.contains(DiffTool.HINT_DIFF_IS_APPROXIMATE)) { diffPanel.setPatchAppliedApproximately(); // todo read only and not variants } final Runnable onOkRunnable = request.getOnOkRunnable(); if (onOkRunnable != null) { builder.setOkOperation(new Runnable() { @Override public void run() { builder.getDialogWrapper().close(0); onOkRunnable.run(); } }); } else { builder.removeAllActions(); } builder.setCenterPanel(diffPanel.getComponent()); builder.setPreferredFocusComponent(diffPanel.getPreferredFocusedComponent()); builder.setTitle(request.getWindowTitle()); builder.setDimensionServiceKey(request.getGroupKey()); new AnAction() { public void actionPerformed(final AnActionEvent e) { builder.getDialogWrapper().close(0); } }.registerCustomShortcutSet( new CustomShortcutSet( KeymapManager.getInstance().getActiveKeymap().getShortcuts("CloseContent")), diffPanel.getComponent()); showDiffDialog(builder, hints); } else { final FrameWrapper frameWrapper = new FrameWrapper(request.getProject(), request.getGroupKey()); DiffPanelImpl diffPanel = createDiffPanelIfShouldShow(request, frameWrapper.getFrame(), frameWrapper, true); if (diffPanel == null) { Disposer.dispose(frameWrapper); return; } if (hints.contains(DiffTool.HINT_DIFF_IS_APPROXIMATE)) { diffPanel.setPatchAppliedApproximately(); } frameWrapper.setTitle(request.getWindowTitle()); DiffUtil.initDiffFrame(diffPanel.getProject(), frameWrapper, diffPanel, diffPanel.getComponent()); new AnAction() { public void actionPerformed(final AnActionEvent e) { frameWrapper.getFrame().dispose(); } }.registerCustomShortcutSet( new CustomShortcutSet( KeymapManager.getInstance().getActiveKeymap().getShortcuts("CloseContent")), diffPanel.getComponent()); frameWrapper.show(); } } @Nullable private DiffPanelImpl createDiffPanelIfShouldShow(DiffRequest request, Window window, @NotNull Disposable parentDisposable, final boolean showMessage) { DiffPanelImpl diffPanel = (DiffPanelImpl) createDiffPanel(request, window, parentDisposable, this); if (checkNoDifferenceAndNotify(diffPanel, request, window, showMessage)) { Disposer.dispose(diffPanel); diffPanel = null; } return diffPanel; } static void showDiffDialog(DialogBuilder builder, Collection hints) { builder.showModal(!hints.contains(DiffTool.HINT_SHOW_NOT_MODAL_DIALOG)); } static boolean shouldOpenDialog(Collection hints) { if (hints.contains(DiffTool.HINT_SHOW_MODAL_DIALOG)) return true; if (hints.contains(DiffTool.HINT_SHOW_NOT_MODAL_DIALOG)) return true; if (hints.contains(DiffTool.HINT_SHOW_FRAME)) return false; return KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow() instanceof JDialog; } private boolean checkNoDifferenceAndNotify(DiffPanel diffPanel, DiffRequest data, final Window window, final boolean showMessage) { if (!diffPanel.hasDifferences() && !data.getHints().contains(HINT_ALLOW_NO_DIFFERENCES)) { DiffManagerImpl manager = (DiffManagerImpl) DiffManager.getInstance(); if (!Comparing.equal(manager.getComparisonPolicy(), ComparisonPolicy.DEFAULT)) { ComparisonPolicy oldPolicy = manager.getComparisonPolicy(); manager.setComparisonPolicy(ComparisonPolicy.DEFAULT); Disposable parentDisposable = Disposer.newDisposable(); DiffPanel maybeDiffPanel = createDiffPanel(data, window, parentDisposable, this); manager.setComparisonPolicy(oldPolicy); boolean hasDiffs = maybeDiffPanel.hasDifferences(); Disposer.dispose(parentDisposable); if (hasDiffs) return false; } if (!showMessage) { return true; } return !askForceOpenDiff(data); } return false; } private static boolean askForceOpenDiff(DiffRequest data) { byte[] bytes1; byte[] bytes2; try { bytes1 = data.getContents()[0].getBytes(); bytes2 = data.getContents()[1].getBytes(); } catch (IOException e) { MessagesEx.error(data.getProject(), e.getMessage()).showNow(); return false; } String message = Arrays.equals(bytes1, bytes2) ? DiffBundle.message("diff.contents.are.identical.message.text") : DiffBundle.message("diff.contents.have.differences.only.in.line.separators.message.text"); Messages.showInfoMessage(data.getProject(), message, DiffBundle.message("no.differences.dialog.title")); return false; } public boolean canShow(DiffRequest data) { return canShowDiff(data); } public static boolean canShowDiff(DiffRequest data) { DiffContent[] contents = data.getContents(); if (contents.length != 2) return false; for (DiffContent content : contents) { if (content.isBinary()) return false; VirtualFile file = content.getFile(); if (file != null && file.isDirectory()) return false; } return true; } @Override public DiffViewer createComponent(String title, DiffRequest request, Window window, @NotNull Disposable parentDisposable) { return createDiffPanelIfShouldShow(request, window, parentDisposable, false); } /** * Based on: * com.intellij.openapi.diff.impl.external.DiffManagerImpl#createDiffPanel */ private static final Logger LOG = Logger .getInstance("#com.intellij.openapi.diff.impl.external.DiffManagerImpl"); protected DiffPanel createDiffPanel(DiffRequest data, Window window, @NotNull Disposable parentDisposable, FrameDiffTool tool) { DiffPanel diffPanel = null; try { diffPanel = new DiffPanelImpl(window, data.getProject(), true, true, DiffManagerImpl.FULL_DIFF_DIVIDER_POLYGONS_OFFSET, tool) { @Override public void setDiffRequest(DiffRequest data) { super.setDiffRequest(data); diffRequestChange(data, this); } }; int contentCount = data.getContents().length; LOG.assertTrue(contentCount == 2, String.valueOf(contentCount)); LOG.assertTrue(data.getContentTitles().length == contentCount); diffPanel.setDiffRequest(data); return diffPanel; } catch (RuntimeException e) { if (diffPanel != null) { Disposer.dispose(diffPanel); } throw e; } } public void diffRequestChange(DiffRequest diffRequest, DiffPanelImpl diffPanel) { } }