part of EDU-331(improving lesson and task management)
[idea/community.git] / python / educational / course-creator / src / com / jetbrains / edu / coursecreator / actions / CCCreateLesson.java
1 package com.jetbrains.edu.coursecreator.actions;
2
3 import com.intellij.ide.IdeView;
4 import com.intellij.ide.util.DirectoryChooserUtil;
5 import com.intellij.ide.util.DirectoryUtil;
6 import com.intellij.openapi.actionSystem.AnActionEvent;
7 import com.intellij.openapi.actionSystem.CommonDataKeys;
8 import com.intellij.openapi.actionSystem.LangDataKeys;
9 import com.intellij.openapi.application.ApplicationManager;
10 import com.intellij.openapi.diagnostic.Logger;
11 import com.intellij.openapi.project.DumbAwareAction;
12 import com.intellij.openapi.project.Project;
13 import com.intellij.openapi.ui.Messages;
14 import com.intellij.openapi.vfs.VirtualFile;
15 import com.intellij.psi.PsiDirectory;
16 import com.intellij.util.PlatformIcons;
17 import com.jetbrains.edu.coursecreator.CCProjectService;
18 import com.jetbrains.edu.coursecreator.CCUtils;
19 import com.jetbrains.edu.coursecreator.format.Course;
20 import com.jetbrains.edu.coursecreator.format.Lesson;
21 import org.jetbrains.annotations.NotNull;
22 import org.jetbrains.annotations.Nullable;
23
24 import java.io.IOException;
25 import java.util.List;
26
27 public class CCCreateLesson extends DumbAwareAction {
28   private static final Logger LOG = Logger.getInstance(CCCreateLesson.class.getName());
29
30   public CCCreateLesson() {
31     super("Lesson", "Create new Lesson", PlatformIcons.DIRECTORY_CLOSED_ICON);
32   }
33
34   @Override
35   public void actionPerformed(AnActionEvent e) {
36     final IdeView view = e.getData(LangDataKeys.IDE_VIEW);
37     final Project project = e.getData(CommonDataKeys.PROJECT);
38     if (view == null || project == null) {
39       return;
40     }
41     final PsiDirectory directory = DirectoryChooserUtil.getOrChooseDirectory(view);
42     if (directory == null) return;
43     final String lessonDirName = "lesson";
44     final CCProjectService service = CCProjectService.getInstance(project);
45     final Course course = service.getCourse();
46     if (course == null) {
47       return;
48     }
49     //"Create Lesson" invoked from project root creates new lesson as last lesson
50     if (directory.getVirtualFile().equals(project.getBaseDir())) {
51       final int size = course.getLessons().size();
52       createLesson(directory, size + 1, view, course);
53       return;
54     }
55     //"Create Lesson" invoked from any of lesson directories creates new lesson as next lesson
56     Lesson lesson = course.getLesson(directory.getName());
57     if (lesson != null) {
58       int index = lesson.getIndex();
59       List<Lesson> lessons = course.getLessons();
60       int lessonNum = lessons.size();
61       for (int i = lessonNum; i >= index + 1; i--) {
62         updateLesson(project, lessonDirName, course, i);
63       }
64       final PsiDirectory parent = directory.getParent();
65       if (parent == null) {
66         return;
67       }
68       createLesson(parent, index + 1, view, course);
69       course.init();
70     }
71   }
72
73   private static void createLesson(@NotNull final PsiDirectory projectDir,
74                                    final int index,
75                                    final IdeView view,
76                                    @NotNull final Course course) {
77     final String lessonName = Messages.showInputDialog("Name:", "Lesson Name", null, "lesson" + index, null);
78     if (lessonName == null) {
79       return;
80     }
81     ApplicationManager.getApplication().runWriteAction(new Runnable() {
82       @Override
83       public void run() {
84         createLessonDir(projectDir, index, lessonName, view, course);
85       }
86     });
87   }
88
89   private void updateLesson(@NotNull final Project project, final String lessonDirName, @NotNull final Course course, int i) {
90     final VirtualFile lessonDir = project.getBaseDir().findChild(lessonDirName + i);
91     if (lessonDir == null) {
92       return;
93     }
94     Lesson l = course.getLesson(lessonDir.getName());
95     if (l == null) {
96       return;
97     }
98     l.setIndex(l.getIndex() + 1);
99     final int next = i + 1;
100     ApplicationManager.getApplication().runWriteAction(new Runnable() {
101       @Override
102       public void run() {
103         try {
104           lessonDir.rename(this, lessonDirName + next);
105         }
106         catch (IOException e1) {
107           LOG.error(e1);
108         }
109       }
110     });
111     course.getLessonsMap().put(lessonDir.getName(), l);
112   }
113
114   @Nullable
115   public static PsiDirectory createLessonDir(@NotNull final PsiDirectory projectDir, int index, String name, final IdeView view,
116                                              @NotNull final Course course) {
117     String lessonFolderName = "lesson" + index;
118     final PsiDirectory lessonDirectory = DirectoryUtil.createSubdirectories("lesson" + index, projectDir, "\\/");
119     if (lessonDirectory != null) {
120       if (view != null) {
121         view.selectElement(lessonDirectory);
122       }
123       final Lesson lesson = new Lesson(name != null ? name : lessonFolderName);
124       lesson.setIndex(index);
125       course.addLesson(lesson, lessonDirectory);
126     }
127     return lessonDirectory;
128   }
129
130   @Override
131   public void update(@NotNull AnActionEvent event) {
132     if (!CCProjectService.setCCActionAvailable(event)) {
133       return;
134     }
135     final Project project = event.getData(CommonDataKeys.PROJECT);
136     final IdeView view = event.getData(LangDataKeys.IDE_VIEW);
137     if (project == null || view == null) {
138       CCUtils.enableAction(event, false);
139       return;
140     }
141     final PsiDirectory[] directories = view.getDirectories();
142     if (directories.length == 0) {
143       CCUtils.enableAction(event, false);
144       return;
145     }
146     final PsiDirectory directory = DirectoryChooserUtil.getOrChooseDirectory(view);
147     if (directory != null && project.getBaseDir().equals(directory.getVirtualFile())) {
148       CCUtils.enableAction(event, true);
149       return;
150     }
151     Course course = CCProjectService.getInstance(project).getCourse();
152     if (directory != null && course != null && course.getLesson(directory.getName()) != null) {
153       CCUtils.enableAction(event, true);
154       return;
155     }
156     CCUtils.enableAction(event, false);
157   }
158 }