remove code related to subtasks

This commit is contained in:
liana.bakradze
2016-07-28 11:17:10 +03:00
parent ed9210111d
commit 80e8516e25
30 changed files with 65 additions and 903 deletions
@@ -25,8 +25,6 @@
<renameHandler implementation="com.jetbrains.edu.coursecreator.handlers.CCLessonRenameHandler" order="first"/>
<applicationService serviceInterface="com.jetbrains.edu.coursecreator.settings.CCSettings"
serviceImplementation="com.jetbrains.edu.coursecreator.settings.CCSettings"/>
<editorTabTitleProvider implementation="com.jetbrains.edu.coursecreator.CCTestsTabTitleProvider"/>
<editorNotificationProvider implementation="com.jetbrains.edu.coursecreator.CCStepEditorNotificationProvider"/>
</extensions>
<extensions defaultExtensionNs="Edu">
<studyActionsProvider implementation="com.jetbrains.edu.coursecreator.CCStudyActionsProvider"/>
@@ -87,9 +85,6 @@
</group>
<action id="UnpackCourse" class="com.jetbrains.edu.coursecreator.actions.CCFromCourseArchive"/>
<action class="com.jetbrains.edu.coursecreator.actions.CCNewStepAction" id="CC.NewStep">
<add-to-group group-id="AnswerPlaceholderGroup" relative-to-action="DeleteAllPlaceholders" anchor="after"/>
</action>
</actions>
@@ -4,7 +4,6 @@ import com.intellij.ide.fileTemplates.FileTemplate;
import com.intellij.lang.LanguageExtension;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.jetbrains.edu.learning.courseFormat.Task;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -27,6 +26,4 @@ public interface CCLanguageManager {
default boolean isTestFile(VirtualFile file) {
return false;
}
default void createTestsForNewStep(@NotNull Project project, @NotNull Task task) {}
}
@@ -1,171 +0,0 @@
package com.jetbrains.edu.coursecreator;
import com.intellij.openapi.editor.colors.EditorColors;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.ListSeparator;
import com.intellij.openapi.ui.popup.PopupStep;
import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.EditorNotificationPanel;
import com.intellij.ui.EditorNotifications;
import com.intellij.ui.awt.RelativePoint;
import com.jetbrains.edu.coursecreator.actions.CCNewStepAction;
import com.jetbrains.edu.learning.StudyStepManager;
import com.jetbrains.edu.learning.StudyUtils;
import com.jetbrains.edu.learning.core.EduNames;
import com.jetbrains.edu.learning.courseFormat.Task;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class CCStepEditorNotificationProvider extends EditorNotifications.Provider<EditorNotificationPanel> implements DumbAware {
private static final Key<EditorNotificationPanel> KEY = Key.create("edu.coursecreator.step");
public static final String SWITCH_STEP = "Switch step";
public static final Integer ADD_STEP_ID = -2;
private final Project myProject;
public CCStepEditorNotificationProvider(Project project) {
myProject = project;
}
@NotNull
@Override
public Key<EditorNotificationPanel> getKey() {
return KEY;
}
@Nullable
@Override
public EditorNotificationPanel createNotificationPanel(@NotNull VirtualFile file, @NotNull FileEditor fileEditor) {
if (!CCUtils.isCourseCreator(myProject)) {
return null;
}
boolean isTestFile = CCUtils.isTestsFile(myProject, file);
if (!isTestFile && StudyUtils.getTaskFile(myProject, file) == null) {
return null;
}
Task task = StudyUtils.getTaskForFile(myProject, file);
if (task == null || task.getAdditionalSteps().isEmpty()) {
return null;
}
int activeStepIndex = task.getActiveStepIndex() + 2;
int stepsNum = task.getAdditionalSteps().size() + 1;
EditorNotificationPanel panel = new EditorNotificationPanel() {
@Override
public Color getBackground() {
Color color = EditorColorsManager.getInstance().getGlobalScheme().getColor(EditorColors.GUTTER_BACKGROUND);
return color == null ? super.getBackground() : color;
}
};
String header = isTestFile ? "test" : "task file";
panel.setText("This is " + header + " for " + EduNames.STEP + " " + activeStepIndex + "/" + stepsNum);
panel.createActionLabel(SWITCH_STEP, () -> {
ArrayList<Integer> values = new ArrayList<>();
values.add(-1);
for (int i = 0; i < task.getAdditionalSteps().size(); i++) {
values.add(i);
}
values.add(ADD_STEP_ID);
JBPopupFactory.getInstance().createListPopup(new SwitchStepPopupStep(SWITCH_STEP, values, task, file)).show(RelativePoint.getSouthEastOf(panel));
});
return panel;
}
private class SwitchStepPopupStep extends BaseListPopupStep<Integer> {
private final Task myTask;
private final VirtualFile myFile;
public SwitchStepPopupStep(@Nullable String title,
List<Integer> values,
Task task, VirtualFile file) {
super(title, values);
myTask = task;
myFile = file;
}
@NotNull
@Override
public String getTextFor(Integer value) {
if (value.equals(ADD_STEP_ID)) {
return CCNewStepAction.NEW_STEP;
}
int stepNum = value + 2;
String text = EduNames.STEP + " " + stepNum;
if (value == myTask.getActiveStepIndex()) {
text += " (current step)";
}
return text;
}
@Override
public PopupStep onChosen(Integer selectedValue, boolean finalChoice) {
if (finalChoice) {
if (selectedValue.equals(ADD_STEP_ID)) {
return doFinalStep(() -> CCNewStepAction.addStep(myFile, myProject));
}
return doFinalStep(() -> StudyStepManager.switchStep(myProject, myTask, selectedValue));
} else {
if (hasSubstep(selectedValue)) {
return new ActionsPopupStep(myTask, selectedValue);
}
}
return super.onChosen(selectedValue, false);
}
@Override
public boolean hasSubstep(Integer selectedValue) {
return !selectedValue.equals(ADD_STEP_ID);
}
@Override
public int getDefaultOptionIndex() {
return myTask.getActiveStepIndex() + 1;
}
@Nullable
@Override
public ListSeparator getSeparatorAbove(Integer value) {
return value.equals(ADD_STEP_ID) ? new ListSeparator(): null;
}
}
private class ActionsPopupStep extends BaseListPopupStep<String> {
public static final String SELECT = "Select";
public static final String DELETE = "Delete";
private final Task myTask;
private final int myStepIndex;
public ActionsPopupStep(Task task, int stepIndex) {
super(null, Arrays.asList(SELECT, DELETE));
myTask = task;
myStepIndex = stepIndex;
}
@Override
public PopupStep onChosen(String selectedValue, boolean finalChoice) {
if (finalChoice) {
if (selectedValue.equals(SELECT)) {
StudyStepManager.switchStep(myProject, myTask, myStepIndex);
} else {
if (myStepIndex != myTask.getAdditionalSteps().size() - 1) {
//TODO: implement
} else {
StudyStepManager.deleteStep(myProject, myTask, myStepIndex);
}
return FINAL_CHOICE;
}
}
return super.onChosen(selectedValue, finalChoice);
}
}
}
@@ -1,30 +0,0 @@
package com.jetbrains.edu.coursecreator;
import com.intellij.openapi.fileEditor.impl.EditorTabTitleProvider;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.jetbrains.edu.learning.StudyLanguageManager;
import com.jetbrains.edu.learning.StudyTaskManager;
import com.jetbrains.edu.learning.StudyUtils;
import com.jetbrains.edu.learning.courseFormat.Course;
import org.jetbrains.annotations.Nullable;
public class CCTestsTabTitleProvider implements EditorTabTitleProvider {
@Nullable
@Override
public String getEditorTabTitle(Project project, VirtualFile file) {
if (!CCUtils.isCourseCreator(project)) {
return null;
}
if (!CCUtils.isTestsFile(project, file)) {
return null;
}
Course course = StudyTaskManager.getInstance(project).getCourse();
assert course != null;
StudyLanguageManager manager = StudyUtils.getLanguageManager(course);
if (manager == null) {
return null;
}
return manager.getTestFileName();
}
}
@@ -20,7 +20,6 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.util.Function;
import com.jetbrains.edu.learning.StudyTaskManager;
import com.jetbrains.edu.learning.StudyUtils;
import com.jetbrains.edu.learning.core.EduUtils;
import com.jetbrains.edu.learning.courseFormat.Course;
import com.jetbrains.edu.learning.courseFormat.StudyItem;
@@ -235,15 +234,14 @@ public class CCUtils {
if (studentDir == null) {
return;
}
Map<String, TaskFile> files = StudyUtils.getTaskFiles(task);
for (Map.Entry<String, TaskFile> entry : files.entrySet()) {
for (Map.Entry<String, TaskFile> entry : task.getTaskFiles().entrySet()) {
String name = entry.getKey();
VirtualFile answerFile = taskDir.findChild(name);
if (answerFile == null) {
continue;
}
ApplicationManager.getApplication().runWriteAction(() -> {
EduUtils.createStudentFile(CCUtils.class, project, answerFile, task.getActiveStepIndex(), studentDir, null);
EduUtils.createStudentFile(CCUtils.class, project, answerFile, studentDir, null);
});
}
}
@@ -128,7 +128,7 @@ public class CCCreateCourseArchive extends DumbAwareAction {
if (answerFile == null) {
continue;
}
EduUtils.createStudentFile(this, project, answerFile, -1, studentFileDir, task);
EduUtils.createStudentFile(this, project, answerFile, studentFileDir, task);
}
}
}
@@ -50,7 +50,7 @@ public class CCEditTaskTextAction extends ToggleAction implements DumbAware {
return;
}
final StudyState studyState = new StudyState(selectedEditor);
VirtualFile taskTextFile = StudyUtils.findTaskDescriptionVirtualFile(project, studyState.getTaskDir());
VirtualFile taskTextFile = StudyUtils.findTaskDescriptionVirtualFile(studyState.getTaskDir());
if (taskTextFile == null) {
LOG.info("Failed to find task.html");
return;
@@ -1,119 +0,0 @@
package com.jetbrains.edu.coursecreator.actions;
import com.intellij.ide.fileTemplates.FileTemplate;
import com.intellij.ide.fileTemplates.FileTemplateManager;
import com.intellij.ide.fileTemplates.FileTemplateUtil;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiManager;
import com.jetbrains.edu.coursecreator.CCLanguageManager;
import com.jetbrains.edu.coursecreator.CCUtils;
import com.jetbrains.edu.coursecreator.settings.CCSettings;
import com.jetbrains.edu.learning.StudyStepManager;
import com.jetbrains.edu.learning.StudyTaskManager;
import com.jetbrains.edu.learning.StudyUtils;
import com.jetbrains.edu.learning.core.EduNames;
import com.jetbrains.edu.learning.courseFormat.Course;
import com.jetbrains.edu.learning.courseFormat.Step;
import com.jetbrains.edu.learning.courseFormat.Task;
import com.jetbrains.edu.learning.courseFormat.TaskFile;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public class CCNewStepAction extends DumbAwareAction {
private static final Logger LOG = Logger.getInstance(CCNewStepAction.class);
public static final String NEW_STEP = "New Step";
public CCNewStepAction() {
super(NEW_STEP);
}
@Override
public void actionPerformed(AnActionEvent e) {
DataContext dataContext = e.getDataContext();
VirtualFile virtualFile = CommonDataKeys.VIRTUAL_FILE.getData(dataContext);
Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
Project project = CommonDataKeys.PROJECT.getData(dataContext);
if (virtualFile == null || project == null || editor == null) {
return;
}
addStep(virtualFile, project);
}
public static void addStep(@NotNull VirtualFile virtualFile, @NotNull Project project) {
TaskFile taskFile = StudyUtils.getTaskFile(project, virtualFile);
if (taskFile == null) {
return;
}
VirtualFile taskDir = StudyUtils.getTaskDir(virtualFile);
if (taskDir == null) {
return;
}
Task task = taskFile.getTask();
List<Step> steps = task.getAdditionalSteps();
createTestsForNewStep(project, task);
createTaskDescriptionFile(project, taskDir, steps.size());
Step step = new Step(task);
steps.add(step);
StudyStepManager.switchStep(project, task, steps.size() - 1);
}
private static void createTestsForNewStep(Project project, Task task) {
Course course = StudyTaskManager.getInstance(project).getCourse();
if (course == null) {
return;
}
CCLanguageManager manager = CCUtils.getStudyLanguageManager(course);
if (manager == null) {
return;
}
manager.createTestsForNewStep(project, task);
}
private static void createTaskDescriptionFile(Project project, VirtualFile taskDir, int index) {
String taskDescriptionFileName = StudyUtils.getTaskDescriptionFileName(CCSettings.getInstance().useHtmlAsDefaultTaskFormat());
FileTemplate taskTextTemplate = FileTemplateManager.getInstance(project)
.getInternalTemplate(taskDescriptionFileName);
PsiDirectory taskPsiDir = PsiManager.getInstance(project).findDirectory(taskDir);
if (taskTextTemplate != null && taskPsiDir != null) {
String nextTaskTextName = FileUtil.getNameWithoutExtension(taskDescriptionFileName) +
EduNames.STEP_MARKER +
index + "." +
FileUtilRt.getExtension(taskDescriptionFileName);
try {
FileTemplateUtil.createFromTemplate(taskTextTemplate, nextTaskTextName, null, taskPsiDir);
}
catch (Exception e) {
LOG.error(e);
}
}
}
@Override
public void update(AnActionEvent e) {
DataContext dataContext = e.getDataContext();
Presentation presentation = e.getPresentation();
presentation.setEnabledAndVisible(false);
VirtualFile virtualFile = CommonDataKeys.VIRTUAL_FILE.getData(dataContext);
Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
Project project = CommonDataKeys.PROJECT.getData(dataContext);
if (virtualFile == null || project == null || editor == null) {
return;
}
if (CCUtils.isCourseCreator(project) && StudyUtils.getTaskForFile(project, virtualFile) != null) {
presentation.setEnabledAndVisible(true);
}
}
}
@@ -122,7 +122,7 @@ public class CCShowPreview extends DumbAwareAction {
@Override
public void run() {
Pair<VirtualFile, TaskFile> pair =
EduUtils.createStudentFile(this, project, virtualFile, taskFile.getTask().getActiveStepIndex(), generatedFilesFolder, null);
EduUtils.createStudentFile(this, project, virtualFile, generatedFilesFolder, null);
if (pair != null) {
showPreviewDialog(project, pair.getFirst(), pair.getSecond());
}
@@ -11,28 +11,19 @@ import com.intellij.ui.SimpleTextAttributes;
* represents a file which is invisible for student in student mode
*/
public class CCStudentInvisibleFileNode extends PsiFileNode{
private final String myName;
public CCStudentInvisibleFileNode(Project project,
PsiFile value,
ViewSettings viewSettings) {
super(project, value, viewSettings);
myName = value.getName();
}
public CCStudentInvisibleFileNode(Project project,
PsiFile value,
ViewSettings viewSettings,
String name) {
super(project, value, viewSettings);
myName = name;
}
@Override
protected void updateImpl(PresentationData data) {
super.updateImpl(data);
String text = data.getPresentableText();
data.clearText();
data.addText(myName, SimpleTextAttributes.GRAY_ATTRIBUTES);
data.addText(text, SimpleTextAttributes.GRAY_ATTRIBUTES);
}
}
@@ -9,12 +9,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiFile;
import com.jetbrains.edu.coursecreator.CCUtils;
import com.jetbrains.edu.learning.StudyLanguageManager;
import com.jetbrains.edu.learning.StudyTaskManager;
import com.jetbrains.edu.learning.StudyUtils;
import com.jetbrains.edu.learning.core.EduNames;
import com.jetbrains.edu.learning.courseFormat.Course;
import com.jetbrains.edu.learning.courseFormat.Task;
import com.jetbrains.edu.learning.projectView.StudyTreeStructureProvider;
import org.jetbrains.annotations.NotNull;
@@ -53,61 +48,12 @@ public class CCTreeStructureProvider extends StudyTreeStructureProvider {
continue;
}
PsiFile psiFile = ((PsiFileNode)node).getValue();
if (!handleTests(project, virtualFile, psiFile, modifiedChildren, settings)) {
modifiedChildren.add(new CCStudentInvisibleFileNode(project, psiFile, settings));
}
modifiedChildren.add(new CCStudentInvisibleFileNode(project, psiFile, settings));
}
}
return modifiedChildren;
}
private static boolean handleTests(Project project,
VirtualFile virtualFile,
PsiFile psiFile,
Collection<AbstractTreeNode> modifiedChildren,
ViewSettings settings) {
Course course = StudyTaskManager.getInstance(project).getCourse();
if (course == null) {
return false;
}
if (!CCUtils.isTestsFile(project, virtualFile)) {
return false;
}
VirtualFile taskDir = StudyUtils.getTaskDir(virtualFile);
if (taskDir == null) {
return false;
}
Task task = StudyUtils.getTask(project, taskDir);
if (task == null) {
return false;
}
if (isCurrentStep(task, virtualFile)) {
StudyLanguageManager manager = StudyUtils.getLanguageManager(course);
String testsFileName = manager != null ? manager.getTestFileName() : psiFile.getName();
modifiedChildren.add(new CCStudentInvisibleFileNode(project, psiFile, settings,
testsFileName));
}
return true;
}
private static boolean isCurrentStep(Task task, VirtualFile virtualFile) {
if (task.getAdditionalSteps().isEmpty()) {
return true;
}
boolean isStepTestFile = virtualFile.getName().contains(EduNames.STEP_MARKER);
if (task.getActiveStepIndex() == -1) {
return !isStepTestFile;
}
if (!isStepTestFile) {
return false;
}
String nameWithoutExtension = virtualFile.getNameWithoutExtension();
int stepMarkerStart = nameWithoutExtension.indexOf(EduNames.STEP_MARKER);
int stepIndex = Integer.valueOf(nameWithoutExtension.substring(EduNames.STEP_MARKER.length() + stepMarkerStart));
return stepIndex == task.getActiveStepIndex();
}
protected boolean needModify(@NotNull final AbstractTreeNode parent) {
Project project = parent.getProject();
if (project == null) {
@@ -1,94 +0,0 @@
package com.jetbrains.edu.learning;
import com.intellij.ide.projectView.ProjectView;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.EditorNotifications;
import com.jetbrains.edu.learning.checker.StudyCheckUtils;
import com.jetbrains.edu.learning.core.EduNames;
import com.jetbrains.edu.learning.courseFormat.Task;
import com.jetbrains.edu.learning.courseFormat.TaskFile;
import com.jetbrains.edu.learning.ui.StudyToolWindow;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;
public class StudyStepManager {
private static final Logger LOG = Logger.getInstance(StudyStepManager.class);
public static void switchStep(@NotNull Project project, @NotNull Task task, int step) {
if (task.getActiveStepIndex() == step) {
return;
}
task.setActiveStepIndex(step);
VirtualFile taskDir = task.getTaskDir(project);
if (taskDir == null) {
return;
}
VirtualFile srcDir = taskDir.findChild(EduNames.SRC);
if (srcDir != null) {
taskDir = srcDir;
}
for (Map.Entry<String, TaskFile> entry : task.getTaskFiles().entrySet()) {
String name = entry.getKey();
VirtualFile virtualFile = taskDir.findChild(name);
if (virtualFile == null) {
continue;
}
EditorNotifications.getInstance(project).updateNotifications(virtualFile);
}
update(project, task, taskDir);
}
private static void update(@NotNull Project project, @NotNull Task task, VirtualFile taskDir) {
StudyCheckUtils.drawAllPlaceholders(project, task, taskDir);
ProjectView.getInstance(project).refresh();
StudyToolWindow toolWindow = StudyUtils.getStudyToolWindow(project);
if (toolWindow != null) {
String text = StudyUtils.getTaskTextFromTask(taskDir, task);
if (text == null) {
toolWindow.setEmptyText(project);
return;
}
toolWindow.setTaskText(text, taskDir, project);
}
}
public static void deleteStep(@NotNull Project project, @NotNull Task task, int index) {
//TODO: delete not only the last step
VirtualFile taskDir = task.getTaskDir(project);
if (taskDir == null) {
return;
}
ArrayList<VirtualFile> filesToDelete = new ArrayList<>();
for (VirtualFile file : taskDir.getChildren()) {
String stepSuffix = EduNames.STEP_MARKER + index;
if (file.getName().contains(stepSuffix)) {
filesToDelete.add(file);
}
}
for (VirtualFile file : filesToDelete) {
ApplicationManager.getApplication().runWriteAction(() -> {
try {
file.delete(StudyStepManager.class);
}
catch (IOException e) {
LOG.error(e);
}
});
}
task.getAdditionalSteps().remove(index);
if (task.getActiveStepIndex() == index) {
switchStep(project, task, index - 1);
}
}
}
@@ -30,7 +30,6 @@ import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
@@ -342,13 +341,7 @@ public class StudyUtils {
}
public static void drawAllWindows(Editor editor, TaskFile taskFile) {
drawAllWindows(editor, taskFile, true);
}
public static void drawAllWindows(Editor editor, TaskFile taskFile, boolean removePrevHighlighters) {
if (removePrevHighlighters) {
editor.getMarkupModel().removeAllHighlighters();
}
editor.getMarkupModel().removeAllHighlighters();
final Project project = editor.getProject();
if (project == null) return;
final StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
@@ -481,35 +474,21 @@ public class StudyUtils {
return null;
}
String text = getFromTask(task);
String text = task.getText();
if (text != null && !text.isEmpty()) {
return text;
}
if (taskDirectory != null) {
String fileNameWithoutExtension = FileUtil.getNameWithoutExtension(EduNames.TASK_HTML);
int activeStepIndex = task.getActiveStepIndex();
if (activeStepIndex != -1) {
fileNameWithoutExtension += EduNames.STEP_MARKER + activeStepIndex;
}
final String prefix = String.format(ourPrefix, EditorColorsManager.getInstance().getGlobalScheme().getEditorFontSize());
final String taskTextFileHtml = getTaskTextFromTaskName(taskDirectory, fileNameWithoutExtension + "." + FileUtilRt.getExtension(EduNames.TASK_HTML));
final String taskTextFileHtml = getTaskTextFromTaskName(taskDirectory, EduNames.TASK_HTML);
if (taskTextFileHtml != null) return prefix + taskTextFileHtml + ourPostfix;
final String taskTextFileMd = getTaskTextFromTaskName(taskDirectory, fileNameWithoutExtension + "." + FileUtilRt.getExtension(EduNames.TASK_MD));
final String taskTextFileMd = getTaskTextFromTaskName(taskDirectory, EduNames.TASK_MD);
if (taskTextFileMd != null) return prefix + convertToHtml(taskTextFileMd) + ourPostfix;
}
return null;
}
@Nullable
private static String getFromTask(Task task) {
int index = task.getActiveStepIndex();
if (index == -1) {
return task.getText();
}
return task.getAdditionalSteps().get(index).getText();
}
@Nullable
private static String getTaskTextFromTaskName(@NotNull VirtualFile taskDirectory, @NotNull String taskTextFilename) {
VirtualFile taskTextFile = taskDirectory.findChild(taskTextFilename);
@@ -704,25 +683,12 @@ public class StudyUtils {
}
public static boolean isTaskDescriptionFile(@NotNull final String fileName) {
if (EduNames.TASK_HTML.equals(fileName) || EduNames.TASK_MD.equals(fileName)) {
return true;
}
return fileName.contains(EduNames.TASK) && fileName.contains(EduNames.STEP_MARKER);
return EduNames.TASK_HTML.equals(fileName) || EduNames.TASK_MD.equals(fileName);
}
@Nullable
public static VirtualFile findTaskDescriptionVirtualFile(@NotNull Project project, @NotNull VirtualFile taskDir) {
Task task = getTask(project, taskDir.getName().contains(EduNames.TASK) ? taskDir: taskDir.getParent());
if (task == null) {
return null;
}
String fileNameWithoutExtension = FileUtil.getNameWithoutExtension(EduNames.TASK_HTML);
int activeStepIndex = task.getActiveStepIndex();
if (activeStepIndex != -1) {
fileNameWithoutExtension += EduNames.STEP_MARKER + activeStepIndex;
}
return ObjectUtils.chooseNotNull(taskDir.findChild(fileNameWithoutExtension + "." + FileUtilRt.getExtension(EduNames.TASK_HTML)),
taskDir.findChild(fileNameWithoutExtension + "." + FileUtilRt.getExtension(EduNames.TASK_MD)));
public static VirtualFile findTaskDescriptionVirtualFile(@NotNull VirtualFile taskDir) {
return ObjectUtils.chooseNotNull(taskDir.findChild(EduNames.TASK_HTML), taskDir.findChild(EduNames.TASK_MD));
}
@NotNull
@@ -758,34 +724,4 @@ public class StudyUtils {
JBPopupFactory.getInstance().createHtmlTextBalloonBuilder("Couldn't post your reaction", MessageType.ERROR, null).createBalloon();
showCheckPopUp(project, balloon);
}
public static void drawPlaceholdersFromOtherSteps(Editor editor, TaskFile taskFile, Task task) {
for (int i = -1; i < task.getAdditionalSteps().size(); i++) {
if (i == task.getActiveStepIndex()) {
continue;
}
List<AnswerPlaceholder> placeholders = getPlaceholders(i, task, taskFile);
for (AnswerPlaceholder placeholder : placeholders) {
EduAnswerPlaceholderPainter.drawAnswerPlaceholderFromPrevStep(editor, placeholder);
}
}
}
private static List<AnswerPlaceholder> getPlaceholders(int index, Task task, TaskFile taskFile) {
TaskFile prevTaskFile = index == -1 ? taskFile.getTask().getTaskFile(taskFile.name)
: task.getAdditionalSteps().get(index).getTaskFiles().get(taskFile.name);
if (prevTaskFile == null) {
return Collections.emptyList();
}
return prevTaskFile.getAnswerPlaceholders();
}
public static Map<String, TaskFile> getTaskFiles(@NotNull Task task) {
int activeStepIndex = task.getActiveStepIndex();
if (activeStepIndex == -1) {
return task.getTaskFiles();
}
return task.getAdditionalSteps().get(activeStepIndex).getTaskFiles();
}
}
@@ -11,7 +11,6 @@ import com.jetbrains.edu.learning.StudyTaskManager;
import com.jetbrains.edu.learning.core.EduNames;
import com.jetbrains.edu.learning.courseFormat.AnswerPlaceholder;
import com.jetbrains.edu.learning.courseFormat.Course;
import com.jetbrains.edu.learning.courseFormat.Task;
import com.jetbrains.edu.learning.courseFormat.TaskFile;
import com.jetbrains.edu.learning.StudyState;
import com.jetbrains.edu.learning.StudyUtils;
@@ -28,15 +27,6 @@ public class StudyFillPlaceholdersAction extends AnAction {
return;
}
TaskFile taskFile = studyState.getTaskFile();
Task task = taskFile.getTask();
int stepIndex = task.getActiveStepIndex();
if (stepIndex != -1) {
TaskFile stepTaskFile = task.getAdditionalSteps().get(stepIndex).getTaskFiles().get(taskFile.name);
if (stepTaskFile == null) {
return;
}
taskFile = stepTaskFile;
}
final Document document = studyState.getEditor().getDocument();
final TaskFile realTaskFile = taskFile;
CommandProcessor.getInstance().runUndoTransparentAction(() -> ApplicationManager.getApplication().runWriteAction(() -> {
@@ -20,10 +20,16 @@ import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.problems.WolfTheProblemSolver;
import com.jetbrains.edu.learning.*;
import com.jetbrains.edu.learning.StudyActionListener;
import com.jetbrains.edu.learning.StudyState;
import com.jetbrains.edu.learning.StudyTaskManager;
import com.jetbrains.edu.learning.StudyUtils;
import com.jetbrains.edu.learning.core.EduAnswerPlaceholderPainter;
import com.jetbrains.edu.learning.core.EduNames;
import com.jetbrains.edu.learning.courseFormat.*;
import com.jetbrains.edu.learning.courseFormat.AnswerPlaceholder;
import com.jetbrains.edu.learning.courseFormat.Course;
import com.jetbrains.edu.learning.courseFormat.StudyStatus;
import com.jetbrains.edu.learning.courseFormat.TaskFile;
import com.jetbrains.edu.learning.editor.StudyEditor;
import com.jetbrains.edu.learning.navigation.StudyNavigator;
import icons.InteractiveLearningIcons;
@@ -31,7 +37,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.List;
public class StudyRefreshTaskFileAction extends StudyActionWithShortcut {
public static final String ACTION_ID = "RefreshTaskAction";
@@ -77,16 +82,11 @@ public class StudyRefreshTaskFileAction extends StudyActionWithShortcut {
@NotNull final Project project,
TaskFile taskFile,
String name) {
Task task = taskFile.getTask();
List<Step> additionalSteps = task.getAdditionalSteps();
if (!additionalSteps.isEmpty() && task.getActiveStepIndex() != -1) {
StudyStepManager.switchStep(project, task, -1);
}
if (!resetDocument(document, taskFile, name)) {
return false;
}
task.setStatus(StudyStatus.Unchecked);
resetAnswerPlaceholders(taskFile);
taskFile.getTask().setStatus(StudyStatus.Unchecked);
resetAnswerPlaceholders(taskFile, project);
ProjectView.getInstance(project).refresh();
StudyUtils.updateToolWindows(project);
return true;
@@ -102,23 +102,11 @@ public class StudyRefreshTaskFileAction extends StudyActionWithShortcut {
Disposer.register(project, balloon);
}
private static void resetAnswerPlaceholders(TaskFile selectedTaskFile) {
private static void resetAnswerPlaceholders(TaskFile selectedTaskFile, Project project) {
final StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
for (AnswerPlaceholder answerPlaceholder : selectedTaskFile.getAnswerPlaceholders()) {
answerPlaceholder.reset();
answerPlaceholder.setStatus(StudyStatus.Unchecked);
}
List<Step> additionalSteps = selectedTaskFile.getTask().getAdditionalSteps();
if (!additionalSteps.isEmpty()) {
for (Step step : additionalSteps) {
TaskFile stepTaskFile = step.getTaskFiles().get(selectedTaskFile.name);
if (stepTaskFile == null) {
continue;
}
for (AnswerPlaceholder placeholder : stepTaskFile.getAnswerPlaceholders()) {
placeholder.reset();
placeholder.setStatus(StudyStatus.Unchecked);
}
}
taskManager.setStatus(answerPlaceholder, StudyStatus.Unchecked);
}
}
@@ -12,19 +12,22 @@ import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.jetbrains.edu.learning.*;
import com.jetbrains.edu.learning.StudyPluginConfigurator;
import com.jetbrains.edu.learning.StudyState;
import com.jetbrains.edu.learning.StudyTaskManager;
import com.jetbrains.edu.learning.StudyUtils;
import com.jetbrains.edu.learning.actions.StudyAfterCheckAction;
import com.jetbrains.edu.learning.core.EduNames;
import com.jetbrains.edu.learning.core.EduUtils;
import com.jetbrains.edu.learning.courseFormat.*;
import com.jetbrains.edu.learning.courseFormat.Course;
import com.jetbrains.edu.learning.courseFormat.StudyStatus;
import com.jetbrains.edu.learning.courseFormat.Task;
import com.jetbrains.edu.learning.stepic.EduAdaptiveStepicConnector;
import com.jetbrains.edu.learning.stepic.EduStepicConnector;
import com.jetbrains.edu.learning.stepic.StepicUser;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public class StudyCheckTask extends com.intellij.openapi.progress.Task.Backgroundable {
private static final Logger LOG = Logger.getInstance(StudyCheckTask.class);
@@ -58,19 +61,6 @@ public class StudyCheckTask extends com.intellij.openapi.progress.Task.Backgroun
StudyCheckUtils.drawAllPlaceholders(myProject, myTask, myTaskDir);
ProjectView.getInstance(myProject).refresh();
clearState();
List<Step> additionalSteps = myTask.getAdditionalSteps();
if (additionalSteps.isEmpty() || myTask.getActiveStepIndex() == additionalSteps.size() - 1) {
return;
}
for (TaskFile taskFile : myTask.getTaskFiles().values()) {
for (AnswerPlaceholder placeholder : taskFile.getAnswerPlaceholders()) {
if (placeholder.getStatus() != StudyStatus.Solved) {
return;
}
}
}
ApplicationManager.getApplication().invokeLater(() -> StudyStepManager.switchStep(myProject, myTask, myTask.getActiveStepIndex() + 1));
}
protected void clearState() {
@@ -188,18 +178,7 @@ public class StudyCheckTask extends com.intellij.openapi.progress.Task.Backgroun
protected void onTaskSolved(String message) {
final Course course = StudyTaskManager.getInstance(myProject).getCourse();
List<Step> additionalSteps = myTask.getAdditionalSteps();
boolean noMoreSteps = additionalSteps.isEmpty() || myTask.getActiveStepIndex() == additionalSteps.size() - 1;
if (noMoreSteps) {
myTask.setStatus(StudyStatus.Solved);
}
else {
for (TaskFile taskFile : myTask.getTaskFiles().values()) {
for (AnswerPlaceholder placeholder : taskFile.getAnswerPlaceholders()) {
placeholder.setStatus(StudyStatus.Solved);
}
}
}
myTask.setStatus(StudyStatus.Solved);
if (course != null) {
if (course.isAdaptive()) {
ApplicationManager.getApplication().invokeLater(
@@ -209,15 +188,8 @@ public class StudyCheckTask extends com.intellij.openapi.progress.Task.Backgroun
});
}
else {
String successMessage = message;
if (!noMoreSteps) {
int stepNum = additionalSteps.size() + 1;
int currentStep = myTask.getActiveStepIndex() + 2;
successMessage = "Step " + currentStep + " from " + stepNum + " solved";
}
String finalSuccessMessage = successMessage;
ApplicationManager.getApplication()
.invokeLater(() -> StudyCheckUtils.showTestResultPopUp(finalSuccessMessage, MessageType.INFO.getPopupBackground(), myProject));
.invokeLater(() -> StudyCheckUtils.showTestResultPopUp(message, MessageType.INFO.getPopupBackground(), myProject));
}
}
}
@@ -51,23 +51,15 @@ public class StudyCheckUtils {
public static void drawAllPlaceholders(@NotNull final Project project, @NotNull final Task task, @NotNull final VirtualFile taskDir) {
for (Map.Entry<String, TaskFile> entry : task.getTaskFiles().entrySet()) {
String name = entry.getKey();
TaskFile taskFile = entry.getValue();
VirtualFile virtualFile = taskDir.findChild(name);
if (virtualFile == null) {
continue;
}
if (FileEditorManager.getInstance(project).isFileOpen(virtualFile)) {
FileEditor fileEditor = FileEditorManager.getInstance(project).getSelectedEditor(virtualFile);
if (fileEditor instanceof StudyEditor) {
Editor editor = ((StudyEditor)fileEditor).getEditor();
editor.getMarkupModel().removeAllHighlighters();
for (TaskFile taskFile : task.getTaskFiles().values()) {
StudyUtils.drawPlaceholdersFromOtherSteps(editor, taskFile, task);
}
TaskFile currentTaskFile = StudyUtils.getTaskFile(project, virtualFile);
if (currentTaskFile != null) {
StudyUtils.drawAllWindows(editor, currentTaskFile, false);
}
}
FileEditor fileEditor = FileEditorManager.getInstance(project).getSelectedEditor(virtualFile);
if (fileEditor instanceof StudyEditor) {
StudyEditor studyEditor = (StudyEditor)fileEditor;
StudyUtils.drawAllWindows(studyEditor.getEditor(), taskFile);
}
}
}
@@ -82,7 +74,7 @@ public class StudyCheckUtils {
VirtualFile fileToNavigate = studyState.getVirtualFile();
final StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
if (!taskManager.hasFailedAnswerPlaceholders(selectedTaskFile)) {
for (Map.Entry<String, TaskFile> entry : StudyUtils.getTaskFiles(task).entrySet()) {
for (Map.Entry<String, TaskFile> entry : task.getTaskFiles().entrySet()) {
String name = entry.getKey();
TaskFile taskFile = entry.getValue();
if (taskManager.hasFailedAnswerPlaceholders(taskFile)) {
@@ -186,7 +178,7 @@ public class StudyCheckUtils {
public static void flushWindows(@NotNull final Task task, @NotNull final VirtualFile taskDir) {
for (Map.Entry<String, TaskFile> entry : StudyUtils.getTaskFiles(task).entrySet()) {
for (Map.Entry<String, TaskFile> entry : task.getTaskFiles().entrySet()) {
String name = entry.getKey();
TaskFile taskFile = entry.getValue();
VirtualFile virtualFile = taskDir.findChild(name);
@@ -6,8 +6,6 @@ import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.impl.event.DocumentEventImpl;
import com.intellij.openapi.util.TextRange;
import com.jetbrains.edu.learning.courseFormat.AnswerPlaceholder;
import com.jetbrains.edu.learning.courseFormat.Step;
import com.jetbrains.edu.learning.courseFormat.Task;
import com.jetbrains.edu.learning.courseFormat.TaskFile;
import java.util.ArrayList;
@@ -40,7 +38,7 @@ public class EduDocumentListener extends DocumentAdapter {
}
myTaskFile.setHighlightErrors(true);
myAnswerPlaceholders.clear();
for (AnswerPlaceholder answerPlaceholder : getAllPlaceholders()) {
for (AnswerPlaceholder answerPlaceholder : myTaskFile.getAnswerPlaceholders()) {
int twStart = answerPlaceholder.getOffset();
int length = answerPlaceholder.getRealLength();
int twEnd = twStart + length;
@@ -48,28 +46,6 @@ public class EduDocumentListener extends DocumentAdapter {
}
}
private List<AnswerPlaceholder> getAllPlaceholders() {
Task task = myTaskFile.getTask();
if (task == null || task.getAdditionalSteps().isEmpty()) {
return myTaskFile.getAnswerPlaceholders();
}
List<AnswerPlaceholder> placeholders = new ArrayList<>();
String name = myTaskFile.name;
TaskFile initialStepTaskFile = task.getTaskFile(name);
if (initialStepTaskFile == null) {
return placeholders;
}
placeholders.addAll(initialStepTaskFile.getAnswerPlaceholders());
for (Step step : task.getAdditionalSteps()) {
TaskFile stepTaskFile = step.getTaskFiles().get(name);
if (stepTaskFile == null) {
continue;
}
placeholders.addAll(stepTaskFile.getAnswerPlaceholders());
}
return placeholders;
}
@Override
public void documentChanged(DocumentEvent e) {
if (!myTaskFile.isTrackChanges()) {
@@ -47,11 +47,8 @@ public class EduNames {
public static final String ADAPTIVE = "Adaptive";
public static final String ANSWER_PLACEHOLDER = "Answer Placeholder";
public static final String PLACEHOLDER = "placeholder";
public static final String SRC = "src";
public static final String STEP_MARKER = "_step";
public static final String STEP = "step";
private EduNames() {
}
@@ -129,7 +129,6 @@ public class EduUtils {
public static Pair<VirtualFile, TaskFile> createStudentFile(Object requestor,
Project project,
VirtualFile answerFile,
int stepIndex,
VirtualFile parentDir,
@Nullable Task task) {
@@ -148,42 +147,18 @@ public class EduUtils {
}
task = task.copy();
}
Map<Integer, TaskFile> taskFileSteps = getTaskFileSteps(task, answerFile.getName());
TaskFile initialTaskFile = taskFileSteps.get(-1);
if (initialTaskFile == null) {
TaskFile taskFile = task.getTaskFile(answerFile.getName());
if (taskFile == null) {
return null;
}
EduDocumentListener listener = new EduDocumentListener(initialTaskFile, false);
EduDocumentListener listener = new EduDocumentListener(taskFile, false);
studentDocument.addDocumentListener(listener);
Pair<VirtualFile, TaskFile> result = null;
for (Map.Entry<Integer, TaskFile> entry : taskFileSteps.entrySet()) {
Integer index = entry.getKey();
if (index < stepIndex) {
continue;
}
TaskFile stepTaskFile = entry.getValue();
if (index == stepIndex) {
result = Pair.createNonNull(studentFile, stepTaskFile);
}
for (AnswerPlaceholder placeholder : stepTaskFile.getAnswerPlaceholders()) {
replaceAnswerPlaceholder(project, studentDocument, placeholder);
}
for (AnswerPlaceholder placeholder : taskFile.getAnswerPlaceholders()) {
replaceAnswerPlaceholder(project, studentDocument, placeholder);
}
studentDocument.removeDocumentListener(listener);
return result;
}
public static Map<Integer, TaskFile> getTaskFileSteps(Task task, String name) {
Map<Integer, TaskFile> files = new HashMap<>();
files.put( -1, task.getTaskFile(name));
List<Step> additionalSteps = task.getAdditionalSteps();
if (!additionalSteps.isEmpty()) {
for (int i = 0; i < additionalSteps.size(); i++) {
files.put(i, additionalSteps.get(i).getTaskFiles().get(name));
}
}
return files;
return Pair.create(studentFile, taskFile);
}
private static void replaceAnswerPlaceholder(@NotNull final Project project,
@@ -198,7 +173,7 @@ public class EduUtils {
}
public static void deleteWindowDescriptions(@NotNull final Task task, @NotNull final VirtualFile taskDir) {
for (Map.Entry<String, TaskFile> entry : StudyUtils.getTaskFiles(task).entrySet()) {
for (Map.Entry<String, TaskFile> entry : task.getTaskFiles().entrySet()) {
String name = entry.getKey();
VirtualFile virtualFile = taskDir.findChild(name);
if (virtualFile == null) {
@@ -1,51 +0,0 @@
package com.jetbrains.edu.learning.courseFormat;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import com.intellij.util.containers.HashMap;
import java.io.Serializable;
import java.util.Map;
public class Step implements Serializable{
@SerializedName("task_files")
@Expose
private Map<String, TaskFile> myTaskFiles = new HashMap<>();
private String myText = "";
public Step() {
}
public Step(Task task) {
for (Map.Entry<String, TaskFile> entry : task.getTaskFiles().entrySet()) {
String name = entry.getKey();
TaskFile taskFile = new TaskFile();
taskFile.name = name;
taskFile.setTask(task);
myTaskFiles.put(name, taskFile);
}
}
public Map<String, TaskFile> getTaskFiles() {
return myTaskFiles;
}
public void setTaskFiles(Map<String, TaskFile> taskFiles) {
myTaskFiles = taskFiles;
}
public void init(Task task, boolean isRestarted) {
for (TaskFile file : myTaskFiles.values()) {
file.initTaskFile(task, isRestarted);
}
}
public String getText() {
return myText;
}
public void setText(String text) {
myText = text;
}
}
@@ -15,9 +15,7 @@ import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
@@ -42,11 +40,6 @@ public class Task implements StudyItem {
@Transient private Lesson myLesson;
@Expose
@SerializedName("additionalSteps")
private List<Step> myAdditionalSteps = new ArrayList<>();
private int myActiveStepIndex = -1;
public Task() {}
public Task(@NotNull final String name) {
@@ -64,9 +57,6 @@ public class Task implements StudyItem {
for (TaskFile taskFile : getTaskFiles().values()) {
taskFile.initTaskFile(this, isRestarted);
}
for (Step step : myAdditionalSteps) {
step.init(this, isRestarted);
}
}
public String getName() {
@@ -128,11 +118,7 @@ public class Task implements StudyItem {
@Nullable
public TaskFile getFile(@NotNull final String fileName) {
if (myActiveStepIndex == -1) {
return taskFiles.get(fileName);
}
Step step = myAdditionalSteps.get(myActiveStepIndex);
return step.getTaskFiles().get(fileName);
return taskFiles.get(fileName);
}
@Transient
@@ -164,7 +150,7 @@ public class Task implements StudyItem {
if (!StringUtil.isEmptyOrSpaces(text)) return text;
final VirtualFile taskDir = getTaskDir(project);
if (taskDir != null) {
final VirtualFile file = StudyUtils.findTaskDescriptionVirtualFile(project, taskDir);
final VirtualFile file = StudyUtils.findTaskDescriptionVirtualFile(taskDir);
if (file == null) return "";
final Document document = FileDocumentManager.getInstance().getDocument(file);
if (document != null) {
@@ -230,29 +216,13 @@ public class Task implements StudyItem {
public void setStatus(StudyStatus status) {
myStatus = status;
for (TaskFile taskFile : StudyUtils.getTaskFiles(this).values()) {
for (TaskFile taskFile : taskFiles.values()) {
for (AnswerPlaceholder placeholder : taskFile.getAnswerPlaceholders()) {
placeholder.setStatus(status);
}
}
}
public List<Step> getAdditionalSteps() {
return myAdditionalSteps;
}
public void setAdditionalSteps(List<Step> additionalSteps) {
myAdditionalSteps = additionalSteps;
}
public int getActiveStepIndex() {
return myActiveStepIndex;
}
public void setActiveStepIndex(int activeStepIndex) {
myActiveStepIndex = activeStepIndex;
}
public Task copy() {
Element element = XmlSerializer.serialize(this);
Task copy = XmlSerializer.deserialize(element, Task.class);
@@ -20,7 +20,6 @@ import com.jetbrains.edu.learning.core.EduDocumentListener;
import com.jetbrains.edu.learning.core.EduNames;
import com.jetbrains.edu.learning.courseFormat.AnswerPlaceholder;
import com.jetbrains.edu.learning.courseFormat.Course;
import com.jetbrains.edu.learning.courseFormat.Task;
import com.jetbrains.edu.learning.courseFormat.TaskFile;
import com.jetbrains.edu.learning.navigation.StudyNavigator;
import com.jetbrains.edu.learning.ui.StudyToolWindowFactory;
@@ -88,10 +87,6 @@ public class StudyEditorFactoryListener implements EditorFactoryListener {
editor.addEditorMouseListener(new WindowSelectionListener(taskFile));
}
}
Task task = taskFile.getTask();
if (!task.getAdditionalSteps().isEmpty()) {
StudyUtils.drawPlaceholdersFromOtherSteps(editor, taskFile, task);
}
}
}
}
@@ -108,38 +108,24 @@ public class StudyDirectoryNode extends PsiDirectoryNode {
protected void setStudyAttributes(Task task, PresentationData data, String name) {
StudyStatus taskStatus = task.getStatus();
String additionalInfo = task.getAdditionalSteps().isEmpty() ? null : getStepInfo(task);
switch (taskStatus) {
case Unchecked: {
updatePresentation(data, name, JBColor.BLACK, InteractiveLearningIcons.Task, additionalInfo);
updatePresentation(data, name, JBColor.BLACK, InteractiveLearningIcons.Task);
break;
}
case Solved: {
updatePresentation(data, name, LIGHT_GREEN, InteractiveLearningIcons.TaskCompl, additionalInfo);
updatePresentation(data, name, LIGHT_GREEN, InteractiveLearningIcons.TaskCompl);
break;
}
case Failed: {
updatePresentation(data, name, JBColor.RED, InteractiveLearningIcons.TaskProbl, additionalInfo);
updatePresentation(data, name, JBColor.RED, InteractiveLearningIcons.TaskProbl);
}
}
}
private static String getStepInfo(Task task) {
int index = task.getActiveStepIndex() + 2;
int number = task.getAdditionalSteps().size() + 1;
return "step " + index + "/" + number;
}
protected static void updatePresentation(PresentationData data, String name, JBColor color, Icon icon) {
updatePresentation(data, name, color, icon, null);
}
protected static void updatePresentation(PresentationData data, String name, JBColor color, Icon icon, String additionalInfo) {
data.clearText();
data.addText(name, new SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, color));
if (additionalInfo != null) {
data.addText(" (" + additionalInfo + ")", SimpleTextAttributes.GRAYED_ATTRIBUTES);
}
data.setIcon(icon);
}
@@ -174,8 +160,7 @@ public class StudyDirectoryNode extends PsiDirectoryNode {
FileEditorManager.getInstance(myProject).closeFile(openFile);
}
VirtualFile child = null;
Map<String, TaskFile> taskFiles = StudyUtils.getTaskFiles(task);
for (Map.Entry<String, TaskFile> entry: taskFiles.entrySet()) {
for (Map.Entry<String, TaskFile> entry: task.getTaskFiles().entrySet()) {
VirtualFile file = taskDir.findChild(entry.getKey());
if (file != null) {
FileEditorManager.getInstance(myProject).openFile(file, true);
@@ -68,7 +68,7 @@ public class StepicWrappers {
assert ideaDir != null;
String name = entry.getKey();
VirtualFile answerFile = taskDir.findChild(name);
Pair<VirtualFile, TaskFile> pair = EduUtils.createStudentFile(StepicWrappers.class, project, answerFile, -1, ideaDir, null);
Pair<VirtualFile, TaskFile> pair = EduUtils.createStudentFile(StepicWrappers.class, project, answerFile, ideaDir, null);
if (pair == null) {
return;
}
@@ -211,12 +211,12 @@ public abstract class StudyToolWindow extends SimpleToolWindowPanel implements D
LOG.info("Failed to enter editing mode for StudyToolWindow");
return;
}
VirtualFile taskTextFile = StudyUtils.findTaskDescriptionVirtualFile(project, taskDirectory);
VirtualFile taskTextFile = StudyUtils.findTaskDescriptionVirtualFile(taskDirectory);
enterEditingMode(taskTextFile, project);
StudyTaskManager.getInstance(project).setTurnEditingMode(false);
}
if (taskDirectory != null && StudyTaskManager.getInstance(project).getToolWindowMode() == StudyToolWindowMode.EDITING) {
VirtualFile taskTextFile = StudyUtils.findTaskDescriptionVirtualFile(project, taskDirectory);
VirtualFile taskTextFile = StudyUtils.findTaskDescriptionVirtualFile(taskDirectory);
enterEditingMode(taskTextFile, project);
}
else {
@@ -2,26 +2,15 @@ package com.jetbrains.edu.coursecreator;
import com.intellij.ide.fileTemplates.FileTemplate;
import com.intellij.ide.fileTemplates.FileTemplateManager;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.DocumentUtil;
import com.jetbrains.edu.learning.StudyTaskManager;
import com.jetbrains.edu.learning.core.EduNames;
import com.jetbrains.edu.learning.courseFormat.Task;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
public class PyCCLanguageManager implements CCLanguageManager {
private static final Logger LOG = Logger.getInstance(PyCCLanguageManager.class);
@Nullable
@Override
@@ -56,63 +45,6 @@ public class PyCCLanguageManager implements CCLanguageManager {
@Override
public boolean isTestFile(VirtualFile file) {
String name = file.getName();
if (EduNames.TESTS_FILE.equals(name)) {
return true;
}
return name.contains(FileUtil.getNameWithoutExtension(EduNames.TESTS_FILE)) && name.contains(EduNames.STEP_MARKER);
return EduNames.TESTS_FILE.equals(file.getName());
}
@Override
public void createTestsForNewStep(@NotNull Project project, @NotNull Task task) {
VirtualFile taskDir = task.getTaskDir(project);
if (taskDir == null) {
return;
}
int prevStepIndex = task.getActiveStepIndex();
String name = prevStepIndex == -1 ? EduNames.TESTS_FILE : getStepTestsFileName(prevStepIndex);
VirtualFile testsFile = taskDir.findChild(name);
if (testsFile == null) {
return;
}
Document document = FileDocumentManager.getInstance().getDocument(testsFile);
if (document == null) {
return;
}
CharSequence prevTestText = document.getCharsSequence();
String nextStepTestsFileName = getStepTestsFileName(prevStepIndex + 1);
ApplicationManager.getApplication().runWriteAction(() -> {
try {
VirtualFile nextStepTestsFile = taskDir.createChildData(this, nextStepTestsFileName);
StudyTaskManager.getInstance(project).addInvisibleFiles(nextStepTestsFile.getPath());
Document nextStepDocument = FileDocumentManager.getInstance().getDocument(nextStepTestsFile);
if (nextStepDocument == null) {
return;
}
int index = prevStepIndex + 2;
//TODO: text for header
String header = "# This is test for step " + index + ". We've already copied tests from previous step here.\n\n";
DocumentUtil.writeInRunUndoTransparentAction(() -> {
nextStepDocument.insertString(0, header);
nextStepDocument.insertString(header.length(), prevTestText);
FileDocumentManager.getInstance().saveDocument(nextStepDocument);
});
}
catch (IOException e) {
LOG.error(e);
}
});
}
@NotNull
public static String getStepTestsFileName(int index) {
if (index == -1) {
return EduNames.TESTS_FILE;
}
return FileUtil.getNameWithoutExtension(EduNames.TESTS_FILE) +
EduNames.STEP_MARKER +
index + "." +
FileUtilRt.getExtension(EduNames.TESTS_FILE);
}
}
@@ -10,7 +10,6 @@ import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.jetbrains.edu.coursecreator.CCUtils;
import com.jetbrains.edu.coursecreator.PyCCLanguageManager;
import com.jetbrains.edu.learning.StudyUtils;
import com.jetbrains.edu.learning.core.EduNames;
import com.jetbrains.edu.learning.courseFormat.Task;
@@ -82,7 +81,7 @@ public class PyCCRunTestsConfigurationProducer extends RunConfigurationProducer<
if (task == null) {
return null;
}
String testsFileName = PyCCLanguageManager.getStepTestsFileName(task.getActiveStepIndex());
String testsFileName = EduNames.TESTS_FILE;
String taskDirPath = FileUtil.toSystemDependentName(taskDir.getPath());
String testsPath = taskDir.findChild(EduNames.SRC) != null ?
FileUtil.join(taskDirPath, EduNames.SRC, testsFileName) :
@@ -98,8 +98,7 @@ public class PyStudyCheckAction extends StudyCheckAction {
ApplicationManager.getApplication().invokeLater(() -> {
if (myTaskDir == null) return;
myTask.setStatus(StudyStatus.Failed);
Map<String, TaskFile> taskFiles = StudyUtils.getTaskFiles(myTask);
for (Map.Entry<String, TaskFile> entry : taskFiles.entrySet()) {
for (Map.Entry<String, TaskFile> entry : myTask.getTaskFiles().entrySet()) {
final String name = entry.getKey();
final TaskFile taskFile = entry.getValue();
if (taskFile.getAnswerPlaceholders().size() < 2) {
@@ -7,10 +7,8 @@ import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.vfs.VirtualFile;
import com.jetbrains.edu.learning.checker.StudyTestRunner;
import com.jetbrains.edu.learning.core.EduNames;
import com.jetbrains.edu.learning.courseFormat.Course;
import com.jetbrains.edu.learning.courseFormat.Task;
import com.jetbrains.python.sdk.PythonSdkType;
@@ -37,10 +35,6 @@ public class PyStudyTestRunner extends StudyTestRunner {
}
String testsFileName = manager.getTestFileName();
int activeStepIndex = myTask.getActiveStepIndex();
if (activeStepIndex != -1) {
testsFileName = FileUtil.getNameWithoutExtension(testsFileName) + EduNames.STEP_MARKER + activeStepIndex + "." + FileUtilRt.getExtension(testsFileName);
}
final File testRunner = new File(myTaskDir.getPath(), testsFileName);
final GeneralCommandLine commandLine = new GeneralCommandLine();
commandLine.withWorkDirectory(myTaskDir.getPath());