From b16605e97c975cefb6dc6612050da79d3808b08d Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Fri, 13 Feb 2015 23:34:35 +0300 Subject: [PATCH] moved studystate to interactive-learning --- .../StudyAnswerPlaceholderPainter.java | 5 +- .../edu/learning/StudyTaskManager.java | 97 ++++++++++++++++++- .../learning/actions/StudyCheckAction.java | 25 +++-- .../actions/StudyRefreshTaskFileAction.java | 8 +- .../learning}/courseFormat/StudyStatus.java | 4 +- .../learning/navigation/StudyNavigator.java | 15 ++- .../projectView/StudyDirectoryNode.java | 33 +++++-- .../edu/learning/run/StudySmartChecker.java | 5 +- .../learning/ui/StudyToolWindowFactory.java | 16 +-- .../edu/courseFormat/AnswerPlaceholder.java | 50 +++++----- .../jetbrains/edu/courseFormat/Lesson.java | 20 +--- .../edu/courseFormat/StudyStateful.java | 6 -- .../com/jetbrains/edu/courseFormat/Task.java | 22 +---- .../jetbrains/edu/courseFormat/TaskFile.java | 29 +----- 14 files changed, 198 insertions(+), 137 deletions(-) rename python/educational/{src/com/jetbrains/edu => interactive-learning/src/com/jetbrains/edu/learning}/courseFormat/StudyStatus.java (50%) delete mode 100644 python/educational/src/com/jetbrains/edu/courseFormat/StudyStateful.java diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyAnswerPlaceholderPainter.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyAnswerPlaceholderPainter.java index 2e8190069dc9..5cfa40458c20 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyAnswerPlaceholderPainter.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyAnswerPlaceholderPainter.java @@ -9,6 +9,7 @@ import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.colors.EditorColorsScheme; import com.intellij.openapi.editor.impl.DocumentImpl; import com.intellij.openapi.editor.markup.*; +import com.intellij.openapi.project.Project; import com.intellij.ui.JBColor; import com.jetbrains.edu.courseFormat.AnswerPlaceholder; import com.jetbrains.edu.courseFormat.TaskFile; @@ -33,7 +34,9 @@ public class StudyAnswerPlaceholderPainter { EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme(); final TextAttributes defaultTestAttributes = new TextAttributes(scheme.getDefaultForeground(), scheme.getDefaultBackground(), null, EffectType.BOXED, Font.PLAIN); - final JBColor color = answerPlaceholder.getColor(); + final Project project = editor.getProject(); + assert project != null; + final JBColor color = StudyTaskManager.getInstance(project).getColor(answerPlaceholder); int startOffset = answerPlaceholder.getRealStartOffset(document); RangeHighlighter highlighter = editor.getMarkupModel().addRangeHighlighter(startOffset, startOffset + answerPlaceholder.getLength(), HighlighterLayer.LAST + 1, diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyTaskManager.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyTaskManager.java index 0a1dbed80f2f..b19fd20493f1 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyTaskManager.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyTaskManager.java @@ -9,12 +9,17 @@ import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.module.ModuleServiceManager; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; +import com.intellij.ui.JBColor; +import com.intellij.util.containers.hash.HashMap; import com.intellij.util.xmlb.XmlSerializerUtil; -import com.jetbrains.edu.courseFormat.Course; +import com.jetbrains.edu.courseFormat.*; +import com.jetbrains.edu.learning.courseFormat.StudyStatus; import com.jetbrains.edu.learning.courseGeneration.StudyGenerator; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Map; + /** * Implementation of class which contains all the information * about study in context of current project @@ -30,20 +35,102 @@ import org.jetbrains.annotations.Nullable; )} ) public class StudyTaskManager implements PersistentStateComponent, DumbAware { - public Course myCourse; + private Course myCourse; + public Map myStudyStatusMap = new HashMap(); + + private StudyTaskManager() { + } public void setCourse(@NotNull final Course course) { myCourse = course; } - private StudyTaskManager() { - } - @Nullable public Course getCourse() { return myCourse; } + public void setStatus(AnswerPlaceholder placeholder, StudyStatus status) { + if (myStudyStatusMap == null) { + myStudyStatusMap = new HashMap(); + } + myStudyStatusMap.put(placeholder, status); + } + + public void setStatus(Task task, StudyStatus status) { + for (TaskFile taskFile : task.getTaskFiles().values()) { + setStatus(taskFile, status); + } + } + + public void setStatus(TaskFile file, StudyStatus status) { + for (AnswerPlaceholder answerPlaceholder : file.getAnswerPlaceholders()) { + setStatus(answerPlaceholder, status); + } + } + + public StudyStatus getStatus(AnswerPlaceholder placeholder) { + StudyStatus status = myStudyStatusMap.get(placeholder); + if (status == null) { + status = StudyStatus.Unchecked; + myStudyStatusMap.put(placeholder, status); + } + return status; + } + + + public StudyStatus getStatus(@NotNull final Lesson lesson) { + for (Task task : lesson.getTaskList()) { + StudyStatus taskStatus = getStatus(task); + if (taskStatus == StudyStatus.Unchecked || taskStatus == StudyStatus.Failed) { + return StudyStatus.Unchecked; + } + } + return StudyStatus.Solved; + } + + public StudyStatus getStatus(@NotNull final Task task) { + for (TaskFile taskFile : task.getTaskFiles().values()) { + StudyStatus taskFileStatus = getStatus(taskFile); + if (taskFileStatus == StudyStatus.Unchecked) { + return StudyStatus.Unchecked; + } + if (taskFileStatus == StudyStatus.Failed) { + return StudyStatus.Failed; + } + } + return StudyStatus.Solved; + } + + private StudyStatus getStatus(@NotNull final TaskFile file) { + for (AnswerPlaceholder answerPlaceholder : file.getAnswerPlaceholders()) { + StudyStatus windowStatus = getStatus(answerPlaceholder); + if (windowStatus == StudyStatus.Failed) { + return StudyStatus.Failed; + } + if (windowStatus == StudyStatus.Unchecked) { + return StudyStatus.Unchecked; + } + } + return StudyStatus.Solved; + } + + + public JBColor getColor(@NotNull final AnswerPlaceholder placeholder) { + final StudyStatus status = getStatus(placeholder); + if (status == StudyStatus.Solved) { + return JBColor.GREEN; + } + if (status == StudyStatus.Failed) { + return JBColor.RED; + } + return JBColor.BLUE; + } + + public boolean hasFailedTaskWindows(@NotNull final TaskFile taskFile) { + return taskFile.getAnswerPlaceholders().size() > 0 && getStatus(taskFile) == StudyStatus.Failed; + } + @Nullable @Override public StudyTaskManager getState() { diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyCheckAction.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyCheckAction.java index 34431c0cbfa0..0c96b37f6583 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyCheckAction.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyCheckAction.java @@ -31,13 +31,10 @@ import com.intellij.openapi.wm.WindowManager; import com.intellij.openapi.wm.ex.StatusBarEx; import com.intellij.openapi.wm.ex.WindowManagerEx; import com.jetbrains.edu.courseFormat.AnswerPlaceholder; -import com.jetbrains.edu.courseFormat.StudyStatus; import com.jetbrains.edu.courseFormat.Task; import com.jetbrains.edu.courseFormat.TaskFile; -import com.jetbrains.edu.learning.StudyAnswerPlaceholderPainter; -import com.jetbrains.edu.learning.StudyDocumentListener; -import com.jetbrains.edu.learning.StudyState; -import com.jetbrains.edu.learning.StudyUtils; +import com.jetbrains.edu.learning.*; +import com.jetbrains.edu.learning.courseFormat.StudyStatus; import com.jetbrains.edu.learning.editor.StudyEditor; import com.jetbrains.edu.learning.navigation.StudyNavigator; import com.jetbrains.edu.learning.run.StudySmartChecker; @@ -191,7 +188,9 @@ public class StudyCheckAction extends DumbAwareAction { final StudyEditor selectedEditor) { final Task task = studyState.getTask(); final VirtualFile taskDir = studyState.getTaskDir(); - final StudyStatus statusBeforeCheck = task.getStatus(); + + final StudyTaskManager taskManager = StudyTaskManager.getInstance(project); + final StudyStatus statusBeforeCheck = taskManager.getStatus(task); return new com.intellij.openapi.progress.Task.Backgroundable(project, "Checking task", true) { @Override public void onSuccess() { @@ -204,8 +203,7 @@ public class StudyCheckAction extends DumbAwareAction { @Override public void onCancel() { - StudyStatus currentStatus = task.getStatus(); - task.setStatus(statusBeforeCheck); + taskManager.setStatus(task, statusBeforeCheck); deleteWindowDescriptions(task, taskDir); selectedEditor.getCheckButton().setEnabled(true); } @@ -226,7 +224,7 @@ public class StudyCheckAction extends DumbAwareAction { } final String failedMessage = testRunner.getTestsOutput(output); if (StudyTestRunner.TEST_OK.equals(failedMessage)) { - task.setStatus(StudyStatus.Solved); + taskManager.setStatus(task, StudyStatus.Solved); ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { @@ -239,12 +237,12 @@ public class StudyCheckAction extends DumbAwareAction { @Override public void run() { if (taskDir == null) return; - task.setStatus(StudyStatus.Failed); + taskManager.setStatus(task, StudyStatus.Failed); for (Map.Entry entry : taskFiles.entrySet()) { final String name = entry.getKey(); final TaskFile taskFile = entry.getValue(); if (taskFile.getAnswerPlaceholders().size() < 2) { - taskFile.setStatus(StudyStatus.Failed); + taskManager.setStatus(taskFile, StudyStatus.Failed); continue; } CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() { @@ -276,11 +274,12 @@ public class StudyCheckAction extends DumbAwareAction { Editor editor = studyState.getEditor(); TaskFile taskFileToNavigate = selectedTaskFile; VirtualFile fileToNavigate = studyState.getVirtualFile(); - if (!selectedTaskFile.hasFailedTaskWindows()) { + final StudyTaskManager taskManager = StudyTaskManager.getInstance(project); + if (!taskManager.hasFailedTaskWindows(selectedTaskFile)) { for (Map.Entry entry : task.getTaskFiles().entrySet()) { String name = entry.getKey(); TaskFile taskFile = entry.getValue(); - if (taskFile.hasFailedTaskWindows()) { + if (taskManager.hasFailedTaskWindows(taskFile)) { taskFileToNavigate = taskFile; VirtualFile virtualFile = taskDir.findChild(name); if (virtualFile == null) { 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 1d142558575d..fdcd8bc666ad 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 @@ -27,7 +27,9 @@ import com.jetbrains.edu.courseFormat.Task; import com.jetbrains.edu.courseFormat.TaskFile; import com.jetbrains.edu.learning.StudyAnswerPlaceholderPainter; import com.jetbrains.edu.learning.StudyState; +import com.jetbrains.edu.learning.StudyTaskManager; import com.jetbrains.edu.learning.StudyUtils; +import com.jetbrains.edu.learning.courseFormat.StudyStatus; import com.jetbrains.edu.learning.editor.StudyEditor; import com.jetbrains.edu.learning.navigation.StudyNavigator; import org.jetbrains.annotations.NotNull; @@ -88,7 +90,7 @@ public class StudyRefreshTaskFileAction extends DumbAwareAction { if (!resetDocument(project, document, taskFile, name)) { return false; } - resetTaskWindows(taskFile); + resetTaskWindows(taskFile, project); ProjectView.getInstance(project).refresh(); StudyUtils.updateStudyToolWindow(project); return true; @@ -104,9 +106,11 @@ public class StudyRefreshTaskFileAction extends DumbAwareAction { Disposer.register(project, balloon); } - private static void resetTaskWindows(TaskFile selectedTaskFile) { + private static void resetTaskWindows(TaskFile selectedTaskFile, Project project) { + final StudyTaskManager taskManager = StudyTaskManager.getInstance(project); for (AnswerPlaceholder answerPlaceholder : selectedTaskFile.getAnswerPlaceholders()) { answerPlaceholder.reset(); + taskManager.setStatus(answerPlaceholder, StudyStatus.Unchecked); } } diff --git a/python/educational/src/com/jetbrains/edu/courseFormat/StudyStatus.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/courseFormat/StudyStatus.java similarity index 50% rename from python/educational/src/com/jetbrains/edu/courseFormat/StudyStatus.java rename to python/educational/interactive-learning/src/com/jetbrains/edu/learning/courseFormat/StudyStatus.java index 917d299330d7..a383b51181c7 100644 --- a/python/educational/src/com/jetbrains/edu/courseFormat/StudyStatus.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/courseFormat/StudyStatus.java @@ -1,4 +1,6 @@ -package com.jetbrains.edu.courseFormat; +package com.jetbrains.edu.learning.courseFormat; + +import com.jetbrains.edu.courseFormat.AnswerPlaceholder; /** * @see {@link AnswerPlaceholder#myStatus} diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/navigation/StudyNavigator.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/navigation/StudyNavigator.java index cbe08bff52f9..5f32c39445cd 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/navigation/StudyNavigator.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/navigation/StudyNavigator.java @@ -2,8 +2,14 @@ package com.jetbrains.edu.learning.navigation; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.LogicalPosition; -import com.jetbrains.edu.courseFormat.*; +import com.intellij.openapi.project.Project; +import com.jetbrains.edu.courseFormat.AnswerPlaceholder; +import com.jetbrains.edu.courseFormat.Lesson; +import com.jetbrains.edu.courseFormat.Task; +import com.jetbrains.edu.courseFormat.TaskFile; +import com.jetbrains.edu.learning.StudyTaskManager; import com.jetbrains.edu.learning.StudyUtils; +import com.jetbrains.edu.learning.courseFormat.StudyStatus; import org.jetbrains.annotations.NotNull; import java.util.List; @@ -54,9 +60,12 @@ public class StudyNavigator { return lesson.getCourse().getLessons().get(lesson.getIndex() - 1); } - public static void navigateToFirstFailedTaskWindow(@NotNull final Editor editor, @NotNull final TaskFile taskFile) { + public static void navigateToFirstFailedTaskWindow(@NotNull final Editor editor, @NotNull final TaskFile taskFile) { + final Project project = editor.getProject(); + if (project == null) return; for (AnswerPlaceholder answerPlaceholder : taskFile.getAnswerPlaceholders()) { - if (answerPlaceholder.getStatus() != StudyStatus.Failed) { + final StudyStatus status = StudyTaskManager.getInstance(project).getStatus(answerPlaceholder); + if (status != StudyStatus.Failed) { continue; } navigateToTaskWindow(editor, answerPlaceholder, taskFile); diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/projectView/StudyDirectoryNode.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/projectView/StudyDirectoryNode.java index 13762e308bee..b4c9992bc79b 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/projectView/StudyDirectoryNode.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/projectView/StudyDirectoryNode.java @@ -12,9 +12,13 @@ import com.intellij.psi.PsiElement; import com.intellij.ui.JBColor; import com.intellij.ui.SimpleTextAttributes; import com.jetbrains.edu.StudyNames; -import com.jetbrains.edu.courseFormat.*; +import com.jetbrains.edu.courseFormat.Course; +import com.jetbrains.edu.courseFormat.Lesson; +import com.jetbrains.edu.courseFormat.Task; +import com.jetbrains.edu.courseFormat.TaskFile; import com.jetbrains.edu.learning.StudyTaskManager; import com.jetbrains.edu.learning.StudyUtils; +import com.jetbrains.edu.learning.courseFormat.StudyStatus; import icons.InteractiveLearningIcons; import org.jetbrains.annotations.NotNull; @@ -91,20 +95,37 @@ public class StudyDirectoryNode extends PsiDirectoryNode { return name.contains(StudyNames.SANDBOX_DIR) ? 0 : 3; } - private static void setStudyAttributes(StudyStateful stateful, PresentationData data, String additionalName) { - StudyStatus taskStatus = stateful.getStatus(); + private void setStudyAttributes(Lesson lesson, PresentationData data, String additionalName) { + StudyStatus taskStatus = StudyTaskManager.getInstance(myProject).getStatus(lesson); switch (taskStatus) { case Unchecked: { - updatePresentation(data, additionalName, JBColor.BLACK, stateful instanceof Lesson ? InteractiveLearningIcons.Lesson : InteractiveLearningIcons.Task); + updatePresentation(data, additionalName, JBColor.BLACK, InteractiveLearningIcons.Lesson); + break; + } + case Solved: { + updatePresentation(data, additionalName, new JBColor(new Color(0, 134, 0), new Color(98, 150, 85)), InteractiveLearningIcons.LessonCompl); + break; + } + case Failed: { + updatePresentation(data, additionalName, JBColor.RED, InteractiveLearningIcons.Lesson); + } + } + } + + private void setStudyAttributes(Task task, PresentationData data, String additionalName) { + StudyStatus taskStatus = StudyTaskManager.getInstance(myProject).getStatus(task); + switch (taskStatus) { + case Unchecked: { + updatePresentation(data, additionalName, JBColor.BLACK, InteractiveLearningIcons.Task); break; } case Solved: { updatePresentation(data, additionalName, new JBColor(new Color(0, 134, 0), new Color(98, 150, 85)), - stateful instanceof Lesson ? InteractiveLearningIcons.LessonCompl : InteractiveLearningIcons.TaskCompl); + InteractiveLearningIcons.TaskCompl); break; } case Failed: { - updatePresentation(data, additionalName, JBColor.RED, stateful instanceof Lesson ? InteractiveLearningIcons.Lesson : InteractiveLearningIcons.TaskProbl); + updatePresentation(data, additionalName, JBColor.RED, InteractiveLearningIcons.TaskProbl); } } } diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/run/StudySmartChecker.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/run/StudySmartChecker.java index b1eee315216d..a39c7d13196e 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/run/StudySmartChecker.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/run/StudySmartChecker.java @@ -12,10 +12,11 @@ import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.VirtualFile; import com.jetbrains.edu.StudyNames; import com.jetbrains.edu.courseFormat.AnswerPlaceholder; -import com.jetbrains.edu.courseFormat.StudyStatus; import com.jetbrains.edu.courseFormat.TaskFile; import com.jetbrains.edu.learning.StudyDocumentListener; +import com.jetbrains.edu.learning.StudyTaskManager; import com.jetbrains.edu.learning.StudyUtils; +import com.jetbrains.edu.learning.courseFormat.StudyStatus; import org.jetbrains.annotations.NotNull; import java.io.File; @@ -66,7 +67,7 @@ public class StudySmartChecker { final CapturingProcessHandler handler = new CapturingProcessHandler(smartTestProcess); final ProcessOutput output = handler.runProcess(); boolean res = testRunner.getTestsOutput(output).equals(StudyTestRunner.TEST_OK); - userAnswerPlaceholder.setStatus(res ? StudyStatus.Solved : StudyStatus.Failed); + StudyTaskManager.getInstance(project).setStatus(userAnswerPlaceholder, res ? StudyStatus.Solved : StudyStatus.Failed); StudyUtils.deleteFile(windowCopy); if (fileWindows != null) { StudyUtils.deleteFile(fileWindows); diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyToolWindowFactory.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyToolWindowFactory.java index f383e5e7f18c..739954cee6d5 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyToolWindowFactory.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyToolWindowFactory.java @@ -9,9 +9,9 @@ import com.intellij.ui.content.ContentFactory; import com.intellij.util.ui.UIUtil; import com.jetbrains.edu.courseFormat.Course; import com.jetbrains.edu.courseFormat.Lesson; -import com.jetbrains.edu.courseFormat.StudyStatus; import com.jetbrains.edu.courseFormat.Task; import com.jetbrains.edu.learning.StudyTaskManager; +import com.jetbrains.edu.learning.courseFormat.StudyStatus; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -25,10 +25,11 @@ public class StudyToolWindowFactory implements ToolWindowFactory, DumbAware { @Override public void createToolWindowContent(@NotNull final Project project, @NotNull final ToolWindow toolWindow) { JPanel contentPanel = new JPanel(); - if (StudyTaskManager.getInstance(project).getCourse() != null) { + StudyTaskManager taskManager = StudyTaskManager.getInstance(project); + if (taskManager.getCourse() != null) { contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.PAGE_AXIS)); contentPanel.add(Box.createRigidArea(new Dimension(10, 0))); - StudyTaskManager taskManager = StudyTaskManager.getInstance(project); + Course course = taskManager.getCourse(); if (course == null) { return; @@ -47,11 +48,12 @@ public class StudyToolWindowFactory implements ToolWindowFactory, DumbAware { int lessonsCompleted = 0; List lessons = course.getLessons(); for (Lesson lesson : lessons) { - if (lesson.getStatus() == StudyStatus.Solved) { + StudyStatus status = taskManager.getStatus(lesson); + if (status == StudyStatus.Solved) { lessonsCompleted++; } taskNum += lesson.getTaskList().size(); - taskSolved += getTaskSolved(lesson); + taskSolved += getSolvedTasks(lesson, taskManager); } String completedLessons = String.format("%d of %d lessons completed", lessonsCompleted, course.getLessons().size()); String completedTasks = String.format("%d of %d tasks completed", taskSolved, taskNum); @@ -71,10 +73,10 @@ public class StudyToolWindowFactory implements ToolWindowFactory, DumbAware { } } - private static int getTaskSolved(@NotNull final Lesson lesson) { + private static int getSolvedTasks(@NotNull final Lesson lesson, StudyTaskManager taskManager) { int solved = 0; for (Task task : lesson.getTaskList()) { - if (task.getStatus() == StudyStatus.Solved) { + if (taskManager.getStatus(task) == StudyStatus.Solved) { solved += 1; } } diff --git a/python/educational/src/com/jetbrains/edu/courseFormat/AnswerPlaceholder.java b/python/educational/src/com/jetbrains/edu/courseFormat/AnswerPlaceholder.java index 3cfa988e55bc..0d9f1994e5e5 100644 --- a/python/educational/src/com/jetbrains/edu/courseFormat/AnswerPlaceholder.java +++ b/python/educational/src/com/jetbrains/edu/courseFormat/AnswerPlaceholder.java @@ -3,7 +3,6 @@ package com.jetbrains.edu.courseFormat; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; import com.intellij.openapi.editor.Document; -import com.intellij.ui.JBColor; import com.intellij.util.xmlb.annotations.Transient; import org.jetbrains.annotations.NotNull; @@ -11,7 +10,7 @@ import org.jetbrains.annotations.NotNull; * Implementation of windows which user should type in */ -public class AnswerPlaceholder implements Comparable, StudyStateful { +public class AnswerPlaceholder implements Comparable { @Expose private int line = 0; @Expose private int start = 0; @@ -21,20 +20,11 @@ public class AnswerPlaceholder implements Comparable, StudyStateful { @Expose private String possibleAnswer = ""; @Expose private int length = 0; private int myIndex = -1; - private StudyStatus myStatus = StudyStatus.Unchecked; private String myTaskText; private MyInitialState myInitialState; @Transient private TaskFile myTaskFile; - public StudyStatus getStatus() { - return myStatus; - } - - public void setStatus(StudyStatus status) { - myStatus = status; - } - public int getIndex() { return myIndex; } @@ -101,16 +91,6 @@ public class AnswerPlaceholder implements Comparable, StudyStateful { myTaskFile = taskFile; } - public JBColor getColor() { - if (myStatus == StudyStatus.Solved) { - return JBColor.GREEN; - } - if (myStatus == StudyStatus.Failed) { - return JBColor.RED; - } - return JBColor.BLUE; - } - public int getRealStartOffset(@NotNull final Document document) { return document.getLineStartOffset(line) + start; } @@ -123,7 +103,6 @@ public class AnswerPlaceholder implements Comparable, StudyStateful { return isLengthValid && isStartValid; } - @Override public int compareTo(@NotNull Object o) { AnswerPlaceholder answerPlaceholder = (AnswerPlaceholder)o; if (answerPlaceholder.getTaskFile() != myTaskFile) { @@ -140,7 +119,6 @@ public class AnswerPlaceholder implements Comparable, StudyStateful { * Returns window to its initial state */ public void reset() { - myStatus = StudyStatus.Unchecked; line = myInitialState.myLine; start = myInitialState.myStart; length = myInitialState.myLength; @@ -160,4 +138,30 @@ public class AnswerPlaceholder implements Comparable, StudyStateful { myStart = start; } } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + AnswerPlaceholder position = (AnswerPlaceholder)o; + + if (getStart() != position.getStart()) return false; + if (getLength() != position.getLength()) return false; + if (getIndex() != position.getIndex()) return false; + if (getLine() != position.getLine()) return false; + if (!getHint().equals(position.getHint())) return false; + + return true; + } + + @Override + public int hashCode() { + int result = getHint().hashCode(); + result = 31 * result + getLine(); + result = 31 * result + getStart(); + result = 31 * result + getLength(); + result = 31 * result + getIndex(); + return result; + } } diff --git a/python/educational/src/com/jetbrains/edu/courseFormat/Lesson.java b/python/educational/src/com/jetbrains/edu/courseFormat/Lesson.java index 31f27aa00b83..be451ca17fff 100644 --- a/python/educational/src/com/jetbrains/edu/courseFormat/Lesson.java +++ b/python/educational/src/com/jetbrains/edu/courseFormat/Lesson.java @@ -6,7 +6,7 @@ import com.intellij.util.xmlb.annotations.Transient; import java.util.ArrayList; import java.util.List; -public class Lesson implements StudyStateful { +public class Lesson { @Transient String id; @Transient @@ -40,24 +40,6 @@ public class Lesson implements StudyStateful { myIndex = index; } - @Transient - public StudyStatus getStatus() { - for (Task task : taskList) { - StudyStatus taskStatus = task.getStatus(); - if (taskStatus == StudyStatus.Unchecked || taskStatus == StudyStatus.Failed) { - return StudyStatus.Unchecked; - } - } - return StudyStatus.Solved; - } - - @Override - public void setStatus(StudyStatus status) { - for (Task task : taskList) { - task.setStatus(status); - } - } - public List getTaskList() { return taskList; } diff --git a/python/educational/src/com/jetbrains/edu/courseFormat/StudyStateful.java b/python/educational/src/com/jetbrains/edu/courseFormat/StudyStateful.java deleted file mode 100644 index 117f661e445f..000000000000 --- a/python/educational/src/com/jetbrains/edu/courseFormat/StudyStateful.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.jetbrains.edu.courseFormat; - -public interface StudyStateful { - StudyStatus getStatus(); - void setStatus(StudyStatus status); -} diff --git a/python/educational/src/com/jetbrains/edu/courseFormat/Task.java b/python/educational/src/com/jetbrains/edu/courseFormat/Task.java index 427042bfc782..4b493e1c8d42 100644 --- a/python/educational/src/com/jetbrains/edu/courseFormat/Task.java +++ b/python/educational/src/com/jetbrains/edu/courseFormat/Task.java @@ -15,7 +15,7 @@ import java.util.Map; /** * Implementation of task which contains task files, tests, input file for tests */ -public class Task implements StudyStateful { +public class Task { private String name; private int myIndex; public Map taskFiles = new HashMap(); @@ -65,26 +65,6 @@ public class Task implements StudyStateful { return taskFiles; } - @Transient - public StudyStatus getStatus() { - for (TaskFile taskFile : taskFiles.values()) { - StudyStatus taskFileStatus = taskFile.getStatus(); - if (taskFileStatus == StudyStatus.Unchecked) { - return StudyStatus.Unchecked; - } - if (taskFileStatus == StudyStatus.Failed) { - return StudyStatus.Failed; - } - } - return StudyStatus.Solved; - } - - public void setStatus(@NotNull final StudyStatus status) { - for (TaskFile taskFile : taskFiles.values()) { - taskFile.setStatus(status); - } - } - public List getUserTests() { return userTests; } diff --git a/python/educational/src/com/jetbrains/edu/courseFormat/TaskFile.java b/python/educational/src/com/jetbrains/edu/courseFormat/TaskFile.java index 36f1c03ab0a3..25230e68b9ae 100644 --- a/python/educational/src/com/jetbrains/edu/courseFormat/TaskFile.java +++ b/python/educational/src/com/jetbrains/edu/courseFormat/TaskFile.java @@ -15,7 +15,7 @@ import java.util.List; * which is visible to student in project view */ -public class TaskFile implements StudyStateful { +public class TaskFile { @SerializedName("placeholders") private List myAnswerPlaceholders = new ArrayList(); private int myIndex = -1; @@ -30,29 +30,6 @@ public class TaskFile implements StudyStateful { private boolean myTrackChanges = true; private boolean myHighlightErrors = false; - /** - * @return if all the windows in task file are marked as resolved - */ - @Transient - public StudyStatus getStatus() { - for (AnswerPlaceholder answerPlaceholder : myAnswerPlaceholders) { - StudyStatus windowStatus = answerPlaceholder.getStatus(); - if (windowStatus == StudyStatus.Failed) { - return StudyStatus.Failed; - } - if (windowStatus == StudyStatus.Unchecked) { - return StudyStatus.Unchecked; - } - } - return StudyStatus.Solved; - } - - public void setStatus(@NotNull final StudyStatus status) { - for (AnswerPlaceholder answerPlaceholder : myAnswerPlaceholders) { - answerPlaceholder.setStatus(status); - } - } - @Nullable @Transient public AnswerPlaceholder getSelectedAnswerPlaceholder() { @@ -144,10 +121,6 @@ public class TaskFile implements StudyStateful { return myUserCreated; } - public boolean hasFailedTaskWindows() { - return myAnswerPlaceholders.size() > 0 && getStatus() == StudyStatus.Failed; - } - public boolean isTrackChanges() { return myTrackChanges; }