mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-139555 diff: show 'go to next file' popup near selected change or cursor
This commit is contained in:
@@ -34,6 +34,7 @@ import com.intellij.diff.util.DiffUserDataKeys;
|
||||
import com.intellij.diff.util.DiffUserDataKeysEx;
|
||||
import com.intellij.diff.util.DiffUserDataKeysEx.ScrollToPolicy;
|
||||
import com.intellij.diff.util.DiffUtil;
|
||||
import com.intellij.diff.util.LineRange;
|
||||
import com.intellij.ide.DataManager;
|
||||
import com.intellij.ide.impl.DataManagerImpl;
|
||||
import com.intellij.openapi.Disposable;
|
||||
@@ -41,6 +42,7 @@ import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.actionSystem.ex.ComboBoxAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.LogicalPosition;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -668,7 +670,7 @@ public abstract class DiffRequestProcessor implements Disposable {
|
||||
if (!isNavigationEnabled() || !hasNextChange() || !getSettings().isGoToNextFileOnNextDifference()) return;
|
||||
|
||||
if (myIterationState != IterationState.NEXT) {
|
||||
notifyMessage(e.getData(DiffDataKeys.CURRENT_EDITOR), true);
|
||||
notifyMessage(e, true);
|
||||
myIterationState = IterationState.NEXT;
|
||||
return;
|
||||
}
|
||||
@@ -717,7 +719,7 @@ public abstract class DiffRequestProcessor implements Disposable {
|
||||
if (!isNavigationEnabled() || !hasPrevChange() || !getSettings().isGoToNextFileOnNextDifference()) return;
|
||||
|
||||
if (myIterationState != IterationState.PREV) {
|
||||
notifyMessage(e.getData(DiffDataKeys.CURRENT_EDITOR), false);
|
||||
notifyMessage(e, false);
|
||||
myIterationState = IterationState.PREV;
|
||||
return;
|
||||
}
|
||||
@@ -726,32 +728,54 @@ public abstract class DiffRequestProcessor implements Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyMessage(@Nullable Editor editor, boolean next) {
|
||||
private void notifyMessage(@NotNull AnActionEvent e, boolean next) {
|
||||
Editor editor = e.getData(DiffDataKeys.CURRENT_EDITOR);
|
||||
|
||||
// TODO: provide "change" word in chain UserData - for tests/etc
|
||||
String message = next ? "Press again to go to the next file" : "Press again to go to the previous file";
|
||||
|
||||
final LightweightHint hint = new LightweightHint(HintUtil.createInformationLabel(message));
|
||||
Point point = new Point(myContentPanel.getWidth() / 2, next ? myContentPanel.getHeight() - JBUI.scale(40) : JBUI.scale(40));
|
||||
|
||||
final HintHint hintHint = new HintHint(myContentPanel, point)
|
||||
.setPreferredPosition(next ? Balloon.Position.above : Balloon.Position.below)
|
||||
.setAwtTooltip(true)
|
||||
.setFont(UIUtil.getLabelFont().deriveFont(Font.BOLD))
|
||||
.setTextBg(HintUtil.INFORMATION_COLOR)
|
||||
.setShowImmediately(true);
|
||||
|
||||
if (editor == null) {
|
||||
final Component owner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
|
||||
final HintHint hintHint = createNotifyHint(myContentPanel, point, next);
|
||||
hint.show(myContentPanel, point.x, point.y, owner instanceof JComponent ? (JComponent)owner : null, hintHint);
|
||||
}
|
||||
else {
|
||||
Point editorPoint = SwingUtilities.convertPoint(myContentPanel, point, editor.getComponent());
|
||||
int x = SwingUtilities.convertPoint(myContentPanel, point, editor.getComponent()).x;
|
||||
|
||||
JComponent header = editor.getHeaderComponent();
|
||||
int shift = editor.getScrollingModel().getVerticalScrollOffset() - (header != null ? header.getHeight() : 0);
|
||||
|
||||
LogicalPosition position;
|
||||
LineRange changeRange = e.getData(DiffDataKeys.CURRENT_CHANGE_RANGE);
|
||||
if (changeRange == null) {
|
||||
position = new LogicalPosition(editor.getCaretModel().getLogicalPosition().line + (next ? 1 : 0), 0);
|
||||
}
|
||||
else {
|
||||
position = new LogicalPosition(next ? changeRange.end : changeRange.start, 0);
|
||||
}
|
||||
int y = editor.logicalPositionToXY(position).y - shift;
|
||||
|
||||
Point editorPoint = new Point(x, y);
|
||||
final HintHint hintHint = createNotifyHint(editor.getComponent(), editorPoint, !next);
|
||||
HintManagerImpl.getInstanceImpl().showEditorHint(hint, editor, editorPoint, HintManager.HIDE_BY_ANY_KEY |
|
||||
HintManager.HIDE_BY_TEXT_CHANGE |
|
||||
HintManager.HIDE_BY_SCROLLING, 0, false, hintHint);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static HintHint createNotifyHint(@NotNull JComponent component, @NotNull Point point, boolean above) {
|
||||
return new HintHint(component, point)
|
||||
.setPreferredPosition(above ? Balloon.Position.above : Balloon.Position.below)
|
||||
.setAwtTooltip(true)
|
||||
.setFont(UIUtil.getLabelFont().deriveFont(Font.BOLD))
|
||||
.setTextBg(HintUtil.INFORMATION_COLOR)
|
||||
.setShowImmediately(true);
|
||||
}
|
||||
|
||||
// Iterate requests
|
||||
|
||||
protected class MyNextChangeAction extends NextChangeAction {
|
||||
|
||||
@@ -566,6 +566,18 @@ public class OnesideDiffViewer extends TextDiffViewerBase {
|
||||
return getOpenFileDescriptor(myEditor.getCaretModel().getOffset());
|
||||
}
|
||||
|
||||
@CalledInAwt
|
||||
@Nullable
|
||||
protected OnesideDiffChange getCurrentChange() {
|
||||
if (myChangedBlockData == null) return null;
|
||||
int caretLine = myEditor.getCaretModel().getLogicalPosition().line;
|
||||
|
||||
for (OnesideDiffChange change : myChangedBlockData.getDiffChanges()) {
|
||||
if (DiffUtil.isSelectedByLine(caretLine, change.getLine1(), change.getLine2())) return change;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected OpenFileDescriptor getOpenFileDescriptor(int offset) {
|
||||
assert myActualContent1 != null || myActualContent2 != null;
|
||||
@@ -806,9 +818,13 @@ public class OnesideDiffViewer extends TextDiffViewerBase {
|
||||
else if (DiffDataKeys.CURRENT_EDITOR.is(dataId)) {
|
||||
return myEditor;
|
||||
}
|
||||
else {
|
||||
return super.getData(dataId);
|
||||
else if (DiffDataKeys.CURRENT_CHANGE_RANGE.is(dataId)) {
|
||||
OnesideDiffChange change = getCurrentChange();
|
||||
if (change != null) {
|
||||
return new LineRange(change.getLine1(), change.getLine2());
|
||||
}
|
||||
}
|
||||
return super.getData(dataId);
|
||||
}
|
||||
|
||||
private class MyStatusPanel extends StatusPanel {
|
||||
|
||||
@@ -27,12 +27,9 @@ import com.intellij.diff.requests.DiffRequest;
|
||||
import com.intellij.diff.tools.util.*;
|
||||
import com.intellij.diff.tools.util.base.HighlightPolicy;
|
||||
import com.intellij.diff.tools.util.twoside.TwosideTextDiffViewer;
|
||||
import com.intellij.diff.util.DiffDividerDrawUtil;
|
||||
import com.intellij.diff.util.DiffDrawUtil;
|
||||
import com.intellij.diff.util.*;
|
||||
import com.intellij.diff.util.DiffUserDataKeysEx.ScrollToPolicy;
|
||||
import com.intellij.diff.util.DiffUtil;
|
||||
import com.intellij.diff.util.DiffUtil.DocumentData;
|
||||
import com.intellij.diff.util.Side;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ide.IdeEventQueue;
|
||||
import com.intellij.openapi.Disposable;
|
||||
@@ -501,6 +498,23 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
return affectedChanges;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@CalledInAwt
|
||||
private SimpleDiffChange getSelectedChange(@NotNull Side side) {
|
||||
EditorEx editor = side.select(myEditor1, myEditor2);
|
||||
if (editor == null) return null;
|
||||
|
||||
int caretLine = editor.getCaretModel().getLogicalPosition().line;
|
||||
|
||||
for (SimpleDiffChange change : myDiffChanges) {
|
||||
int line1 = change.getStartLine(side);
|
||||
int line2 = change.getEndLine(side);
|
||||
|
||||
if (DiffUtil.isSelectedByLine(caretLine, line1, line2)) return change;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//
|
||||
// Actions
|
||||
//
|
||||
@@ -820,9 +834,13 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
if (DiffDataKeys.PREV_NEXT_DIFFERENCE_ITERABLE.is(dataId)) {
|
||||
return myPrevNextDifferenceIterable;
|
||||
}
|
||||
else {
|
||||
return super.getData(dataId);
|
||||
else if (DiffDataKeys.CURRENT_CHANGE_RANGE.is(dataId)) {
|
||||
SimpleDiffChange change = getSelectedChange(getCurrentSide());
|
||||
if (change != null) {
|
||||
return new LineRange(change.getStartLine(getCurrentSide()), change.getEndLine(getCurrentSide()));
|
||||
}
|
||||
}
|
||||
return super.getData(dataId);
|
||||
}
|
||||
|
||||
private class MySyncScrollable extends BaseSyncScrollable {
|
||||
|
||||
+23
-2
@@ -392,6 +392,22 @@ public class SimpleThreesideDiffViewer extends ThreesideTextDiffViewer {
|
||||
// Misc
|
||||
//
|
||||
|
||||
@Nullable
|
||||
@CalledInAwt
|
||||
private SimpleThreesideDiffChange getSelectedChange(@NotNull ThreeSide side) {
|
||||
EditorEx editor = side.select(myEditors);
|
||||
|
||||
int caretLine = editor.getCaretModel().getLogicalPosition().line;
|
||||
|
||||
for (SimpleThreesideDiffChange change : myDiffChanges) {
|
||||
int line1 = change.getStartLine(side);
|
||||
int line2 = change.getEndLine(side);
|
||||
|
||||
if (DiffUtil.isSelectedByLine(caretLine, line1, line2)) return change;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("MethodOverridesStaticMethodOfSuperclass")
|
||||
public static boolean canShowRequest(@NotNull DiffContext context, @NotNull DiffRequest request) {
|
||||
return ThreesideTextDiffViewer.canShowRequest(context, request);
|
||||
@@ -505,9 +521,14 @@ public class SimpleThreesideDiffViewer extends ThreesideTextDiffViewer {
|
||||
if (DiffDataKeys.PREV_NEXT_DIFFERENCE_ITERABLE.is(dataId)) {
|
||||
return myPrevNextDifferenceIterable;
|
||||
}
|
||||
else {
|
||||
return super.getData(dataId);
|
||||
else if (DiffDataKeys.CURRENT_CHANGE_RANGE.is(dataId)) {
|
||||
SimpleThreesideDiffChange change = getSelectedChange(getCurrentSide());
|
||||
if (change != null) {
|
||||
return new LineRange(change.getStartLine(getCurrentSide()), change.getEndLine(getCurrentSide()));
|
||||
}
|
||||
}
|
||||
|
||||
return super.getData(dataId);
|
||||
}
|
||||
|
||||
private class MySyncScrollable extends BaseSyncScrollable {
|
||||
|
||||
@@ -19,6 +19,8 @@ import com.intellij.diff.DiffContext;
|
||||
import com.intellij.diff.FrameDiffTool;
|
||||
import com.intellij.diff.contents.DiffContent;
|
||||
import com.intellij.diff.requests.DiffRequest;
|
||||
import com.intellij.diff.util.IntPair;
|
||||
import com.intellij.diff.util.LineRange;
|
||||
import com.intellij.openapi.actionSystem.DataKey;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
|
||||
@@ -26,6 +28,7 @@ import com.intellij.openapi.fileEditor.OpenFileDescriptor;
|
||||
public interface DiffDataKeys {
|
||||
DataKey<Editor> CURRENT_EDITOR = DataKey.create("diff_current_editor");
|
||||
DataKey<DiffContent> CURRENT_CONTENT = DataKey.create("diff_current_content");
|
||||
DataKey<LineRange> CURRENT_CHANGE_RANGE = DataKey.create("diff_current_change_range");
|
||||
|
||||
DataKey<DiffRequest> DIFF_REQUEST = DataKey.create("diff_request");
|
||||
DataKey<DiffContext> DIFF_CONTEXT = DataKey.create("diff_context");
|
||||
|
||||
Reference in New Issue
Block a user