From 78167d30065584fe7f0868fc94f6ad8d604a75f6 Mon Sep 17 00:00:00 2001 From: Sergey Simonchik Date: Fri, 21 Oct 2011 17:56:44 +0400 Subject: [PATCH] WI-7960 : OpenFileHyperlinkInfo now accepts documentLine and documentColumn (not a logical position) * OpenFileDescriptor: try to navigate to logical position if possible + variable renaming --- .../filters/OpenFileHyperlinkInfo.java | 45 +++++++++++--- .../fileEditor/OpenFileDescriptor.java | 60 +++++++++++-------- 2 files changed, 70 insertions(+), 35 deletions(-) diff --git a/platform/lang-api/src/com/intellij/execution/filters/OpenFileHyperlinkInfo.java b/platform/lang-api/src/com/intellij/execution/filters/OpenFileHyperlinkInfo.java index e517ba806445..66833ad1f2b8 100644 --- a/platform/lang-api/src/com/intellij/execution/filters/OpenFileHyperlinkInfo.java +++ b/platform/lang-api/src/com/intellij/execution/filters/OpenFileHyperlinkInfo.java @@ -16,45 +16,72 @@ package com.intellij.execution.filters; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileEditor.OpenFileDescriptor; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; public final class OpenFileHyperlinkInfo implements FileHyperlinkInfo { private final Project myProject; private final VirtualFile myFile; - private final int myLine; - private final int myColumn; + private final int myDocumentLine; + private final int myDocumentColumn; public OpenFileHyperlinkInfo(@NotNull OpenFileDescriptor descriptor) { this(descriptor.getProject(), descriptor.getFile(), descriptor.getLine(), descriptor.getColumn()); } - public OpenFileHyperlinkInfo(Project project, @NotNull final VirtualFile file, final int line, final int column) { + public OpenFileHyperlinkInfo(@NotNull Project project, @NotNull VirtualFile file, + int documentLine, int documentColumn) { myProject = project; myFile = file; - myLine = line; - myColumn = column; + myDocumentLine = documentLine; + myDocumentColumn = documentColumn; } - public OpenFileHyperlinkInfo(Project project, @NotNull final VirtualFile file, final int line) { - this (project, file, line, 0); + public OpenFileHyperlinkInfo(@NotNull Project project, @NotNull final VirtualFile file, final int line) { + this(project, file, line, 0); } public OpenFileDescriptor getDescriptor() { - return new OpenFileDescriptor(myProject, myFile, myLine, myColumn); + int offset = calculateOffset(myFile, myDocumentLine, myDocumentColumn); + if (offset != -1) { + return new OpenFileDescriptor(myProject, myFile, offset); + } + // although document position != logical position, it seems better than returning 'null' + return new OpenFileDescriptor(myProject, myFile, myDocumentLine, myDocumentColumn); } public void navigate(final Project project) { ApplicationManager.getApplication().runReadAction(new Runnable() { public void run() { final VirtualFile file = myFile; - if(file.isValid()) { + if (file.isValid()) { FileEditorManager.getInstance(project).openTextEditor(getDescriptor(), true); } } }); } + + private static int calculateOffset(@NotNull final VirtualFile file, + final int documentLine, final int documentColumn) { + return ApplicationManager.getApplication().runReadAction(new Computable() { + + @Override + public Integer compute() { + Document document = FileDocumentManager.getInstance().getDocument(file); + if (document != null) { + int lineStartOffset = document.getLineStartOffset(documentLine); + int lineEndOffset = document.getLineEndOffset(documentLine); + int fixedColumn = Math.min(Math.max(documentColumn, 0), lineEndOffset - lineStartOffset); + return lineStartOffset + fixedColumn; + } + return -1; + } + }); + } } diff --git a/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java b/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java index 17d4b06ebe81..41ecfa1ec625 100644 --- a/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java +++ b/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java @@ -44,41 +44,43 @@ public class OpenFileDescriptor implements Navigatable { @NotNull private final VirtualFile myFile; private final int myOffset; - private final int myLine; - private final int myColumn; + private final int myLogicalLine; + private final int myLogicalColumn; private final RangeMarker myRangeMarker; private final Project myProject; private boolean myUseCurrentWindow = false; - public OpenFileDescriptor(Project project, @NotNull VirtualFile file, int offset) { + public OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file, int offset) { this(project, file, -1, -1, offset, false); } - public OpenFileDescriptor(Project project, @NotNull VirtualFile file, int line, int col) { - this(project, file, line, col, -1, false); + public OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file, int logicalLine, int logicalColumn) { + this(project, file, logicalLine, logicalColumn, -1, false); } - public OpenFileDescriptor(Project project, @NotNull VirtualFile file, int line, int col, boolean persistent) { - this(project, file, line, col, -1, persistent); + public OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file, + int logicalLine, int logicalColumn, boolean persistent) { + this(project, file, logicalLine, logicalColumn, -1, persistent); } - public OpenFileDescriptor(Project project, @NotNull VirtualFile file) { + public OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file) { this(project, file, -1, -1, -1, false); } - private OpenFileDescriptor(final Project project, @NotNull final VirtualFile file, int line, int col, int offset, boolean persistent) { + private OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file, + int logicalLine, int logicalColumn, int offset, boolean persistent) { myProject = project; myFile = file; - myLine = line; - myColumn = col; + myLogicalLine = logicalLine; + myLogicalColumn = logicalColumn; myOffset = offset; if (offset >= 0) { myRangeMarker = LazyRangeMarkerFactory.getInstance(project).createRangeMarker(file, offset); } - else if (line >= 0 ){ - myRangeMarker = LazyRangeMarkerFactory.getInstance(project).createRangeMarker(file, line, Math.max(0, col), persistent); + else if (logicalLine >= 0 ){ + myRangeMarker = LazyRangeMarkerFactory.getInstance(project).createRangeMarker(file, logicalLine, Math.max(0, logicalColumn), persistent); } else { myRangeMarker = null; @@ -100,11 +102,11 @@ public class OpenFileDescriptor implements Navigatable { } public int getLine() { - return myLine; + return myLogicalLine; } public int getColumn() { - return myColumn; + return myLogicalColumn; } public void navigate(boolean requestFocus) { @@ -181,20 +183,26 @@ public class OpenFileDescriptor implements Navigatable { } public void navigateIn(@NotNull Editor e) { - if (getOffset() >= 0) { - e.getCaretModel().moveToOffset(Math.min(getOffset(), e.getDocument().getTextLength())); + final int offset = getOffset(); + CaretModel caretModel = e.getCaretModel(); + boolean caretMoved = false; + if (myLogicalLine != -1) { + LogicalPosition pos = new LogicalPosition(myLogicalLine, myLogicalColumn); + if (offset < 0 || offset == e.logicalPositionToOffset(pos)) { + caretModel.moveToLogicalPosition(pos); + caretMoved = true; + } } - else if (getLine() != -1) { - LogicalPosition pos = new LogicalPosition(getLine(), getColumn()); - e.getCaretModel().moveToLogicalPosition(pos); - } - else { - return; + if (!caretMoved && offset >= 0) { + caretModel.moveToOffset(Math.min(offset, e.getDocument().getTextLength())); + caretMoved = true; } - e.getSelectionModel().removeSelection(); - scrollToCaret(e); - unfoldCurrentLine(e); + if (caretMoved) { + e.getSelectionModel().removeSelection(); + scrollToCaret(e); + unfoldCurrentLine(e); + } } private static void unfoldCurrentLine(@NotNull final Editor editor) {