diff --git a/platform/lang-impl/resources/messages/AnalysisProblemBundle.properties b/platform/lang-impl/resources/messages/AnalysisProblemBundle.properties index b84214136972..f09ffa158fa4 100644 --- a/platform/lang-impl/resources/messages/AnalysisProblemBundle.properties +++ b/platform/lang-impl/resources/messages/AnalysisProblemBundle.properties @@ -4,4 +4,5 @@ filter.problems=Filter filter.problems.description=Filter problems shown in the Problems View tool window tab.caption.filter=filtering by {0} tab.caption.filter.severity=severity +problems.view.panel.preview.nothing=Select a problem file to preview problems.view.highlighting=Current File \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/analysis/problemsView/toolWindow/ProblemNode.kt b/platform/lang-impl/src/com/intellij/analysis/problemsView/toolWindow/ProblemNode.kt index 45965f7b1423..a8335c246195 100644 --- a/platform/lang-impl/src/com/intellij/analysis/problemsView/toolWindow/ProblemNode.kt +++ b/platform/lang-impl/src/com/intellij/analysis/problemsView/toolWindow/ProblemNode.kt @@ -2,7 +2,6 @@ package com.intellij.analysis.problemsView.toolWindow import com.intellij.ide.projectView.PresentationData -import com.intellij.openapi.fileEditor.OpenFileDescriptor import com.intellij.openapi.project.Project import com.intellij.ui.SimpleTextAttributes.GRAYED_ATTRIBUTES import com.intellij.ui.tree.LeafState @@ -12,9 +11,6 @@ internal class ProblemNode(parent: FileNode, val problem: Problem) : Node(parent val file = parent.file - val descriptor - get() = OpenFileDescriptor(project!!, file, problem.offset) - override fun getLeafState() = LeafState.ALWAYS override fun getName() = problem.description diff --git a/platform/lang-impl/src/com/intellij/analysis/problemsView/toolWindow/ProblemsViewPanel.java b/platform/lang-impl/src/com/intellij/analysis/problemsView/toolWindow/ProblemsViewPanel.java index 0e74c540eb01..025ef1b6c8ec 100644 --- a/platform/lang-impl/src/com/intellij/analysis/problemsView/toolWindow/ProblemsViewPanel.java +++ b/platform/lang-impl/src/com/intellij/analysis/problemsView/toolWindow/ProblemsViewPanel.java @@ -6,10 +6,11 @@ import com.intellij.openapi.actionSystem.ActionGroup; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.ActionToolbar; import com.intellij.openapi.actionSystem.ToggleOptionAction.Option; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileEditor.OpenFileDescriptor; import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.ToolWindow; import com.intellij.openapi.wm.ex.ToolWindowEx; import com.intellij.ui.OnePixelSplitter; @@ -18,7 +19,6 @@ import com.intellij.ui.content.Content; import com.intellij.ui.tree.AsyncTreeModel; import com.intellij.ui.tree.TreeVisitor; import com.intellij.ui.treeStructure.Tree; -import com.intellij.util.OpenSourceUtil; import com.intellij.util.ui.JBUI; import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.tree.TreeUtil; @@ -26,14 +26,16 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import javax.swing.tree.TreePath; import java.awt.*; import java.util.Comparator; import java.util.function.Predicate; +import static com.intellij.openapi.application.ApplicationManager.getApplication; +import static com.intellij.openapi.application.ModalityState.stateForComponent; import static com.intellij.ui.ColorUtil.toHtmlColor; import static com.intellij.ui.ScrollPaneFactory.createScrollPane; import static com.intellij.ui.scale.JBUIScale.scale; +import static com.intellij.util.OpenSourceUtil.navigate; import static com.intellij.util.ui.UIUtil.getInactiveTextColor; import static javax.swing.tree.TreeSelectionModel.SINGLE_TREE_SELECTION; @@ -56,7 +58,7 @@ abstract class ProblemsViewPanel extends OnePixelSplitter implements Disposable @Override public void setSelected(boolean selected) { myState.setAutoscrollToSource(selected); - updateAutoscroll(getDescriptor(getTree().getSelectionPath())); + updateAutoscroll(getSelectedDescriptor()); } }; private final Option myShowPreview = new Option() { @@ -68,7 +70,7 @@ abstract class ProblemsViewPanel extends OnePixelSplitter implements Disposable @Override public void setSelected(boolean selected) { myState.setShowPreview(selected); - updatePreview(getDescriptor(getTree().getSelectionPath())); + updatePreview(getSelectedDescriptor()); } }; private final Option myShowErrors = new Option() { @@ -154,7 +156,7 @@ abstract class ProblemsViewPanel extends OnePixelSplitter implements Disposable myTree.setShowsRootHandles(false); myTree.getSelectionModel().setSelectionMode(SINGLE_TREE_SELECTION); myTree.addTreeSelectionListener(event -> { - OpenFileDescriptor descriptor = getDescriptor(event.getPath()); + OpenFileDescriptor descriptor = getSelectedDescriptor(); updateAutoscroll(descriptor); updatePreview(descriptor); }); @@ -172,7 +174,7 @@ abstract class ProblemsViewPanel extends OnePixelSplitter implements Disposable @Override public void dispose() { - myPreview.preview(null); + myPreview.preview(null, false); } abstract @NotNull String getDisplayName(); @@ -189,7 +191,6 @@ abstract class ProblemsViewPanel extends OnePixelSplitter implements Disposable if (count > 0) { //noinspection HardCodedStringLiteral name = "" + name + " " + count + ""; - //name = name + " (" + count + ")"; } content.setDisplayName(name); } @@ -223,13 +224,13 @@ abstract class ProblemsViewPanel extends OnePixelSplitter implements Disposable myToolbarInsets.right = !vertical ? scale(1) : 0; myToolbarInsets.bottom = vertical ? scale(1) : 0; myPanel.add(vertical ? BorderLayout.NORTH : BorderLayout.WEST, myToolbar.getComponent()); - updatePreview(getDescriptor(getTree().getSelectionPath())); + updatePreview(getSelectedDescriptor()); } void selectionChangedTo(boolean selected) { myTreeModel.setComparator(createComparator()); myTreeModel.setFilter(createFilter()); - updatePreview(getDescriptor(getTree().getSelectionPath())); + updatePreview(getSelectedDescriptor()); ToolWindow window = ProblemsView.getToolWindow(getProject()); if (window instanceof ToolWindowEx) { @@ -238,24 +239,47 @@ abstract class ProblemsViewPanel extends OnePixelSplitter implements Disposable } } - private static @Nullable OpenFileDescriptor getDescriptor(@Nullable TreePath path) { - ProblemNode node = TreeUtil.getLastUserObject(ProblemNode.class, path); - return node == null ? null : node.getDescriptor(); + private @Nullable OpenFileDescriptor getSelectedDescriptor() { + Object object = TreeUtil.getLastUserObject(getTree().getSelectionPath()); + if (object instanceof ProblemNode) { + ProblemNode node = (ProblemNode)object; + return getDescriptor(node.getFile(), node.getProblem().getOffset()); + } + if (object instanceof FileNode) { + FileNode node = (FileNode)object; + return getDescriptor(node.getFile(), 0); + } + return null; + } + + private @Nullable OpenFileDescriptor getDescriptor(@NotNull VirtualFile file, int offset) { + Document document = ProblemsView.getDocument(getProject(), file); + return document == null ? null : new OpenFileDescriptor(getProject(), file, offset); } private void updateAutoscroll(@Nullable OpenFileDescriptor descriptor) { if (descriptor != null && isNotNullAndSelected(getAutoscrollToSource())) { - ApplicationManager.getApplication().invokeLater( - () -> OpenSourceUtil.navigate(false, descriptor), - ModalityState.stateForComponent(getTree()) - ); + invokeLater(() -> navigate(false, descriptor)); } } private void updatePreview(@Nullable OpenFileDescriptor descriptor) { - myPreview.preview(isNotNullAndSelected(getShowPreview()) ? descriptor : null); + Document document = descriptor == null ? null : ProblemsView.getDocument(getProject(), descriptor.getFile()); + Editor editor = myPreview.preview(document, isNotNullAndSelected(getShowPreview())); + if (editor != null && descriptor != null) { + invokeLater(() -> { + if (editor.getComponent().isShowing()) { + descriptor.navigateIn(editor); + } + }); + } } + private void invokeLater(@NotNull Runnable runnable) { + getApplication().invokeLater(runnable, stateForComponent(this)); + } + + void select(@NotNull Node node) { TreeUtil.promiseSelect(getTree(), createVisitor(node)); } diff --git a/platform/lang-impl/src/com/intellij/analysis/problemsView/toolWindow/ProblemsViewPreview.java b/platform/lang-impl/src/com/intellij/analysis/problemsView/toolWindow/ProblemsViewPreview.java deleted file mode 100644 index 270edebba91d..000000000000 --- a/platform/lang-impl/src/com/intellij/analysis/problemsView/toolWindow/ProblemsViewPreview.java +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -package com.intellij.analysis.problemsView.toolWindow; - -import com.intellij.openapi.editor.*; -import com.intellij.openapi.fileEditor.OpenFileDescriptor; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -final class ProblemsViewPreview { - private final ProblemsViewPanel panel; - private Editor editor; - - ProblemsViewPreview(@NotNull ProblemsViewPanel panel) { - this.panel = panel; - } - - void preview(@Nullable OpenFileDescriptor descriptor) { - Document document = descriptor == null ? null : ProblemsView.getDocument(panel.getProject(), descriptor.getFile()); - if (editor != null && document != editor.getDocument()) { - panel.setSecondComponent(null); - EditorFactory.getInstance().releaseEditor(editor); - this.editor = null; - } - if (editor == null && document != null) { - editor = EditorFactory.getInstance().createViewer(document, panel.getProject(), EditorKind.PREVIEW); - - EditorSettings settings = editor.getSettings(); - settings.setAnimatedScrolling(false); - settings.setRefrainFromScrolling(false); - settings.setLineNumbersShown(true); - settings.setFoldingOutlineShown(false); - - editor.setBorder(null); - panel.setSecondComponent(editor.getComponent()); - } - if (editor != null) { - descriptor.navigateIn(editor); - } - } -} diff --git a/platform/lang-impl/src/com/intellij/analysis/problemsView/toolWindow/ProblemsViewPreview.kt b/platform/lang-impl/src/com/intellij/analysis/problemsView/toolWindow/ProblemsViewPreview.kt new file mode 100644 index 000000000000..e74c9bd77f0f --- /dev/null +++ b/platform/lang-impl/src/com/intellij/analysis/problemsView/toolWindow/ProblemsViewPreview.kt @@ -0,0 +1,43 @@ +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.analysis.problemsView.toolWindow + +import com.intellij.analysis.problemsView.AnalysisProblemBundle.message +import com.intellij.openapi.editor.Document +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.editor.EditorFactory.getInstance +import com.intellij.openapi.editor.EditorKind +import javax.swing.BorderFactory.createEmptyBorder +import javax.swing.JComponent +import javax.swing.JLabel + +internal class ProblemsViewPreview(private val panel: ProblemsViewPanel) + : JLabel(message("problems.view.panel.preview.nothing"), CENTER) { + + private var preview: Editor? = null + set(value) { + field?.let { getInstance().releaseEditor(it) } + field = value + } + + private fun update(editor: Editor?, component: JComponent?): Editor? { + panel.secondComponent = component + preview = editor + return editor + } + + fun preview(document: Document?, show: Boolean): Editor? { + if (!show) return update(null, null) // hide preview + if (document == null) return update(null, this) // show label preview + if (preview?.document === document) return preview // nothing is changed + + val editor = getInstance().createEditor(document, panel.project, EditorKind.PREVIEW) + with(editor.settings) { + isAnimatedScrolling = false + isRefrainFromScrolling = false + isLineNumbersShown = true + isFoldingOutlineShown = false + } + editor.setBorder(createEmptyBorder()) + return update(editor, editor.component) // show editor preview + } +}