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 731634b85080..fca5f9a4188a 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 @@ -55,6 +55,7 @@ import com.intellij.util.BeforeAfter; import com.intellij.util.PlatformIcons; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; @@ -152,88 +153,88 @@ public class ChangesFragmentedDiffPanel implements Disposable { private void createNavigateAction() { myNavigateAction = new DumbAwareAction("Edit Source", "Edit Source", AllIcons.Actions.EditSource) { + @Nullable + private OpenFileDescriptor createDescriptor() { + if (myFragmentedContent == null || myFragmentedContent.getFile() == null) return null; + + final DiffPanel panel = myCurrentHorizontal ? myHorizontal : myVertical; + final DiffSideView side = ((DiffPanelImpl)panel).getCurrentSide(); + if (side == null || side.getEditor() == null) return null; + + final boolean isAfter = FragmentSide.SIDE2.equals(side.getSide()); + if (isAfter) { + final LogicalPosition position = side.getEditor().getCaretModel().getLogicalPosition(); + final int line = position.line; + final int converted = myFragmentedContent.getNewConvertor().execute(line); + return new OpenFileDescriptor(myProject, myFragmentedContent.getFile(), converted, position.column); + } + + if (((DiffPanelImpl)panel).getEditor1().getDocument().getTextLength() == 0) { + return new OpenFileDescriptor(myProject, myFragmentedContent.getFile(), 0); + } + + final CaretModel model = side.getEditor().getCaretModel(); + final FragmentList fragments = ((DiffPanelImpl)panel).getFragments(); + final int line = model.getLogicalPosition().line; + //final int offset = side.getEditor().getDocument().getLineStartOffset(line); + final int offset = model.getOffset(); + + BeforeAfter current = null; + final List> ranges = myFragmentedContent.getLineRanges(); + for (BeforeAfter range : ranges) { + if (range.getBefore() > line) break; + current = range; + } + if (current == null) return null; + final Fragment at = fragments.getFragmentAt(offset, FragmentSide.SIDE1, Condition.TRUE); + if (at == null) return null; + final TextRange opposite = at.getRange(FragmentSide.SIDE2); + + final int lineInNew = ((DiffPanelImpl)panel).getEditor2().getDocument().getLineNumber(opposite.getStartOffset()); + + int correctLine; + int column; + if (at.getType() == null || TextDiffTypeEnum.NONE.equals(at.getType())) { + column = model.getLogicalPosition().column; + final int startIn1 = + ((DiffPanelImpl)panel).getEditor1().getDocument().getLineNumber(at.getRange(FragmentSide.SIDE1).getStartOffset()); + correctLine = lineInNew + line - startIn1; + } + else { + column = 0; + correctLine = Math.max(lineInNew, current.getAfter()); + } + + int converted = myFragmentedContent.getNewConvertor().execute(correctLine); + return new OpenFileDescriptor(myProject, myFragmentedContent.getFile(), converted, column); + } + @Override public void actionPerformed(AnActionEvent e) { - final boolean enabled = getEnabled(); - if (enabled) { - OpenFileDescriptor descriptor = null; - if (myFragmentedContent != null && myFragmentedContent.getFile() != null) { - final DiffPanel panel = myCurrentHorizontal ? myHorizontal : myVertical; + if (!getEnabled()) return; + OpenFileDescriptor descriptor = createDescriptor(); + if (descriptor == null) return; + final OpenFileDescriptor finalDescriptor = descriptor; + final Runnable runnable = new Runnable() { + @Override + public void run() { + FileEditorManager.getInstance(myProject).openTextEditor(finalDescriptor, true); + } + }; - final DiffSideView side = ((DiffPanelImpl)panel).getCurrentSide(); - if (side == null || side.getEditor() == null) return; - - final boolean isAfter = FragmentSide.SIDE2.equals(side.getSide()); - if (isAfter) { - final LogicalPosition position = side.getEditor().getCaretModel().getLogicalPosition(); - final int line = position.line; - final int converted = myFragmentedContent.getNewConvertor().execute(line); - descriptor = new OpenFileDescriptor(myProject, myFragmentedContent.getFile(), converted, position.column); - } else { - if (((DiffPanelImpl) panel).getEditor1().getDocument().getTextLength() == 0) { - FileEditorManager.getInstance(myProject).openTextEditor(new OpenFileDescriptor(myProject, myFragmentedContent.getFile(), 0), - true); - return; - } - - final CaretModel model = side.getEditor().getCaretModel(); - final FragmentList fragments = ((DiffPanelImpl)panel).getFragments(); - final int line = model.getLogicalPosition().line; - //final int offset = side.getEditor().getDocument().getLineStartOffset(line); - final int offset = model.getOffset(); - - BeforeAfter current = null; - final List> ranges = myFragmentedContent.getLineRanges(); - for (BeforeAfter range : ranges) { - if (range.getBefore() > line) break; - current = range; - } - if (current == null) return; - final Fragment at = fragments.getFragmentAt(offset, FragmentSide.SIDE1, Condition.TRUE); - if (at == null) return; - final TextRange opposite = at.getRange(FragmentSide.SIDE2); - - final int lineInNew = ((DiffPanelImpl)panel).getEditor2().getDocument().getLineNumber(opposite.getStartOffset()); - - int correctLine; - int column; - if (at.getType() == null || TextDiffTypeEnum.NONE.equals(at.getType())) { - column = model.getLogicalPosition().column; - final int startIn1 = - ((DiffPanelImpl)panel).getEditor1().getDocument().getLineNumber(at.getRange(FragmentSide.SIDE1).getStartOffset()); - correctLine = lineInNew + line - startIn1; - } - else { - column = 0; - correctLine = Math.max(lineInNew, current.getAfter()); - } - - int converted = myFragmentedContent.getNewConvertor().execute(correctLine); - descriptor = new OpenFileDescriptor(myProject, myFragmentedContent.getFile(), converted, column); + if (! ModalityState.NON_MODAL.equals(ModalityState.current())) { + final Window window = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow(); + if (window instanceof DialogWrapperDialog) { + final DialogWrapper wrapper = ((DialogWrapperDialog)window).getDialogWrapper(); + if (wrapper != null) { + Disposer.dispose(wrapper.getDisposable()); + wrapper.close(DialogWrapper.CANCEL_EXIT_CODE); + ApplicationManager.getApplication().invokeLater(runnable, ModalityState.NON_MODAL, myProject.getDisposed()); + return; } } - if (descriptor == null) return; - final OpenFileDescriptor finalDescriptor = descriptor; - final Runnable runnable = new Runnable() { - @Override - public void run() { - FileEditorManager.getInstance(myProject).openTextEditor(finalDescriptor, true); - } - }; - if (! ModalityState.NON_MODAL.equals(ModalityState.current())) { - final Window window = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow(); - if (window instanceof DialogWrapperDialog) { - final DialogWrapper wrapper = ((DialogWrapperDialog)window).getDialogWrapper(); - if (wrapper != null) { - Disposer.dispose(wrapper.getDisposable()); - wrapper.close(DialogWrapper.CANCEL_EXIT_CODE); - ApplicationManager.getApplication().invokeLater(runnable, ModalityState.NON_MODAL, myProject.getDisposed()); - return; - } - } - } - runnable.run(); } + runnable.run(); } @Override