diff options
Diffstat (limited to 'python/edu/learn-python/src/com/jetbrains/python/edu/StudyTaskManager.java')
-rw-r--r-- | python/edu/learn-python/src/com/jetbrains/python/edu/StudyTaskManager.java | 296 |
1 files changed, 296 insertions, 0 deletions
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyTaskManager.java b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyTaskManager.java new file mode 100644 index 000000000000..213c1f7601f0 --- /dev/null +++ b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyTaskManager.java @@ -0,0 +1,296 @@ +package com.jetbrains.python.edu; + +import com.intellij.ide.ui.UISettings; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.AnActionListener; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.*; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.keymap.Keymap; +import com.intellij.openapi.keymap.KeymapManager; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.DumbAwareRunnable; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileAdapter; +import com.intellij.openapi.vfs.VirtualFileEvent; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.openapi.wm.*; +import com.intellij.util.xmlb.XmlSerializer; +import com.jetbrains.python.edu.actions.StudyNextWindowAction; +import com.jetbrains.python.edu.actions.StudyPrevWindowAction; +import com.jetbrains.python.edu.actions.StudyShowHintAction; +import com.jetbrains.python.edu.course.Course; +import com.jetbrains.python.edu.course.Lesson; +import com.jetbrains.python.edu.course.Task; +import com.jetbrains.python.edu.course.TaskFile; +import com.jetbrains.python.edu.ui.StudyCondition; +import com.jetbrains.python.edu.ui.StudyToolWindowFactory; +import org.jdom.Element; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Implementation of class which contains all the information + * about study in context of current project + */ + +@State( + name = "StudySettings", + storages = { + @Storage( + id = "others", + file = "$PROJECT_CONFIG_DIR$/study_project.xml", + scheme = StorageScheme.DIRECTORY_BASED + )} +) +public class StudyTaskManager implements ProjectComponent, PersistentStateComponent<Element>, DumbAware { + public static final String COURSE_ELEMENT = "courseElement"; + private static Map<String, StudyTaskManager> myTaskManagers = new HashMap<String, StudyTaskManager>(); + private static Map<String, String> myDeletedShortcuts = new HashMap<String, String>(); + private final Project myProject; + private Course myCourse; + private FileCreatedListener myListener; + + + public void setCourse(Course course) { + myCourse = course; + } + + private StudyTaskManager(@NotNull final Project project) { + myTaskManagers.put(project.getBasePath(), this); + myProject = project; + } + + + @Nullable + public Course getCourse() { + return myCourse; + } + + @Nullable + @Override + public Element getState() { + Element el = new Element("taskManager"); + if (myCourse != null) { + Element courseElement = new Element(COURSE_ELEMENT); + XmlSerializer.serializeInto(myCourse, courseElement); + el.addContent(courseElement); + } + return el; + } + + @Override + public void loadState(Element el) { + myCourse = XmlSerializer.deserialize(el.getChild(COURSE_ELEMENT), Course.class); + if (myCourse != null) { + myCourse.init(true); + } + } + + @Override + public void projectOpened() { + ApplicationManager.getApplication().invokeLater(new DumbAwareRunnable() { + @Override + public void run() { + ApplicationManager.getApplication().runWriteAction(new DumbAwareRunnable() { + @Override + public void run() { + if (myCourse != null) { + StartupManager.getInstance(myProject).runWhenProjectIsInitialized(new Runnable() { + @Override + public void run() { + ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PROJECT_VIEW).show(null); + FileEditor[] editors = FileEditorManager.getInstance(myProject).getSelectedEditors(); + if (editors.length > 0) { + JComponent focusedComponent = editors[0].getPreferredFocusedComponent(); + if (focusedComponent != null) { + IdeFocusManager.getInstance(myProject).requestFocus(focusedComponent, true); + } + } + } + }); + UISettings.getInstance().HIDE_TOOL_STRIPES = false; + UISettings.getInstance().fireUISettingsChanged(); + ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(myProject); + String toolWindowId = StudyToolWindowFactory.STUDY_TOOL_WINDOW; + //TODO:decide smth with tool window position + try { + Method method = toolWindowManager.getClass().getDeclaredMethod("registerToolWindow", String.class, + JComponent.class, + ToolWindowAnchor.class, + boolean.class, boolean.class, boolean.class); + method.setAccessible(true); + method.invoke(toolWindowManager, toolWindowId, null, ToolWindowAnchor.LEFT, true, true, true); + } + catch (Exception e) { + final ToolWindow toolWindow = toolWindowManager.getToolWindow(toolWindowId); + if (toolWindow == null) + toolWindowManager.registerToolWindow(toolWindowId, true, ToolWindowAnchor.RIGHT, myProject, true); + } + + final ToolWindow studyToolWindow = toolWindowManager.getToolWindow(toolWindowId); + if (studyToolWindow != null) { + StudyUtils.updateStudyToolWindow(myProject); + studyToolWindow.show(null); + } + addShortcut(StudyNextWindowAction.SHORTCUT, StudyNextWindowAction.ACTION_ID); + addShortcut(StudyPrevWindowAction.SHORTCUT, StudyPrevWindowAction.ACTION_ID); + addShortcut(StudyShowHintAction.SHORTCUT, StudyShowHintAction.ACTION_ID); + addShortcut(StudyNextWindowAction.SHORTCUT2, StudyNextWindowAction.ACTION_ID); + } + } + }); + } + }); + } + + + private static void addShortcut(@NotNull final String shortcutString, @NotNull final String actionIdString) { + Keymap keymap = KeymapManager.getInstance().getActiveKeymap(); + Shortcut studyActionShortcut = new KeyboardShortcut(KeyStroke.getKeyStroke(shortcutString), null); + String[] actionsIds = keymap.getActionIds(studyActionShortcut); + for (String actionId : actionsIds) { + myDeletedShortcuts.put(actionId, shortcutString); + keymap.removeShortcut(actionId, studyActionShortcut); + } + keymap.addShortcut(actionIdString, studyActionShortcut); + } + + @Override + public void projectClosed() { + StudyCondition.VALUE = false; + if (myCourse != null) { + ToolWindowManager.getInstance(myProject).getToolWindow(StudyToolWindowFactory.STUDY_TOOL_WINDOW).getContentManager() + .removeAllContents(false); + if (!myDeletedShortcuts.isEmpty()) { + for (Map.Entry<String, String> shortcut : myDeletedShortcuts.entrySet()) { + Keymap keymap = KeymapManager.getInstance().getActiveKeymap(); + Shortcut actionShortcut = new KeyboardShortcut(KeyStroke.getKeyStroke(shortcut.getValue()), null); + keymap.addShortcut(shortcut.getKey(), actionShortcut); + } + } + } + } + + @Override + public void initComponent() { + EditorFactory.getInstance().addEditorFactoryListener(new StudyEditorFactoryListener(), myProject); + ActionManager.getInstance().addAnActionListener(new AnActionListener() { + @Override + public void beforeActionPerformed(AnAction action, DataContext dataContext, AnActionEvent event) { + AnAction[] newGroupActions = ((ActionGroup)ActionManager.getInstance().getAction("NewGroup")).getChildren(null); + for (AnAction newAction : newGroupActions) { + if (newAction == action) { + myListener = new FileCreatedListener(); + VirtualFileManager.getInstance().addVirtualFileListener(myListener); + break; + } + } + } + + @Override + public void afterActionPerformed(AnAction action, DataContext dataContext, AnActionEvent event) { + AnAction[] newGroupActions = ((ActionGroup)ActionManager.getInstance().getAction("NewGroup")).getChildren(null); + for (AnAction newAction : newGroupActions) { + if (newAction == action) { + VirtualFileManager.getInstance().removeVirtualFileListener(myListener); + } + } + } + + @Override + public void beforeEditorTyping(char c, DataContext dataContext) { + + } + }); + } + + @Override + public void disposeComponent() { + } + + @NotNull + @Override + public String getComponentName() { + return "StudyTaskManager"; + } + + public static StudyTaskManager getInstance(@NotNull final Project project) { + StudyTaskManager item = myTaskManagers.get(project.getBasePath()); + return item != null ? item : new StudyTaskManager(project); + } + + + @Nullable + public TaskFile getTaskFile(@NotNull final VirtualFile file) { + if (myCourse == null) { + return null; + } + VirtualFile taskDir = file.getParent(); + if (taskDir != null) { + String taskDirName = taskDir.getName(); + if (taskDirName.contains(Task.TASK_DIR)) { + VirtualFile lessonDir = taskDir.getParent(); + if (lessonDir != null) { + String lessonDirName = lessonDir.getName(); + int lessonIndex = StudyUtils.getIndex(lessonDirName, Lesson.LESSON_DIR); + List<Lesson> lessons = myCourse.getLessons(); + if (!StudyUtils.indexIsValid(lessonIndex, lessons)) { + return null; + } + Lesson lesson = lessons.get(lessonIndex); + int taskIndex = StudyUtils.getIndex(taskDirName, Task.TASK_DIR); + List<Task> tasks = lesson.getTaskList(); + if (!StudyUtils.indexIsValid(taskIndex, tasks)) { + return null; + } + Task task = tasks.get(taskIndex); + return task.getFile(file.getName()); + } + } + } + return null; + } + + class FileCreatedListener extends VirtualFileAdapter { + @Override + public void fileCreated(@NotNull VirtualFileEvent event) { + VirtualFile createdFile = event.getFile(); + VirtualFile taskDir = createdFile.getParent(); + String taskLogicalName = Task.TASK_DIR; + if (taskDir != null && taskDir.getName().contains(taskLogicalName)) { + int taskIndex = StudyUtils.getIndex(taskDir.getName(), taskLogicalName); + VirtualFile lessonDir = taskDir.getParent(); + String lessonLogicalName = Lesson.LESSON_DIR; + if (lessonDir != null && lessonDir.getName().contains(lessonLogicalName)) { + int lessonIndex = StudyUtils.getIndex(lessonDir.getName(), lessonLogicalName); + if (myCourse != null) { + List<Lesson> lessons = myCourse.getLessons(); + if (StudyUtils.indexIsValid(lessonIndex, lessons)) { + Lesson lesson = lessons.get(lessonIndex); + List<Task> tasks = lesson.getTaskList(); + if (StudyUtils.indexIsValid(taskIndex, tasks)) { + Task task = tasks.get(taskIndex); + TaskFile taskFile = new TaskFile(); + taskFile.init(task, false); + taskFile.setUserCreated(true); + task.getTaskFiles().put(createdFile.getName(), taskFile); + } + } + } + } + } + } + } + +} |