diff --git a/python/educational/interactive-learning/resources/META-INF/plugin.xml b/python/educational/interactive-learning/resources/META-INF/plugin.xml index 8374db06e8ed..75c0bc02e942 100644 --- a/python/educational/interactive-learning/resources/META-INF/plugin.xml +++ b/python/educational/interactive-learning/resources/META-INF/plugin.xml @@ -70,5 +70,6 @@ + \ No newline at end of file diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyDocumentListener.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyDocumentListener.java index a7a2e0debeaa..0f57cf9d139f 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyDocumentListener.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyDocumentListener.java @@ -31,6 +31,7 @@ public class StudyDocumentListener extends DocumentAdapter { if (!myTaskFile.isTrackChanges()) { return; } + myTaskFile.setHighlightErrors(true); Document document = e.getDocument(); myTaskWindows.clear(); for (TaskWindow taskWindow : myTaskFile.getTaskWindows()) { diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyEditorFactoryListener.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyEditorFactoryListener.java index 78da60815e4a..f7e6bface1f3 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyEditorFactoryListener.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyEditorFactoryListener.java @@ -12,6 +12,7 @@ import com.intellij.openapi.editor.event.EditorMouseEvent; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.problems.WolfTheProblemSolver; import com.jetbrains.edu.learning.course.TaskFile; import com.jetbrains.edu.learning.course.TaskWindow; import com.jetbrains.edu.learning.editor.StudyEditor; @@ -74,6 +75,7 @@ class StudyEditorFactoryListener implements EditorFactoryListener { StudyDocumentListener listener = new StudyDocumentListener(taskFile); StudyEditor.addDocumentListener(document, listener); document.addDocumentListener(listener); + WolfTheProblemSolver.getInstance(project).clearProblems(openedFile); taskFile.drawAllWindows(editor); } } diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyHighlightErrorFilter.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyHighlightErrorFilter.java new file mode 100644 index 000000000000..f1fdbf4bae41 --- /dev/null +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyHighlightErrorFilter.java @@ -0,0 +1,24 @@ +package com.jetbrains.edu.learning; + +import com.intellij.codeInsight.highlighting.HighlightErrorFilter; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiErrorElement; +import com.intellij.psi.PsiFile; +import com.jetbrains.edu.learning.course.TaskFile; +import org.jetbrains.annotations.NotNull; + +public class StudyHighlightErrorFilter extends HighlightErrorFilter{ + @Override + public boolean shouldHighlightErrorElement(@NotNull PsiErrorElement element) { + PsiFile file = element.getContainingFile(); + if (file == null) { + return true; + } + VirtualFile virtualFile = file.getVirtualFile(); + if (virtualFile == null) { + return true; + } + TaskFile taskFile = StudyTaskManager.getInstance(element.getProject()).getTaskFile(virtualFile); + return taskFile == null || taskFile.isHighlightErrors(); + } +} diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyRefreshTaskFileAction.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyRefreshTaskFileAction.java index c2ef5ab211a5..e58e80eb5525 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyRefreshTaskFileAction.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyRefreshTaskFileAction.java @@ -19,6 +19,7 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.IdeFocusManager; +import com.intellij.problems.WolfTheProblemSolver; import com.jetbrains.edu.learning.StudyState; import com.jetbrains.edu.learning.StudyUtils; import com.jetbrains.edu.learning.course.*; @@ -59,6 +60,8 @@ public class StudyRefreshTaskFileAction extends DumbAwareAction { if (!resetTaskFile(editor.getDocument(), project, taskFile, studyState.getVirtualFile().getName())) { return; } + WolfTheProblemSolver.getInstance(project).clearProblems(studyState.getVirtualFile()); + taskFile.setHighlightErrors(false); taskFile.drawAllWindows(editor); taskFile.createGuardedBlocks(editor); ApplicationManager.getApplication().invokeLater(new Runnable() { diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/course/TaskFile.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/course/TaskFile.java index 5e835e076ac5..ffc2d8c6feae 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/course/TaskFile.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/course/TaskFile.java @@ -37,6 +37,7 @@ public class TaskFile implements Stateful { public int myIndex = -1; private boolean myUserCreated = false; private boolean myTrackChanges = true; + private boolean myHighlightErrors = false; /** * @return if all the windows in task file are marked as resolved @@ -262,4 +263,12 @@ public class TaskFile implements Stateful { public void setTrackChanges(boolean trackChanges) { myTrackChanges = trackChanges; } + + public boolean isHighlightErrors() { + return myHighlightErrors; + } + + public void setHighlightErrors(boolean highlightErrors) { + myHighlightErrors = highlightErrors; + } } diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/course/TaskWindow.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/course/TaskWindow.java index 2cd4c4ce7759..83598afe865a 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/course/TaskWindow.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/course/TaskWindow.java @@ -7,12 +7,9 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.editor.colors.EditorColors; import com.intellij.openapi.editor.colors.EditorColorsManager; -import com.intellij.openapi.editor.markup.HighlighterLayer; -import com.intellij.openapi.editor.markup.HighlighterTargetArea; -import com.intellij.openapi.editor.markup.RangeHighlighter; -import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.markup.*; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; @@ -23,6 +20,7 @@ import com.jetbrains.edu.learning.StudyTestRunner; import com.jetbrains.edu.learning.StudyUtils; import org.jetbrains.annotations.NotNull; +import java.awt.*; import java.io.File; import java.io.IOException; @@ -91,17 +89,24 @@ public class TaskWindow implements Comparable, Stateful { if (!isValid(document)) { return; } - TextAttributes defaultTestAttributes = - EditorColorsManager.getInstance().getGlobalScheme().getAttributes(EditorColors.LIVE_TEMPLATE_ATTRIBUTES); - JBColor color = getColor(); + EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme(); + final TextAttributes defaultTestAttributes = new TextAttributes(scheme.getDefaultForeground(), scheme.getDefaultBackground(), null, + EffectType.BOXED, Font.PLAIN); + final JBColor color = getColor(); int startOffset = document.getLineStartOffset(line) + start; RangeHighlighter rh = editor.getMarkupModel().addRangeHighlighter(startOffset, startOffset + length, HighlighterLayer.LAST + 1, - new TextAttributes(defaultTestAttributes.getForegroundColor(), - defaultTestAttributes.getBackgroundColor(), color, - defaultTestAttributes.getEffectType(), - defaultTestAttributes.getFontType()), + defaultTestAttributes, HighlighterTargetArea.EXACT_RANGE); + rh.setCustomRenderer(new CustomHighlighterRenderer() { + @Override + public void paint(@NotNull Editor editor, @NotNull RangeHighlighter highlighter, @NotNull Graphics g) { + g.setColor(color); + Point point = editor.logicalPositionToXY(editor.offsetToLogicalPosition(highlighter.getStartOffset())); + Point pointEnd = editor.logicalPositionToXY(editor.offsetToLogicalPosition(highlighter.getEndOffset())); + g.drawRect(point.x, point.y - 2, (pointEnd.x - point.x), editor.getLineHeight() + 1); + } + }); if (drawSelection) { editor.getSelectionModel().setSelection(startOffset, startOffset + length); }