EDU-555 Add As Task File action should be undoable and revertable
authorLiana Bakradze <liana.bakradze@jetbrains.com>
Fri, 5 Aug 2016 16:41:03 +0000 (19:41 +0300)
committerLiana Bakradze <liana.bakradze@jetbrains.com>
Fri, 5 Aug 2016 16:45:17 +0000 (19:45 +0300)
python/educational-core/course-creator/resources/META-INF/plugin.xml
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCAddAsTaskFile.java
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCHideFromStudent.java
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCTaskFileActionBase.java

index b46da939f1b4a568ffee11ff2d02fe7dbaed0fcf..7ba0e8107a8894569d8394f817ceee8581af83a8 100644 (file)
@@ -56,8 +56,8 @@
     <action id="ChangeCourseInfo" class="com.jetbrains.edu.coursecreator.actions.CCChangeCourseInfo"/>
 
     <group id="CCProjectViewGroup" popup="true" text="Course Creator" class="com.jetbrains.edu.coursecreator.actions.CCProjectViewActionGroup">
     <action id="ChangeCourseInfo" class="com.jetbrains.edu.coursecreator.actions.CCChangeCourseInfo"/>
 
     <group id="CCProjectViewGroup" popup="true" text="Course Creator" class="com.jetbrains.edu.coursecreator.actions.CCProjectViewActionGroup">
-      <action id="AddTaskFile" class="com.jetbrains.edu.coursecreator.actions.CCAddAsTaskFile" text="Make Visible to Student"/>
-      <action id="HideTaskFile" class="com.jetbrains.edu.coursecreator.actions.CCHideFromStudent" text="Hide from Student"/>
+      <action id="AddTaskFile" class="com.jetbrains.edu.coursecreator.actions.CCAddAsTaskFile"/>
+      <action id="HideTaskFile" class="com.jetbrains.edu.coursecreator.actions.CCHideFromStudent"/>
       <action id="ShowPreview" class="com.jetbrains.edu.coursecreator.actions.CCShowPreview">
         <add-to-group group-id="EditorTabPopupMenu"/>
       </action>
       <action id="ShowPreview" class="com.jetbrains.edu.coursecreator.actions.CCShowPreview">
         <add-to-group group-id="EditorTabPopupMenu"/>
       </action>
index c62bd5e1e069935658d820f8a6e93e5e4547e6df..f98a0223f4511e11d9f8533e9e5ff9cc39207d71 100644 (file)
@@ -1,20 +1,77 @@
 package com.jetbrains.edu.coursecreator.actions;
 
 package com.jetbrains.edu.coursecreator.actions;
 
+import com.intellij.ide.projectView.ProjectView;
+import com.intellij.openapi.command.undo.DocumentReference;
+import com.intellij.openapi.command.undo.UndoableAction;
+import com.intellij.openapi.command.undo.UnexpectedUndoException;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.jetbrains.edu.coursecreator.CCUtils;
 import com.jetbrains.edu.learning.StudyUtils;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.jetbrains.edu.coursecreator.CCUtils;
 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.Task;
 import com.jetbrains.edu.learning.courseFormat.Course;
 import com.jetbrains.edu.learning.courseFormat.Task;
+import com.jetbrains.edu.learning.courseFormat.TaskFile;
+import org.jetbrains.annotations.Nullable;
 
 public class CCAddAsTaskFile extends CCTaskFileActionBase {
 
 public class CCAddAsTaskFile extends CCTaskFileActionBase {
+  public static final String ACTION_NAME = "Make Visible to Student";
+
+  public CCAddAsTaskFile() {
+    super(ACTION_NAME);
+  }
+
 
   protected void performAction(VirtualFile file, Task task, Course course, Project project) {
 
   protected void performAction(VirtualFile file, Task task, Course course, Project project) {
-    task.addTaskFile(file.getName(), task.getTaskFiles().size());
-    CCUtils.createResourceFile(file, course, StudyUtils.getTaskDir(file));
+    EduUtils.runUndoableAction(project, ACTION_NAME, new AddTaskFile(file, null, course, project, task));
   }
 
   protected boolean isAvailable(Project project, VirtualFile file) {
     return StudyUtils.getTaskFile(project, file) == null && !CCUtils.isTestsFile(project, file);
   }
   }
 
   protected boolean isAvailable(Project project, VirtualFile file) {
     return StudyUtils.getTaskFile(project, file) == null && !CCUtils.isTestsFile(project, file);
   }
+
+  private static class AddTaskFile implements UndoableAction {
+    private final VirtualFile myFile;
+    private TaskFile myTaskFile;
+    private final Course myCourse;
+    private final Project myProject;
+    private final Task myTask;
+
+    public AddTaskFile(VirtualFile file, TaskFile taskFile, Course course, Project project, Task task) {
+      myFile = file;
+      myTaskFile = taskFile;
+      myCourse = course;
+      myProject = project;
+      myTask = task;
+    }
+
+    @Override
+    public void undo() throws UnexpectedUndoException {
+      CCHideFromStudent.hideFromStudent(myFile, myProject, myTask.getTaskFiles(), myTaskFile);
+      ProjectView.getInstance(myProject).refresh();
+    }
+
+    @Override
+    public void redo() throws UnexpectedUndoException {
+      if (myTaskFile != null) {
+        myTask.addTaskFile(myTaskFile);
+      } else {
+        myTask.addTaskFile(myFile.getName(), myTask.getTaskFiles().size());
+        myTaskFile = myTask.getTaskFile(myFile.getName());
+      }
+      CCUtils.createResourceFile(myFile, myCourse, StudyUtils.getTaskDir(myFile));
+      ProjectView.getInstance(myProject).refresh();
+    }
+
+    @Nullable
+    @Override
+    public DocumentReference[] getAffectedDocuments() {
+      return new DocumentReference[0];
+    }
+
+    @Override
+    public boolean isGlobal() {
+      return true;
+    }
+  }
 }
 }
index f794e69d0ea21bd2c45e182c206ca19e5cf37f98..3ce85b39d7f8d81cbc04dc66080df4d5f4f89765 100644 (file)
@@ -1,6 +1,10 @@
 package com.jetbrains.edu.coursecreator.actions;
 
 package com.jetbrains.edu.coursecreator.actions;
 
+import com.intellij.ide.projectView.ProjectView;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.command.undo.DocumentReference;
+import com.intellij.openapi.command.undo.UndoableAction;
+import com.intellij.openapi.command.undo.UnexpectedUndoException;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.fileEditor.FileEditor;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.fileEditor.FileEditor;
@@ -8,10 +12,13 @@ import com.intellij.openapi.fileEditor.FileEditorManager;
 import com.intellij.openapi.fileEditor.impl.text.PsiAwareTextEditorImpl;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.openapi.fileEditor.impl.text.PsiAwareTextEditorImpl;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.vfs.VirtualFile;
+import com.jetbrains.edu.coursecreator.CCUtils;
 import com.jetbrains.edu.learning.StudyUtils;
 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.Task;
 import com.jetbrains.edu.learning.courseFormat.TaskFile;
 import com.jetbrains.edu.learning.courseFormat.Course;
 import com.jetbrains.edu.learning.courseFormat.Task;
 import com.jetbrains.edu.learning.courseFormat.TaskFile;
+import org.jetbrains.annotations.Nullable;
 
 import java.io.IOException;
 import java.util.Map;
 
 import java.io.IOException;
 import java.util.Map;
@@ -19,14 +26,71 @@ import java.util.Map;
 public class CCHideFromStudent extends CCTaskFileActionBase {
 
   private static final Logger LOG = Logger.getInstance(CCHideFromStudent.class);
 public class CCHideFromStudent extends CCTaskFileActionBase {
 
   private static final Logger LOG = Logger.getInstance(CCHideFromStudent.class);
+  private static final String ACTION_NAME = "Hide from Student";
+
+  public CCHideFromStudent() {
+    super(ACTION_NAME);
+  }
 
   @Override
   protected void performAction(VirtualFile file, Task task, Course course, Project project) {
 
   @Override
   protected void performAction(VirtualFile file, Task task, Course course, Project project) {
-    Map<String, TaskFile> taskFiles = task.getTaskFiles();
     TaskFile taskFile = StudyUtils.getTaskFile(project, file);
     if (taskFile == null) {
       return;
     }
     TaskFile taskFile = StudyUtils.getTaskFile(project, file);
     if (taskFile == null) {
       return;
     }
+    EduUtils.runUndoableAction(project, ACTION_NAME, new HideTaskFile(project, course, file, task, taskFile));
+  }
+
+  private static class HideTaskFile implements UndoableAction {
+
+    private final Project myProject;
+    private final Course myCourse;
+    private final VirtualFile myFile;
+    private final Task myTask;
+    private final TaskFile myTaskFile;
+
+    public HideTaskFile(Project project, Course course, VirtualFile file, Task task, TaskFile taskFile) {
+      myProject = project;
+      myCourse = course;
+      myFile = file;
+      myTask = task;
+      myTaskFile = taskFile;
+    }
+
+    @Override
+    public void undo() throws UnexpectedUndoException {
+      myTask.getTaskFiles().put(myFile.getName(), myTaskFile);
+      CCUtils.createResourceFile(myFile, myCourse, StudyUtils.getTaskDir(myFile));
+      if (!myTaskFile.getAnswerPlaceholders().isEmpty() && FileEditorManager.getInstance(myProject).isFileOpen(myFile)) {
+        for (FileEditor fileEditor : FileEditorManager.getInstance(myProject).getEditors(myFile)) {
+          if (fileEditor instanceof PsiAwareTextEditorImpl) {
+            Editor editor = ((PsiAwareTextEditorImpl)fileEditor).getEditor();
+            StudyUtils.drawAllWindows(editor, myTaskFile);
+          }
+        }
+      }
+      ProjectView.getInstance(myProject).refresh();
+    }
+
+    @Override
+    public void redo() throws UnexpectedUndoException {
+      hideFromStudent(myFile, myProject, myTask.getTaskFiles(), myTaskFile);
+      ProjectView.getInstance(myProject).refresh();
+    }
+
+    @Nullable
+    @Override
+    public DocumentReference[] getAffectedDocuments() {
+      return new DocumentReference[0];
+    }
+
+    @Override
+    public boolean isGlobal() {
+      return true;
+    }
+  }
+
+  public static void hideFromStudent(VirtualFile file, Project project, Map<String, TaskFile> taskFiles, TaskFile taskFile) {
     if (!taskFile.getAnswerPlaceholders().isEmpty() && FileEditorManager.getInstance(project).isFileOpen(file)) {
       for (FileEditor fileEditor : FileEditorManager.getInstance(project).getEditors(file)) {
         if (fileEditor instanceof PsiAwareTextEditorImpl) {
     if (!taskFile.getAnswerPlaceholders().isEmpty() && FileEditorManager.getInstance(project).isFileOpen(file)) {
       for (FileEditor fileEditor : FileEditorManager.getInstance(project).getEditors(file)) {
         if (fileEditor instanceof PsiAwareTextEditorImpl) {
index 4f0632e82ee8cb45049188676622711a393e139c..649db137a19a4e1d53e8b8146c27bb04de674279 100644 (file)
@@ -1,6 +1,5 @@
 package com.jetbrains.edu.coursecreator.actions;
 
 package com.jetbrains.edu.coursecreator.actions;
 
-import com.intellij.ide.projectView.ProjectView;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.actionSystem.CommonDataKeys;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.actionSystem.CommonDataKeys;
@@ -12,8 +11,12 @@ import com.jetbrains.edu.learning.StudyTaskManager;
 import com.jetbrains.edu.learning.StudyUtils;
 import com.jetbrains.edu.learning.courseFormat.Course;
 import com.jetbrains.edu.learning.courseFormat.Task;
 import com.jetbrains.edu.learning.StudyUtils;
 import com.jetbrains.edu.learning.courseFormat.Course;
 import com.jetbrains.edu.learning.courseFormat.Task;
+import org.jetbrains.annotations.Nullable;
 
 public abstract class CCTaskFileActionBase extends AnAction {
 
 public abstract class CCTaskFileActionBase extends AnAction {
+  public CCTaskFileActionBase(@Nullable String text) {
+    super(text);
+  }
 
   @Override
   public void actionPerformed(final AnActionEvent e) {
 
   @Override
   public void actionPerformed(final AnActionEvent e) {
@@ -35,7 +38,6 @@ public abstract class CCTaskFileActionBase extends AnAction {
     }
     Course course = StudyTaskManager.getInstance(project).getCourse();
     performAction(file, task, course, project);
     }
     Course course = StudyTaskManager.getInstance(project).getCourse();
     performAction(file, task, course, project);
-    ProjectView.getInstance(project).refresh();
   }
 
   protected abstract void performAction(VirtualFile file, Task task, Course course, Project project);
   }
 
   protected abstract void performAction(VirtualFile file, Task task, Course course, Project project);