/* * Copyright 2000-2015 JetBrains s.r.o. * * 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.intellij.diff.tools.simple; import com.intellij.diff.DiffContext; import com.intellij.diff.actions.AllLinesIterator; import com.intellij.diff.contents.DocumentContent; import com.intellij.diff.requests.ContentDiffRequest; import com.intellij.diff.requests.DiffRequest; import com.intellij.diff.tools.util.DiffDataKeys; import com.intellij.diff.tools.util.base.HighlightPolicy; import com.intellij.diff.tools.util.base.TextDiffViewerUtil; import com.intellij.diff.tools.util.side.OnesideTextDiffViewer; import com.intellij.diff.tools.util.text.TextDiffProvider; import com.intellij.diff.util.DiffDrawUtil; import com.intellij.diff.util.DiffUtil; import com.intellij.diff.util.LineRange; import com.intellij.diff.util.TextDiffType; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.Separator; import com.intellij.openapi.diff.DiffNavigationContext; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.LogicalPosition; import com.intellij.openapi.editor.markup.RangeHighlighter; import com.intellij.openapi.progress.ProgressIndicator; import org.jetbrains.annotations.CalledInAwt; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; import static com.intellij.diff.util.DiffUtil.getLineCount; public class SimpleOnesideDiffViewer extends OnesideTextDiffViewer { @NotNull private final MyInitialScrollHelper myInitialScrollHelper = new MyInitialScrollHelper(); @NotNull private final TextDiffProvider myTextDiffProvider; @NotNull private final List<RangeHighlighter> myHighlighters = new ArrayList<>(); public SimpleOnesideDiffViewer(@NotNull DiffContext context, @NotNull DiffRequest request) { super(context, (ContentDiffRequest)request); myTextDiffProvider = DiffUtil.createTextDiffProvider(getProject(), getRequest(), getTextSettings(), this::rediff, this); } @Override @CalledInAwt protected void onDispose() { for (RangeHighlighter highlighter : myHighlighters) { highlighter.dispose(); } myHighlighters.clear(); super.onDispose(); } @NotNull @Override protected List<AnAction> createToolbarActions() { List<AnAction> group = new ArrayList<>(); group.addAll(myTextDiffProvider.getToolbarActions()); group.add(new MyReadOnlyLockAction()); group.add(myEditorSettingsAction); group.add(Separator.getInstance()); group.addAll(super.createToolbarActions()); return group; } @NotNull @Override protected List<AnAction> createPopupActions() { List<AnAction> group = new ArrayList<>(); group.addAll(myTextDiffProvider.getPopupActions()); group.add(Separator.getInstance()); group.addAll(super.createPopupActions()); return group; } @Override @CalledInAwt protected void processContextHints() { super.processContextHints(); myInitialScrollHelper.processContext(myRequest); } @Override @CalledInAwt protected void updateContextHints() { super.updateContextHints(); myInitialScrollHelper.updateContext(myRequest); } // // Diff // @Override @NotNull protected Runnable performRediff(@NotNull final ProgressIndicator indicator) { return () -> { clearDiffPresentation(); boolean shouldHighlight = getTextSettings().getHighlightPolicy() != HighlightPolicy.DO_NOT_HIGHLIGHT; if (shouldHighlight) { final DocumentContent content = getContent(); final Document document = content.getDocument(); TextDiffType type = getSide().select(TextDiffType.DELETED, TextDiffType.INSERTED); myHighlighters.addAll(DiffDrawUtil.createHighlighter(getEditor(), 0, getLineCount(document), type, false)); } myInitialScrollHelper.onRediff(); }; } private void clearDiffPresentation() { myPanel.resetNotifications(); for (RangeHighlighter highlighter : myHighlighters) { highlighter.dispose(); } myHighlighters.clear(); } // // Impl // private void doScrollToChange(final boolean animated) { DiffUtil.moveCaret(getEditor(), 0); DiffUtil.scrollEditor(getEditor(), 0, animated); } protected boolean doScrollToContext(@NotNull DiffNavigationContext context) { if (getSide().isLeft()) return false; AllLinesIterator allLinesIterator = new AllLinesIterator(getEditor().getDocument()); int line = context.contextMatchCheck(allLinesIterator); if (line == -1) return false; scrollToLine(line); return true; } // // Misc // @SuppressWarnings("MethodOverridesStaticMethodOfSuperclass") public static boolean canShowRequest(@NotNull DiffContext context, @NotNull DiffRequest request) { return OnesideTextDiffViewer.canShowRequest(context, request); } // // Actions // private class MyReadOnlyLockAction extends TextDiffViewerUtil.EditorReadOnlyLockAction { public MyReadOnlyLockAction() { super(getContext(), getEditableEditors()); } } // // Helpers // @Nullable @Override public Object getData(@NonNls String dataId) { if (DiffDataKeys.CURRENT_CHANGE_RANGE.is(dataId)) { int lineCount = getLineCount(getEditor().getDocument()); return new LineRange(0, lineCount); } return super.getData(dataId); } private class MyInitialScrollHelper extends MyInitialScrollPositionHelper { @Override protected boolean doScrollToChange() { if (myScrollToChange == null) return false; SimpleOnesideDiffViewer.this.doScrollToChange(false); return true; } @Override protected boolean doScrollToFirstChange() { SimpleOnesideDiffViewer.this.doScrollToChange(false); return true; } @Override protected boolean doScrollToContext() { if (myNavigationContext == null) return false; return SimpleOnesideDiffViewer.this.doScrollToContext(myNavigationContext); } @Override protected boolean doScrollToPosition() { if (myCaretPosition == null) return false; LogicalPosition position = getSide().select(myCaretPosition); getEditor().getCaretModel().moveToLogicalPosition(position); if (myEditorsPosition != null && myEditorsPosition.isSame(position)) { DiffUtil.scrollToPoint(getEditor(), myEditorsPosition.myPoints[0], false); } else { DiffUtil.scrollToCaret(getEditor(), false); } return true; } @Nullable @Override protected LogicalPosition[] getCaretPositions() { int index = getSide().getIndex(); int otherIndex = getSide().other().getIndex(); LogicalPosition[] carets = new LogicalPosition[2]; carets[index] = getEditor().getCaretModel().getLogicalPosition(); carets[otherIndex] = new LogicalPosition(0, 0); return carets; } } }