summaryrefslogtreecommitdiff
path: root/python/edu/learn-python/src/com/jetbrains/python/edu/StudyTaskManager.java
diff options
context:
space:
mode:
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.java296
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);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+}