package jetbrains.mps.debugger.api.ui.executionPoint; /*Generated by MPS */ import com.intellij.openapi.components.ProjectComponent; import jetbrains.mps.debug.api.SessionChangeListener; import jetbrains.mps.debug.api.DebugSessionManagerComponent; import com.intellij.openapi.project.Project; import com.intellij.openapi.editor.markup.RangeHighlighter; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.util.messages.MessageBusConnection; import com.intellij.openapi.fileEditor.FileEditorManagerListener; import com.intellij.openapi.fileEditor.FileEditorManagerAdapter; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import jetbrains.mps.debug.api.AbstractDebugSession; import jetbrains.mps.baseLanguage.closures.runtime._FunctionTypes; import com.intellij.openapi.application.ApplicationManager; import jetbrains.mps.debug.api.source.TextSourcePosition; import jetbrains.mps.ide.common.FileOpenUtil; import org.jetbrains.annotations.Nullable; import jetbrains.mps.debug.api.programState.IStackFrame; import jetbrains.mps.debug.api.source.SourcePosition; import jetbrains.mps.debug.api.source.PositionProvider; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.editor.markup.TextAttributes; import java.awt.Color; import com.intellij.openapi.editor.ex.MarkupModelEx; import com.intellij.openapi.editor.impl.DocumentMarkupModel; import com.intellij.openapi.editor.markup.HighlighterLayer; import jetbrains.mps.debug.api.SessionChangeAdapter; public class InTextPositionComponent implements ProjectComponent { private final SessionChangeListener myChangeListener = new InTextPositionComponent.MySessionChangeListener(); private final DebugSessionManagerComponent.DebugSessionListener myCurrentDebugSessionListener = new InTextPositionComponent.MyCurrentDebugSessionListener(); private final Project myProject; private volatile RangeHighlighter myHighlighter; private final FileEditorManager myEditorManager; private MessageBusConnection myConnection; public InTextPositionComponent(Project project, FileEditorManager fileEditorManager) { myProject = project; myEditorManager = fileEditorManager; } @Override public void projectOpened() { } @Override public void projectClosed() { } @Override public void initComponent() { DebugSessionManagerComponent component = myProject.getComponent(DebugSessionManagerComponent.class); component.addDebugSessionListener(myCurrentDebugSessionListener); myConnection = myProject.getMessageBus().connect(); myConnection.subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, new FileEditorManagerAdapter() { @Override public void fileOpened(FileEditorManager manager, VirtualFile file) { reAttachPainter(getCurrentSession(), false); } @Override public void fileClosed(FileEditorManager manager, VirtualFile file) { reAttachPainter(getCurrentSession(), false); } }); } @Override public void disposeComponent() { myConnection.disconnect(); DebugSessionManagerComponent component = myProject.getComponent(DebugSessionManagerComponent.class); component.removeDebugSessionListener(myCurrentDebugSessionListener); } @NonNls @NotNull @Override public String getComponentName() { return "Text Position Component"; } protected AbstractDebugSession getCurrentSession() { return myProject.getComponent(DebugSessionManagerComponent.class).getDebugSessionByCurrentTab(); } public void currentSessionChanged(AbstractDebugSession session) { reAttachPainter(session); } public void reAttachPainter(AbstractDebugSession session) { final _FunctionTypes._void_P0_E0 detach = detachPainterRunnable(); final _FunctionTypes._void_P0_E0 attach = attachPainterRunnable(session); if (detach != null || attach != null) { ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { check_uzwzqp_a0a0a0a0a0a2a41(detach); check_uzwzqp_a1a0a0a0a0a2a41(attach); } }); } } public void reAttachPainter(AbstractDebugSession session, boolean open) { final _FunctionTypes._void_P0_E0 detach = detachPainterRunnable(); final _FunctionTypes._void_P0_E0 attach = attachPainterRunnable(session, open); if (detach != null || attach != null) { ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { check_uzwzqp_a0a0a0a0a0a2a51(detach); check_uzwzqp_a1a0a0a0a0a2a51(attach); } }); } } private _FunctionTypes._void_P0_E0 attachPainterRunnable(AbstractDebugSession session, final boolean open) { if (session == null) { return null; } final TextSourcePosition location = getLocation(session); if (location == null) { return null; } return new _FunctionTypes._void_P0_E0() { public void invoke() { myHighlighter = createHighlighter(location); if (open) { FileOpenUtil.openFile(myProject, location.getFile(), location.getLineNumber()); } } }; } private _FunctionTypes._void_P0_E0 attachPainterRunnable(AbstractDebugSession session) { AbstractDebugSession currentSession = getCurrentSession(); return attachPainterRunnable(session, currentSession != null && session == currentSession); } public void detachPainter() { final _FunctionTypes._void_P0_E0 runnable = detachPainterRunnable(); if (runnable == null) { return; } ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { runnable.invoke(); } }); } public _FunctionTypes._void_P0_E0 detachPainterRunnable() { if (myHighlighter != null) { return new _FunctionTypes._void_P0_E0() { public void invoke() { if (myHighlighter == null) { return; } RangeHighlighter highlighter = myHighlighter; myHighlighter = null; highlighter.dispose(); } }; } return null; } @Nullable public TextSourcePosition getLocation(AbstractDebugSession session) { IStackFrame stackFrame = session.getUiState().getStackFrame(); if (stackFrame != null) { SourcePosition position = PositionProvider.getInstance(myProject).getPosition(stackFrame.getLocation(), session); if (position instanceof TextSourcePosition) { return ((TextSourcePosition) position); } } return null; } @Nullable public RangeHighlighter createHighlighter(TextSourcePosition location) { Document document = FileDocumentManager.getInstance().getDocument(location.getFile()); if (document == null) { return null; } if (location.getLineNumber() < 0 || location.getLineNumber() >= document.getLineCount()) { return null; } TextAttributes attributes = new TextAttributes(); attributes.setForegroundColor(Color.WHITE); attributes.setBackgroundColor(Color.BLUE); RangeHighlighter highlighter = ((MarkupModelEx) DocumentMarkupModel.forDocument(document, myProject, true)).addPersistentLineHighlighter(location.getLineNumber() - 1, HighlighterLayer.SELECTION - 1, attributes); if (highlighter == null || !(highlighter.isValid())) { return null; } return highlighter; } private class MyCurrentDebugSessionListener implements DebugSessionManagerComponent.DebugSessionListener { private MyCurrentDebugSessionListener() { } @Override public void registered(AbstractDebugSession session) { session.addChangeListener(myChangeListener); } @Override public void currentSessionChanged(AbstractDebugSession session) { InTextPositionComponent.this.currentSessionChanged(session); } @Override public void detached(AbstractDebugSession session) { detachPainter(); session.removeChangeListener(myChangeListener); } } private class MySessionChangeListener extends SessionChangeAdapter { private MySessionChangeListener() { } @Override public void stateChanged(AbstractDebugSession session) { reAttachPainter(session); } @Override public void paused(AbstractDebugSession session) { reAttachPainter(session); } @Override public void resumed(AbstractDebugSession session) { detachPainter(); } } private static void check_uzwzqp_a0a0a0a0a0a2a41(_FunctionTypes._void_P0_E0 checkedDotOperand) { if (null != checkedDotOperand) { checkedDotOperand.invoke(); } } private static void check_uzwzqp_a1a0a0a0a0a2a41(_FunctionTypes._void_P0_E0 checkedDotOperand) { if (null != checkedDotOperand) { checkedDotOperand.invoke(); } } private static void check_uzwzqp_a0a0a0a0a0a2a51(_FunctionTypes._void_P0_E0 checkedDotOperand) { if (null != checkedDotOperand) { checkedDotOperand.invoke(); } } private static void check_uzwzqp_a1a0a0a0a0a2a51(_FunctionTypes._void_P0_E0 checkedDotOperand) { if (null != checkedDotOperand) { checkedDotOperand.invoke(); } } }