<project-components>
<component>
- <implementation-class>com.jetbrains.edu.learning.StudyTaskManager</implementation-class>
- <interface-class>com.jetbrains.edu.learning.StudyTaskManager</interface-class>
+ <implementation-class>com.jetbrains.edu.learning.StudyProjectComponent</implementation-class>
+ <interface-class>com.jetbrains.edu.learning.StudyProjectComponent</interface-class>
</component>
</project-components>
serviceImplementation="com.jetbrains.edu.learning.StudyInstructionPainter" overrides="true"/>
<errorHandler implementation="com.intellij.diagnostic.ITNReporter"/>
<highlightErrorFilter implementation="com.jetbrains.edu.learning.editor.StudyHighlightErrorFilter"/>
+ <projectService serviceInterface="com.jetbrains.edu.learning.StudyTaskManager"
+ serviceImplementation="com.jetbrains.edu.learning.StudyTaskManager"/>
</extensions>
</idea-plugin>
\ No newline at end of file
--- /dev/null
+package com.jetbrains.edu.learning;
+
+import com.intellij.ide.ui.UISettings;
+import com.intellij.notification.Notification;
+import com.intellij.notification.NotificationType;
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.actionSystem.ex.AnActionListener;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.components.ProjectComponent;
+import com.intellij.openapi.diagnostic.Logger;
+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.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.module.ModuleServiceManager;
+import com.intellij.openapi.project.DumbAwareRunnable;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.startup.StartupManager;
+import com.intellij.openapi.util.io.FileUtil;
+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.jetbrains.edu.StudyNames;
+import com.jetbrains.edu.courseFormat.Course;
+import com.jetbrains.edu.courseFormat.Lesson;
+import com.jetbrains.edu.courseFormat.Task;
+import com.jetbrains.edu.courseFormat.TaskFile;
+import com.jetbrains.edu.learning.actions.*;
+import com.jetbrains.edu.learning.courseGeneration.StudyGenerator;
+import com.jetbrains.edu.learning.editor.StudyEditorFactoryListener;
+import com.jetbrains.edu.learning.ui.StudyCondition;
+import com.jetbrains.edu.learning.ui.StudyToolWindowFactory;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+public class StudyProjectComponent implements ProjectComponent {
+ private static final Logger LOG = Logger.getInstance(StudyProjectComponent.class.getName());
+ private static Map<String, String> myDeletedShortcuts = new HashMap<String, String>();
+ private final Project myProject;
+
+ private FileCreatedByUserListener myListener;
+
+ private StudyProjectComponent(@NotNull final Project project) {
+ myProject = project;
+ }
+
+ @Override
+ public void projectOpened() {
+ final Course course = StudyTaskManager.getInstance(myProject).getCourse();
+ if (course != null && !course.isUpToDate()) {
+ course.setUpToDate(true);
+ updateCourse();
+ }
+
+ registerStudyToolwindow(course);
+ ApplicationManager.getApplication().invokeLater(new DumbAwareRunnable() {
+ @Override
+ public void run() {
+ ApplicationManager.getApplication().runWriteAction(new DumbAwareRunnable() {
+ @Override
+ public void run() {
+ if (course != null) {
+ moveFocusToEditor();
+ UISettings.getInstance().HIDE_TOOL_STRIPES = false;
+ UISettings.getInstance().fireUISettingsChanged();
+ registerShortcuts();
+ }
+ }
+ });
+ }
+ });
+ }
+
+ public void registerStudyToolwindow(@Nullable final Course course) {
+ if (course != null) {
+ final ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(myProject);
+ registerToolWindow(toolWindowManager);
+ final ToolWindow studyToolWindow = toolWindowManager.getToolWindow(StudyToolWindowFactory.STUDY_TOOL_WINDOW);
+ if (studyToolWindow != null) {
+ StudyUtils.updateStudyToolWindow(myProject);
+ studyToolWindow.show(null);
+ }
+ }
+ }
+
+ private void moveFocusToEditor() {
+ StartupManager.getInstance(myProject).runWhenProjectIsInitialized(new Runnable() {
+ @Override
+ public void run() {
+ ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PROJECT_VIEW).show(new Runnable() {
+ @Override
+ public void run() {
+ FileEditor[] editors = FileEditorManager.getInstance(myProject).getSelectedEditors();
+ if (editors.length > 0) {
+ final JComponent focusedComponent = editors[0].getPreferredFocusedComponent();
+ if (focusedComponent != null) {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ IdeFocusManager.getInstance(myProject).requestFocus(focusedComponent, true);
+ }
+ });
+ }
+ }
+ }
+ });
+ }
+ });
+ }
+
+ private static void registerShortcuts() {
+ addShortcut(StudyNextWindowAction.SHORTCUT, StudyNextWindowAction.ACTION_ID, false);
+ addShortcut(StudyPrevWindowAction.SHORTCUT, StudyPrevWindowAction.ACTION_ID, false);
+ addShortcut(StudyShowHintAction.SHORTCUT, StudyShowHintAction.ACTION_ID, false);
+ addShortcut(StudyNextWindowAction.SHORTCUT2, StudyNextWindowAction.ACTION_ID, true);
+ addShortcut(StudyCheckAction.SHORTCUT, StudyCheckAction.ACTION_ID, false);
+ addShortcut(StudyNextStudyTaskAction.SHORTCUT, StudyNextStudyTaskAction.ACTION_ID, false);
+ addShortcut(StudyPreviousStudyTaskAction.SHORTCUT, StudyPreviousStudyTaskAction.ACTION_ID, false);
+ addShortcut(StudyRefreshTaskFileAction.SHORTCUT, StudyRefreshTaskFileAction.ACTION_ID, false);
+ }
+
+ private void registerToolWindow(@NotNull final ToolWindowManager toolWindowManager) {
+ 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, StudyToolWindowFactory.STUDY_TOOL_WINDOW, null, ToolWindowAnchor.LEFT, true, true, true);
+ }
+ catch (Exception e) {
+ final ToolWindow toolWindow = toolWindowManager.getToolWindow(StudyToolWindowFactory.STUDY_TOOL_WINDOW);
+ if (toolWindow == null) {
+ toolWindowManager.registerToolWindow(StudyToolWindowFactory.STUDY_TOOL_WINDOW, true, ToolWindowAnchor.RIGHT, myProject, true);
+ }
+ }
+ }
+
+ private void updateCourse() {
+ final Course course = StudyTaskManager.getInstance(myProject).getCourse();
+ if (course == null) {
+ return;
+ }
+ final File resourceDirectory = new File(course.getCourseDirectory());
+ if (!resourceDirectory.exists()) {
+ return;
+ }
+ StudyLanguageManager manager = StudyUtils.getLanguageManager(course);
+ if (manager == null) {
+ LOG.info("Study Language Manager is null for " + course.getLanguageById().getDisplayName());
+ return;
+ }
+ final File[] files = resourceDirectory.listFiles();
+ if (files == null) return;
+ for (File file : files) {
+ String testHelper = manager.getTestHelperFileName();
+ if (file.getName().equals(testHelper)) {
+ copyFile(file, new File(myProject.getBasePath(), testHelper));
+ }
+ if (file.getName().startsWith(StudyNames.LESSON)) {
+ final File[] tasks = file.listFiles();
+ if (tasks == null) continue;
+ for (File task : tasks) {
+ final File taskDescr = new File(task, StudyNames.TASK_HTML);
+ String testFileName = manager.getTestFileName();
+ final File taskTests = new File(task, testFileName);
+ copyFile(taskDescr, new File(new File(new File(myProject.getBasePath(), file.getName()), task.getName()), StudyNames.TASK_HTML));
+ copyFile(taskTests, new File(new File(new File(myProject.getBasePath(), file.getName()), task.getName()),
+ testFileName));
+ }
+ }
+ }
+
+ final Notification notification =
+ new Notification("Update.course", "Course update", "Current course is synchronized", NotificationType.INFORMATION);
+ notification.notify(myProject);
+ }
+
+ private static void copyFile(@NotNull final File from, @NotNull final File to) {
+ if (from.exists()) {
+ try {
+ FileUtil.copy(from, to);
+ }
+ catch (IOException e) {
+ LOG.warn("Failed to copy " + from.getName());
+ }
+ }
+ }
+
+ private static void addShortcut(@NotNull final String shortcutString, @NotNull final String actionIdString, boolean isAdditional) {
+ Keymap keymap = KeymapManager.getInstance().getActiveKeymap();
+ Shortcut[] shortcuts = keymap.getShortcuts(actionIdString);
+ if (shortcuts.length > 0 && !isAdditional) {
+ return;
+ }
+ 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() {
+ //noinspection AssignmentToStaticFieldFromInstanceMethod
+ StudyCondition.VALUE = false;
+ final Course course = StudyTaskManager.getInstance(myProject).getCourse();
+ if (course != null) {
+ ToolWindowManager.getInstance(myProject).getToolWindow(StudyToolWindowFactory.STUDY_TOOL_WINDOW).getContentManager()
+ .removeAllContents(false);
+ if (!myDeletedShortcuts.isEmpty()) {
+ for (Map.Entry<String, String> shortcut : myDeletedShortcuts.entrySet()) {
+ final Keymap keymap = KeymapManager.getInstance().getActiveKeymap();
+ final 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 FileCreatedByUserListener();
+ 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 StudyProjectComponent getInstance(@NotNull final Project project) {
+ final Module module = ModuleManager.getInstance(project).getModules()[0];
+ return ModuleServiceManager.getService(module, StudyProjectComponent.class);
+ }
+ private class FileCreatedByUserListener extends VirtualFileAdapter {
+ @Override
+ public void fileCreated(@NotNull VirtualFileEvent event) {
+ final VirtualFile createdFile = event.getFile();
+ final VirtualFile taskDir = createdFile.getParent();
+ final Course course = StudyTaskManager.getInstance(myProject).getCourse();
+ if (taskDir != null && taskDir.getName().contains(StudyNames.TASK_DIR)) {
+ int taskIndex = StudyUtils.getIndex(taskDir.getName(), StudyNames.TASK_DIR);
+ final VirtualFile lessonDir = taskDir.getParent();
+ if (lessonDir != null && lessonDir.getName().contains(StudyNames.LESSON_DIR)) {
+ int lessonIndex = StudyUtils.getIndex(lessonDir.getName(), StudyNames.LESSON_DIR);
+ if (course != null) {
+ List<Lesson> lessons = course.getLessons();
+ if (StudyUtils.indexIsValid(lessonIndex, lessons)) {
+ final Lesson lesson = lessons.get(lessonIndex);
+ final List<Task> tasks = lesson.getTaskList();
+ if (StudyUtils.indexIsValid(taskIndex, tasks)) {
+ final Task task = tasks.get(taskIndex);
+ final TaskFile taskFile = new TaskFile();
+ StudyGenerator.initTaskFile(taskFile, task, false);
+ taskFile.setUserCreated(true);
+ task.getTaskFiles().put(createdFile.getName(), taskFile);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+}
package com.jetbrains.edu.learning;
-import com.intellij.ide.ui.UISettings;
-import com.intellij.notification.Notification;
-import com.intellij.notification.NotificationType;
-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.diagnostic.Logger;
-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.components.PersistentStateComponent;
+import com.intellij.openapi.components.State;
+import com.intellij.openapi.components.Storage;
+import com.intellij.openapi.components.StorageScheme;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.ModuleServiceManager;
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.util.io.FileUtil;
-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.edu.StudyNames;
+import com.intellij.util.xmlb.XmlSerializerUtil;
import com.jetbrains.edu.courseFormat.Course;
-import com.jetbrains.edu.courseFormat.Lesson;
-import com.jetbrains.edu.courseFormat.Task;
-import com.jetbrains.edu.courseFormat.TaskFile;
-import com.jetbrains.edu.learning.actions.*;
import com.jetbrains.edu.learning.courseGeneration.StudyGenerator;
-import com.jetbrains.edu.learning.editor.StudyEditorFactoryListener;
-import com.jetbrains.edu.learning.ui.StudyCondition;
-import com.jetbrains.edu.learning.ui.StudyToolWindowFactory;
-import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import javax.swing.*;
-import java.io.File;
-import java.io.IOException;
-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
scheme = StorageScheme.DIRECTORY_BASED
)}
)
-public class StudyTaskManager implements ProjectComponent, PersistentStateComponent<Element>, DumbAware {
- private static final Logger LOG = Logger.getInstance(StudyTaskManager.class.getName());
- public static final String COURSE_ELEMENT = "courseElement";
- private static Map<String, String> myDeletedShortcuts = new HashMap<String, String>();
- private final Project myProject;
- private Course myCourse;
- private FileCreatedByUserListener myListener;
-
+public class StudyTaskManager implements PersistentStateComponent<StudyTaskManager>, DumbAware {
+ public Course myCourse;
public void setCourse(@NotNull final Course course) {
myCourse = course;
}
- private StudyTaskManager(@NotNull final Project project) {
- myProject = project;
+ private StudyTaskManager() {
}
@Nullable
@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;
+ public StudyTaskManager getState() {
+ return this;
}
@Override
- public void loadState(Element el) {
- myCourse = XmlSerializer.deserialize(el.getChild(COURSE_ELEMENT), Course.class);
+ public void loadState(StudyTaskManager state) {
+ XmlSerializerUtil.copyBean(state, this);
if (myCourse != null) {
StudyGenerator.initCourse(myCourse, true);
}
}
- @Override
- public void projectOpened() {
- if (myCourse != null && !myCourse.isUpToDate()) {
- myCourse.setUpToDate(true);
- updateCourse();
- }
- ApplicationManager.getApplication().invokeLater(new DumbAwareRunnable() {
- @Override
- public void run() {
- ApplicationManager.getApplication().runWriteAction(new DumbAwareRunnable() {
- @Override
- public void run() {
- if (myCourse != null) {
- moveFocusToEditor();
- UISettings.getInstance().HIDE_TOOL_STRIPES = false;
- UISettings.getInstance().fireUISettingsChanged();
- final ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(myProject);
- registerToolWindow(toolWindowManager);
- final ToolWindow studyToolWindow = toolWindowManager.getToolWindow(StudyToolWindowFactory.STUDY_TOOL_WINDOW);
- if (studyToolWindow != null) {
- StudyUtils.updateStudyToolWindow(myProject);
- studyToolWindow.show(null);
- }
- registerShortcuts();
- }
- }
- });
- }
- });
- }
-
- private void moveFocusToEditor() {
- StartupManager.getInstance(myProject).runWhenProjectIsInitialized(new Runnable() {
- @Override
- public void run() {
- ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PROJECT_VIEW).show(new Runnable() {
- @Override
- public void run() {
- FileEditor[] editors = FileEditorManager.getInstance(myProject).getSelectedEditors();
- if (editors.length > 0) {
- final JComponent focusedComponent = editors[0].getPreferredFocusedComponent();
- if (focusedComponent != null) {
- ApplicationManager.getApplication().invokeLater(new Runnable() {
- @Override
- public void run() {
- IdeFocusManager.getInstance(myProject).requestFocus(focusedComponent, true);
- }
- });
- }
- }
- }
- });
- }
- });
- }
-
- private static void registerShortcuts() {
- addShortcut(StudyNextWindowAction.SHORTCUT, StudyNextWindowAction.ACTION_ID, false);
- addShortcut(StudyPrevWindowAction.SHORTCUT, StudyPrevWindowAction.ACTION_ID, false);
- addShortcut(StudyShowHintAction.SHORTCUT, StudyShowHintAction.ACTION_ID, false);
- addShortcut(StudyNextWindowAction.SHORTCUT2, StudyNextWindowAction.ACTION_ID, true);
- addShortcut(StudyCheckAction.SHORTCUT, StudyCheckAction.ACTION_ID, false);
- addShortcut(StudyNextStudyTaskAction.SHORTCUT, StudyNextStudyTaskAction.ACTION_ID, false);
- addShortcut(StudyPreviousStudyTaskAction.SHORTCUT, StudyPreviousStudyTaskAction.ACTION_ID, false);
- addShortcut(StudyRefreshTaskFileAction.SHORTCUT, StudyRefreshTaskFileAction.ACTION_ID, false);
- }
-
- private void registerToolWindow(@NotNull final ToolWindowManager toolWindowManager) {
- 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, StudyToolWindowFactory.STUDY_TOOL_WINDOW, null, ToolWindowAnchor.LEFT, true, true, true);
- }
- catch (Exception e) {
- final ToolWindow toolWindow = toolWindowManager.getToolWindow(StudyToolWindowFactory.STUDY_TOOL_WINDOW);
- if (toolWindow == null) {
- toolWindowManager.registerToolWindow(StudyToolWindowFactory.STUDY_TOOL_WINDOW, true, ToolWindowAnchor.RIGHT, myProject, true);
- }
- }
- }
-
- private void updateCourse() {
- if (myCourse == null) {
- return;
- }
- final File resourceDirectory = new File(myCourse.getCourseDirectory());
- if (!resourceDirectory.exists()) {
- return;
- }
- StudyLanguageManager manager = StudyUtils.getLanguageManager(myCourse);
- if (manager == null) {
- LOG.info("Study Language Manager is null for " + myCourse.getLanguageById().getDisplayName());
- return;
- }
- final File[] files = resourceDirectory.listFiles();
- if (files == null) return;
- for (File file : files) {
- String testHelper = manager.getTestHelperFileName();
- if (file.getName().equals(testHelper)) {
- copyFile(file, new File(myProject.getBasePath(), testHelper));
- }
- if (file.getName().startsWith(StudyNames.LESSON)) {
- final File[] tasks = file.listFiles();
- if (tasks == null) continue;
- for (File task : tasks) {
- final File taskDescr = new File(task, StudyNames.TASK_HTML);
- String testFileName = manager.getTestFileName();
- final File taskTests = new File(task, testFileName);
- copyFile(taskDescr, new File(new File(new File(myProject.getBasePath(), file.getName()), task.getName()), StudyNames.TASK_HTML));
- copyFile(taskTests, new File(new File(new File(myProject.getBasePath(), file.getName()), task.getName()),
- testFileName));
- }
- }
- }
-
- final Notification notification =
- new Notification("Update.course", "Course update", "Current course is synchronized", NotificationType.INFORMATION);
- notification.notify(myProject);
- }
-
- private static void copyFile(@NotNull final File from, @NotNull final File to) {
- if (from.exists()) {
- try {
- FileUtil.copy(from, to);
- }
- catch (IOException e) {
- LOG.warn("Failed to copy " + from.getName());
- }
- }
- }
-
- private static void addShortcut(@NotNull final String shortcutString, @NotNull final String actionIdString, boolean isAdditional) {
- Keymap keymap = KeymapManager.getInstance().getActiveKeymap();
- Shortcut[] shortcuts = keymap.getShortcuts(actionIdString);
- if (shortcuts.length > 0 && !isAdditional) {
- return;
- }
- 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() {
- //noinspection AssignmentToStaticFieldFromInstanceMethod
- 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()) {
- final Keymap keymap = KeymapManager.getInstance().getActiveKeymap();
- final 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 FileCreatedByUserListener();
- 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) {
final Module module = ModuleManager.getInstance(project).getModules()[0];
return ModuleServiceManager.getService(module, StudyTaskManager.class);
}
- private class FileCreatedByUserListener extends VirtualFileAdapter {
- @Override
- public void fileCreated(@NotNull VirtualFileEvent event) {
- final VirtualFile createdFile = event.getFile();
- final VirtualFile taskDir = createdFile.getParent();
- if (taskDir != null && taskDir.getName().contains(StudyNames.TASK_DIR)) {
- int taskIndex = StudyUtils.getIndex(taskDir.getName(), StudyNames.TASK_DIR);
- final VirtualFile lessonDir = taskDir.getParent();
- if (lessonDir != null && lessonDir.getName().contains(StudyNames.LESSON_DIR)) {
- int lessonIndex = StudyUtils.getIndex(lessonDir.getName(), StudyNames.LESSON_DIR);
- if (myCourse != null) {
- List<Lesson> lessons = myCourse.getLessons();
- if (StudyUtils.indexIsValid(lessonIndex, lessons)) {
- final Lesson lesson = lessons.get(lessonIndex);
- final List<Task> tasks = lesson.getTaskList();
- if (StudyUtils.indexIsValid(taskIndex, tasks)) {
- final Task task = tasks.get(taskIndex);
- final TaskFile taskFile = new TaskFile();
- StudyGenerator.initTaskFile(taskFile, task, false);
- taskFile.setUserCreated(true);
- task.getTaskFiles().put(createdFile.getName(), taskFile);
- }
- }
- }
- }
- }
- }
- }
-
}
package com.jetbrains.edu.learning.courseGeneration;
-import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
*/
public static void createCourse(@NotNull final Course course, @NotNull final VirtualFile baseDir, @NotNull final File resourceRoot,
@NotNull final Project project) {
- ApplicationManager.getApplication().invokeLater(
- new Runnable() {
- @Override
- public void run() {
- ApplicationManager.getApplication().runWriteAction(new Runnable() {
- @Override
- public void run() {
+
try {
final List<Lesson> lessons = course.getLessons();
for (int i = 0; i < lessons.size(); i++) {
lesson.setIndex(i);
createLesson(lesson, baseDir, resourceRoot, project);
}
- baseDir.createChildDirectory(this, StudyNames.SANDBOX_DIR);
+ baseDir.createChildDirectory(project, StudyNames.SANDBOX_DIR);
File[] files = resourceRoot.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
catch (IOException e) {
LOG.error(e);
}
- }
- });
- }
- });
}
/**
import com.google.gson.GsonBuilder;
import com.intellij.facet.ui.ValidationResult;
import com.intellij.ide.projectView.ProjectView;
-import com.intellij.ide.projectView.impl.AbstractProjectViewPane;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
-import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
import com.intellij.openapi.vfs.newvfs.impl.VirtualDirectoryImpl;
-import com.intellij.openapi.wm.ex.ToolWindowManagerAdapter;
-import com.intellij.openapi.wm.ex.ToolWindowManagerEx;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.util.containers.ContainerUtil;
import com.jetbrains.edu.courseFormat.Lesson;
import com.jetbrains.edu.courseFormat.Task;
import com.jetbrains.edu.courseFormat.TaskFile;
-import com.jetbrains.edu.learning.CourseInfo;
-import com.jetbrains.edu.learning.StudyLanguageManager;
-import com.jetbrains.edu.learning.StudyTaskManager;
-import com.jetbrains.edu.learning.StudyUtils;
+import com.jetbrains.edu.learning.*;
import com.jetbrains.edu.learning.stepic.StudyStepicConnector;
import org.jetbrains.annotations.NotNull;
-import javax.swing.*;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public void generateProject(@NotNull final Project project, @NotNull final VirtualFile baseDir) {
final Course course = StudyStepicConnector.getCourse(mySelectedCourseInfo);
if (course == null) return;
- flushCourse(course);
- StudyGenerator.initCourse(course, false);
- final File courseDirectory = new File(myCoursesDir, course.getName());
- StudyGenerator.createCourse(course, baseDir, courseDirectory, project);
- course.setCourseDirectory(new File(myCoursesDir, mySelectedCourseInfo.getName()).getAbsolutePath());
- VirtualFileManager.getInstance().refreshWithoutFileWatcher(true);
StudyTaskManager.getInstance(project).setCourse(course);
- ToolWindowManagerEx.getInstanceEx(project).addToolWindowManagerListener(new OpenFirstTaskListener(project, course));
- }
-
- private static class OpenFirstTaskListener extends ToolWindowManagerAdapter {
- private final Project myProject;
- private final Course myCourse;
- private boolean myInitialized = false;
-
- OpenFirstTaskListener(@NotNull final Project project, @NotNull final Course course) {
- myProject = project;
- myCourse = course;
- }
-
- public void stateChanged() {
- final AbstractProjectViewPane projectViewPane = ProjectView.getInstance(myProject).getCurrentProjectViewPane();
- if (projectViewPane == null || myInitialized) return;
- JTree tree = projectViewPane.getTree();
- if (tree == null) {
- return;
- }
- tree.updateUI();
-
- ApplicationManager.getApplication().invokeLater(new Runnable() {
+ flushCourse(course);
+ ApplicationManager.getApplication().invokeLater(
+ new Runnable() {
@Override
public void run() {
- LocalFileSystem.getInstance().refresh(false);
- final Lesson firstLesson = StudyUtils.getFirst(myCourse.getLessons());
- final Task firstTask = StudyUtils.getFirst(firstLesson.getTaskList());
- final VirtualFile taskDir = firstTask.getTaskDir(myProject);
- if (taskDir == null) return;
- final Map<String, TaskFile> taskFiles = firstTask.getTaskFiles();
- VirtualFile activeVirtualFile = null;
- for (Map.Entry<String, TaskFile> entry : taskFiles.entrySet()) {
- final String name = entry.getKey();
- final TaskFile taskFile = entry.getValue();
- final VirtualFile virtualFile = ((VirtualDirectoryImpl)taskDir).refreshAndFindChild(name);
- if (virtualFile != null) {
- FileEditorManager.getInstance(myProject).openFile(virtualFile, true);
- if (!taskFile.getAnswerPlaceholders().isEmpty()) {
- activeVirtualFile = virtualFile;
- }
- }
- }
- if (activeVirtualFile != null) {
- final PsiFile file = PsiManager.getInstance(myProject).findFile(activeVirtualFile);
- ProjectView.getInstance(myProject).select(file, activeVirtualFile, true);
- } else {
- String first = StudyUtils.getFirst(taskFiles.keySet());
- if (first != null) {
- NewVirtualFile firstFile = ((VirtualDirectoryImpl)taskDir).refreshAndFindChild(first);
- if (firstFile != null) {
- FileEditorManager.getInstance(myProject).openFile(firstFile, true);
- }
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ StudyGenerator.initCourse(course, false);
+ final File courseDirectory = new File(myCoursesDir, course.getName());
+ StudyGenerator.createCourse(course, baseDir, courseDirectory, project);
+ course.setCourseDirectory(new File(myCoursesDir, mySelectedCourseInfo.getName()).getAbsolutePath());
+ VirtualFileManager.getInstance().refreshWithoutFileWatcher(true);
+ StudyProjectComponent.getInstance(project).registerStudyToolwindow(course);
+ openFirstTask(course, project);
+
}
- }
- myInitialized = true;
- }
- }, ModalityState.current(), new Condition() {
- @Override
- public boolean value(Object o) {
- return myProject.isDisposed();
+ });
}
});
+ }
+
+ private static void openFirstTask(@NotNull final Course course, @NotNull final Project project) {
+ LocalFileSystem.getInstance().refresh(false);
+ final Lesson firstLesson = StudyUtils.getFirst(course.getLessons());
+ final Task firstTask = StudyUtils.getFirst(firstLesson.getTaskList());
+ final VirtualFile taskDir = firstTask.getTaskDir(project);
+ if (taskDir == null) return;
+ final Map<String, TaskFile> taskFiles = firstTask.getTaskFiles();
+ VirtualFile activeVirtualFile = null;
+ for (Map.Entry<String, TaskFile> entry : taskFiles.entrySet()) {
+ final String name = entry.getKey();
+ final TaskFile taskFile = entry.getValue();
+ final VirtualFile virtualFile = ((VirtualDirectoryImpl)taskDir).refreshAndFindChild(name);
+ if (virtualFile != null) {
+ FileEditorManager.getInstance(project).openFile(virtualFile, true);
+ if (!taskFile.getAnswerPlaceholders().isEmpty()) {
+ activeVirtualFile = virtualFile;
+ }
+ }
+ }
+ if (activeVirtualFile != null) {
+ final PsiFile file = PsiManager.getInstance(project).findFile(activeVirtualFile);
+ ProjectView.getInstance(project).select(file, activeVirtualFile, true);
+ } else {
+ String first = StudyUtils.getFirst(taskFiles.keySet());
+ if (first != null) {
+ NewVirtualFile firstFile = ((VirtualDirectoryImpl)taskDir).refreshAndFindChild(first);
+ if (firstFile != null) {
+ FileEditorManager.getInstance(project).openFile(firstFile, true);
+ }
+ }
}
}
public class StudyToolWindowFactory implements ToolWindowFactory, DumbAware {
public static final String STUDY_TOOL_WINDOW = "Course Description";
- private JPanel myContentPanel = new JPanel();
+
@Override
public void createToolWindowContent(@NotNull final Project project, @NotNull final ToolWindow toolWindow) {
+ JPanel contentPanel = new JPanel();
if (StudyTaskManager.getInstance(project).getCourse() != null) {
- myContentPanel.setLayout(new BoxLayout(myContentPanel, BoxLayout.PAGE_AXIS));
- myContentPanel.add(Box.createRigidArea(new Dimension(10, 0)));
+ contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.PAGE_AXIS));
+ contentPanel.add(Box.createRigidArea(new Dimension(10, 0)));
StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
Course course = taskManager.getCourse();
if (course == null) {
String description = UIUtil.toHtml(course.getDescription(), 5);
String author = taskManager.getCourse().getAuthor();
String authorLabel = UIUtil.toHtml("<b>Author: </b>" + author, 5);
- myContentPanel.add(new JLabel(courseName));
- myContentPanel.add(new JLabel(authorLabel));
- myContentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
- myContentPanel.add(new JLabel(description));
- myContentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
+ contentPanel.add(new JLabel(courseName));
+ contentPanel.add(new JLabel(authorLabel));
+ contentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
+ contentPanel.add(new JLabel(description));
+ contentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
int taskNum = 0;
int taskSolved = 0;
int lessonsCompleted = 0;
String completedLessons = String.format("%d of %d lessons completed", lessonsCompleted, course.getLessons().size());
String completedTasks = String.format("%d of %d tasks completed", taskSolved, taskNum);
String tasksLeft = String.format("%d of %d tasks left", taskNum - taskSolved, taskNum);
- myContentPanel.add(Box.createVerticalStrut(10));
- addStatistics(completedLessons);
- addStatistics(completedTasks);
+ contentPanel.add(Box.createVerticalStrut(10));
+ addStatistics(completedLessons, contentPanel);
+ addStatistics(completedTasks, contentPanel);
double percent = (taskSolved * 100.0) / taskNum;
- myContentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
+ contentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
StudyProgressBar studyProgressBar = new StudyProgressBar(percent / 100, 40, 10);
- myContentPanel.add(studyProgressBar);
- addStatistics(tasksLeft);
+ contentPanel.add(studyProgressBar);
+ addStatistics(tasksLeft, contentPanel);
ContentFactory contentFactory = ContentFactory.SERVICE.getInstance();
- Content content = contentFactory.createContent(myContentPanel, "", true);
+ Content content = contentFactory.createContent(contentPanel, "", true);
toolWindow.getContentManager().addContent(content);
}
}
- private void addStatistics(String statistics) {
+ private static void addStatistics(String statistics, JPanel contentPanel) {
String labelText = UIUtil.toHtml(statistics, 5);
- myContentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
+ contentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
JLabel statisticLabel = new JLabel(labelText);
- myContentPanel.add(statisticLabel);
+ contentPanel.add(statisticLabel);
}
}