summaryrefslogtreecommitdiff
path: root/python/edu/learn-python/src/com
diff options
context:
space:
mode:
Diffstat (limited to 'python/edu/learn-python/src/com')
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/StudyDirectoryProjectGenerator.java2
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/StudyTestRunner.java4
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyIntroductionCourseAction.java75
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNewProject.java34
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyRefreshTaskFileAction.java211
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyReloadCourseAction.java134
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyTaskNavigationAction.java7
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/projectView/StudyDirectoryNode.java55
-rw-r--r--python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyToolWindowFactory.java11
9 files changed, 407 insertions, 126 deletions
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDirectoryProjectGenerator.java b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDirectoryProjectGenerator.java
index 59bd8bc2ea7c..b558667734bc 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDirectoryProjectGenerator.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDirectoryProjectGenerator.java
@@ -53,7 +53,7 @@ public class StudyDirectoryProjectGenerator extends PythonProjectGenerator imple
@NotNull
@Override
public String getName() {
- return "Learn Python";
+ return "Educational";
}
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyTestRunner.java b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyTestRunner.java
index b0cd5ba89fed..1800deb0a0d9 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyTestRunner.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyTestRunner.java
@@ -61,7 +61,9 @@ public class StudyTestRunner {
try {
while ((line = testOutputReader.readLine()) != null) {
if (line.contains(TEST_FAILED)) {
- return line.substring(TEST_FAILED.length(), line.length());
+ String res = line.substring(TEST_FAILED.length(), line.length());
+ StudyUtils.closeSilently(testOutputReader);
+ return res;
}
}
}
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyIntroductionCourseAction.java b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyIntroductionCourseAction.java
new file mode 100644
index 000000000000..ed1fff22878f
--- /dev/null
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyIntroductionCourseAction.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jetbrains.python.edu.actions;
+
+import com.intellij.ide.impl.ProjectUtil;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.jetbrains.python.configuration.PyConfigurableInterpreterList;
+import com.jetbrains.python.edu.StudyDirectoryProjectGenerator;
+import com.jetbrains.python.edu.StudyUtils;
+import com.jetbrains.python.edu.course.CourseInfo;
+import com.jetbrains.python.newProject.actions.GenerateProjectCallback;
+import com.jetbrains.python.newProject.actions.ProjectSpecificSettingsStep;
+import icons.StudyIcons;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.util.List;
+import java.util.Map;
+
+public class StudyIntroductionCourseAction extends AnAction {
+
+ public StudyIntroductionCourseAction() {
+ super("Introduction to Python", "Introduction to Python", StudyIcons.EducationalProjectType);
+ }
+
+ @Override
+ public void actionPerformed(@NotNull AnActionEvent e) {
+ final File projectDir = new File(ProjectUtil.getBaseDir(), "PythonIntroduction");
+ if (projectDir.exists()) {
+ ProjectUtil.openProject(projectDir.getPath(), null, false);
+ }
+ else {
+ final GenerateProjectCallback callback = new GenerateProjectCallback(null);
+ final StudyDirectoryProjectGenerator generator = new StudyDirectoryProjectGenerator();
+ final Map<CourseInfo, File> courses = generator.getCourses();
+ CourseInfo introCourse = null;
+ for (CourseInfo info : courses.keySet()) {
+ if ("Introduction to Python".equals(info.getName())) {
+ introCourse = info;
+ }
+ }
+ if (introCourse == null) {
+ introCourse = StudyUtils.getFirst(courses.keySet());
+ }
+ generator.setSelectedCourse(introCourse);
+ final ProjectSpecificSettingsStep step = new ProjectSpecificSettingsStep(generator, callback, true);
+
+ step.createPanel(); // initialize panel to set location
+ step.setLocation(projectDir.toString());
+
+ final Project project = ProjectManager.getInstance().getDefaultProject();
+ final List<Sdk> sdks = PyConfigurableInterpreterList.getInstance(project).getAllPythonSdks();
+ Sdk sdk = sdks.isEmpty() ? null : sdks.iterator().next();
+ step.setSdk(sdk);
+ callback.consume(step);
+ }
+ }
+}
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNewProject.java b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNewProject.java
deleted file mode 100644
index 0b75c4bc01c4..000000000000
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNewProject.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2000-2013 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.jetbrains.python.edu.actions;
-
-import com.jetbrains.python.edu.StudyDirectoryProjectGenerator;
-import com.jetbrains.python.newProject.actions.GenerateProjectCallback;
-import com.jetbrains.python.newProject.actions.ProjectSpecificAction;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class StudyNewProject extends ProjectSpecificAction {
-
- public StudyNewProject(@NotNull final String name, @Nullable final Runnable runnable) {
- super(new GenerateProjectCallback(runnable), new StudyDirectoryProjectGenerator(), name, true);
- }
-
- public StudyNewProject() {
- this("Learn Python", null);
- }
-
-}
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyRefreshTaskFileAction.java b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyRefreshTaskFileAction.java
index a9448ddea0e3..a6c16d2553bf 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyRefreshTaskFileAction.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyRefreshTaskFileAction.java
@@ -22,108 +22,139 @@ import com.jetbrains.python.edu.StudyTaskManager;
import com.jetbrains.python.edu.StudyUtils;
import com.jetbrains.python.edu.course.*;
import com.jetbrains.python.edu.editor.StudyEditor;
+import org.jetbrains.annotations.NotNull;
import java.io.*;
public class StudyRefreshTaskFileAction extends DumbAwareAction {
private static final Logger LOG = Logger.getInstance(StudyRefreshTaskFileAction.class.getName());
- public void refresh(final Project project) {
- ApplicationManager.getApplication().invokeLater(new Runnable() {
+ public static void refresh(final Project project) {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
@Override
public void run() {
- ApplicationManager.getApplication().runWriteAction(new Runnable() {
- @SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
- @Override
- public void run() {
- final Editor editor = StudyEditor.getSelectedEditor(project);
- assert editor != null;
- final Document document = editor.getDocument();
- StudyDocumentListener listener = StudyEditor.getListener(document);
- if (listener != null) {
- document.removeDocumentListener(listener);
- }
- final int lineCount = document.getLineCount();
- if (lineCount != 0) {
- CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() {
- @Override
- public void run() {
- document.deleteString(0, document.getLineEndOffset(lineCount - 1));
- }
- });
- }
- StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
- Course course = taskManager.getCourse();
- assert course != null;
- File resourceFile = new File(course.getResourcePath());
- File resourceRoot = resourceFile.getParentFile();
- FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance();
- VirtualFile openedFile = fileDocumentManager.getFile(document);
- assert openedFile != null;
- final TaskFile selectedTaskFile = taskManager.getTaskFile(openedFile);
- assert selectedTaskFile != null;
- Task currentTask = selectedTaskFile.getTask();
- String lessonDir = Lesson.LESSON_DIR + String.valueOf(currentTask.getLesson().getIndex() + 1);
- String taskDir = Task.TASK_DIR + String.valueOf(currentTask.getIndex() + 1);
- File pattern = new File(new File(new File(resourceRoot, lessonDir), taskDir), openedFile.getName());
- BufferedReader reader = null;
- try {
- reader = new BufferedReader(new InputStreamReader(new FileInputStream(pattern)));
- String line;
- StringBuilder patternText = new StringBuilder();
- while ((line = reader.readLine()) != null) {
- patternText.append(line);
- patternText.append("\n");
- }
- int patternLength = patternText.length();
- if (patternText.charAt(patternLength - 1) == '\n') {
- patternText.delete(patternLength - 1, patternLength);
- }
- document.setText(patternText);
- StudyStatus oldStatus = currentTask.getStatus();
- LessonInfo lessonInfo = currentTask.getLesson().getLessonInfo();
- lessonInfo.update(oldStatus, -1);
- lessonInfo.update(StudyStatus.Unchecked, +1);
- StudyUtils.updateStudyToolWindow(project);
- for (TaskWindow taskWindow : selectedTaskFile.getTaskWindows()) {
- taskWindow.reset();
- }
- ProjectView.getInstance(project).refresh();
- if (listener != null) {
- document.addDocumentListener(listener);
- }
- selectedTaskFile.drawAllWindows(editor);
- ApplicationManager.getApplication().invokeLater(new Runnable() {
- @Override
- public void run() {
- IdeFocusManager.getInstance(project).requestFocus(editor.getContentComponent(), true);
- }
- });
- selectedTaskFile.navigateToFirstTaskWindow(editor);
- BalloonBuilder balloonBuilder =
- JBPopupFactory.getInstance().createHtmlTextBalloonBuilder("You can now start again", MessageType.INFO, null);
- final Balloon balloon = balloonBuilder.createBalloon();
- StudyEditor selectedStudyEditor = StudyEditor.getSelectedStudyEditor(project);
- assert selectedStudyEditor != null;
- balloon.showInCenterOf(selectedStudyEditor.getRefreshButton());
- Disposer.register(project, balloon);
- }
- catch (FileNotFoundException e1) {
- LOG.error(e1);
- }
- catch (IOException e1) {
- LOG.error(e1);
- }
- finally {
- StudyUtils.closeSilently(reader);
- }
- }
- });
+ final Editor editor = StudyEditor.getSelectedEditor(project);
+ assert editor != null;
+ final Document document = editor.getDocument();
+ refreshFile(editor, document, project);
}
});
+ }
+ });
}
- public void actionPerformed(AnActionEvent e) {
+ public static void refreshFile(@NotNull final Editor editor, @NotNull final Document document, @NotNull final Project project) {
+ StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
+ Course course = taskManager.getCourse();
+ assert course != null;
+ FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance();
+ VirtualFile openedFile = fileDocumentManager.getFile(document);
+ assert openedFile != null;
+ final TaskFile selectedTaskFile = taskManager.getTaskFile(openedFile);
+ assert selectedTaskFile != null;
+ String openedFileName = openedFile.getName();
+ Task currentTask = selectedTaskFile.getTask();
+ resetTaskFile(document, project, course, selectedTaskFile, openedFileName, currentTask);
+ selectedTaskFile.drawAllWindows(editor);
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ IdeFocusManager.getInstance(project).requestFocus(editor.getContentComponent(), true);
+ }
+ });
+ selectedTaskFile.navigateToFirstTaskWindow(editor);
+ showBaloon(project);
+ }
+
+ public static void resetTaskFile(Document document, Project project, Course course, TaskFile taskFile, String name, Task task) {
+ resetDocument(document, course, name, task);
+ updateLessonInfo(task);
+ StudyUtils.updateStudyToolWindow(project);
+ resetTaskWindows(taskFile);
+ ProjectView.getInstance(project).refresh();
+ }
+
+ private static void showBaloon(Project project) {
+ BalloonBuilder balloonBuilder =
+ JBPopupFactory.getInstance().createHtmlTextBalloonBuilder("You can now start again", MessageType.INFO, null);
+ final Balloon balloon = balloonBuilder.createBalloon();
+ StudyEditor selectedStudyEditor = StudyEditor.getSelectedStudyEditor(project);
+ assert selectedStudyEditor != null;
+ balloon.showInCenterOf(selectedStudyEditor.getRefreshButton());
+ Disposer.register(project, balloon);
+ }
+
+ private static void resetTaskWindows(TaskFile selectedTaskFile) {
+ for (TaskWindow taskWindow : selectedTaskFile.getTaskWindows()) {
+ taskWindow.reset();
+ }
+ }
+
+ private static void updateLessonInfo(Task currentTask) {
+ StudyStatus oldStatus = currentTask.getStatus();
+ LessonInfo lessonInfo = currentTask.getLesson().getLessonInfo();
+ lessonInfo.update(oldStatus, -1);
+ lessonInfo.update(StudyStatus.Unchecked, +1);
+ }
+
+ @SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
+ private static void resetDocument(Document document, Course course, String fileName, Task task) {
+ BufferedReader reader = null;
+ StudyDocumentListener listener = StudyEditor.getListener(document);
+ if (listener != null) {
+ document.removeDocumentListener(listener);
+ }
+ clearDocument(document);
+ try {
+ String lessonDir = Lesson.LESSON_DIR + String.valueOf(task.getLesson().getIndex() + 1);
+ String taskDir = Task.TASK_DIR + String.valueOf(task.getIndex() + 1);
+ File resourceFile = new File(course.getResourcePath());
+ File resourceRoot = resourceFile.getParentFile();
+ File pattern = new File(new File(new File(resourceRoot, lessonDir), taskDir), fileName);
+ reader = new BufferedReader(new InputStreamReader(new FileInputStream(pattern)));
+ String line;
+ StringBuilder patternText = new StringBuilder();
+ while ((line = reader.readLine()) != null) {
+ patternText.append(line);
+ patternText.append("\n");
+ }
+ int patternLength = patternText.length();
+ if (patternText.charAt(patternLength - 1) == '\n') {
+ patternText.delete(patternLength - 1, patternLength);
+ }
+ document.setText(patternText);
+ }
+ catch (FileNotFoundException e) {
+ LOG.error(e);
+ }
+ catch (IOException e) {
+ LOG.error(e);
+ }
+ finally {
+ StudyUtils.closeSilently(reader);
+ }
+ if (listener != null) {
+ document.addDocumentListener(listener);
+ }
+ }
+
+ private static void clearDocument(final Document document) {
+ final int lineCount = document.getLineCount();
+ if (lineCount != 0) {
+ CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() {
+ @Override
+ public void run() {
+ document.deleteString(0, document.getLineEndOffset(lineCount - 1));
+ }
+ });
+ }
+ }
+
+ public void actionPerformed(@NotNull AnActionEvent e) {
refresh(e.getProject());
}
}
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyReloadCourseAction.java b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyReloadCourseAction.java
new file mode 100644
index 000000000000..beefaaa94f7e
--- /dev/null
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyReloadCourseAction.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jetbrains.python.edu.actions;
+
+import com.intellij.ide.projectView.ProjectView;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.Presentation;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.project.DumbAwareAction;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.ui.tree.TreeUtil;
+import com.jetbrains.python.edu.StudyTaskManager;
+import com.jetbrains.python.edu.StudyUtils;
+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 org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import javax.swing.tree.TreePath;
+import java.util.List;
+import java.util.Map;
+
+public class StudyReloadCourseAction extends DumbAwareAction {
+
+ public StudyReloadCourseAction() {
+ super("Reload Course", "Reload Course", null);
+ }
+
+ @Override
+ public void update(@NotNull AnActionEvent e) {
+ Presentation presentation = e.getPresentation();
+ Project project = e.getProject();
+ if (project != null) {
+ Course course = StudyTaskManager.getInstance(project).getCourse();
+ if (course != null) {
+ presentation.setVisible(true);
+ presentation.setEnabled(true);
+ }
+ }
+ presentation.setVisible(false);
+ presentation.setEnabled(false);
+ }
+
+ @Override
+ public void actionPerformed(@NotNull AnActionEvent e) {
+ Project project = e.getProject();
+ if (project == null) {
+ return;
+ }
+ reloadCourse(project);
+ }
+
+ public static void reloadCourse(@NotNull final Project project) {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ Course course = StudyTaskManager.getInstance(project).getCourse();
+ if (course == null) {
+ return;
+ }
+ for (VirtualFile file : FileEditorManager.getInstance(project).getOpenFiles()) {
+ FileEditorManager.getInstance(project).closeFile(file);
+ }
+ JTree tree = ProjectView.getInstance(project).getCurrentProjectViewPane().getTree();
+ TreePath path = TreeUtil.getFirstNodePath(tree);
+ tree.collapsePath(path);
+ List<Lesson> lessons = course.getLessons();
+ for (Lesson lesson : lessons) {
+ List<Task> tasks = lesson.getTaskList();
+ VirtualFile lessonDir = project.getBaseDir().findChild(Lesson.LESSON_DIR + (lesson.getIndex() + 1));
+ if (lessonDir == null) {
+ continue;
+ }
+ for (Task task : tasks) {
+ VirtualFile taskDir = lessonDir.findChild(Task.TASK_DIR + (task.getIndex() + 1));
+ if (taskDir == null) {
+ continue;
+ }
+ Map<String, TaskFile> taskFiles = task.getTaskFiles();
+ for (Map.Entry<String, TaskFile> entry : taskFiles.entrySet()) {
+ String name = entry.getKey();
+ TaskFile taskFile = entry.getValue();
+ VirtualFile file = taskDir.findChild(name);
+ if (file == null) {
+ continue;
+ }
+ Document document = FileDocumentManager.getInstance().getDocument(file);
+ if (document == null) {
+ continue;
+ }
+ StudyRefreshTaskFileAction.resetTaskFile(document, project, course, taskFile, name, task);
+ }
+ }
+ }
+ Lesson firstLesson = StudyUtils.getFirst(lessons);
+ if (firstLesson == null) {
+ return;
+ }
+ Task firstTask = StudyUtils.getFirst(firstLesson.getTaskList());
+ VirtualFile lessonDir = project.getBaseDir().findChild(Lesson.LESSON_DIR + (firstLesson.getIndex() + 1));
+ if (lessonDir != null) {
+ VirtualFile taskDir = lessonDir.findChild(Task.TASK_DIR + (firstTask.getIndex() + 1));
+ if (taskDir != null) {
+ ProjectView.getInstance(project).select(taskDir, taskDir, true);
+ }
+ }
+ }
+ });
+ }
+ });
+ }
+}
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyTaskNavigationAction.java b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyTaskNavigationAction.java
index 46c0981cb964..b98bbd098776 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyTaskNavigationAction.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyTaskNavigationAction.java
@@ -1,5 +1,6 @@
package com.jetbrains.python.edu.actions;
+import com.intellij.ide.projectView.ProjectView;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.DumbAwareAction;
@@ -12,6 +13,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowId;
import com.intellij.openapi.wm.ToolWindowManager;
+import com.intellij.util.ui.tree.TreeUtil;
import com.jetbrains.python.edu.StudyState;
import com.jetbrains.python.edu.course.Lesson;
import com.jetbrains.python.edu.course.Task;
@@ -20,6 +22,7 @@ import com.jetbrains.python.edu.editor.StudyEditor;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
+import javax.swing.tree.TreePath;
import java.util.Map;
@@ -74,7 +77,11 @@ abstract public class StudyTaskNavigationAction extends DumbAwareAction {
}
}
}
+ JTree tree = ProjectView.getInstance(project).getCurrentProjectViewPane().getTree();
+ TreePath path = TreeUtil.getFirstNodePath(tree);
+ tree.collapsePath(path);
if (shouldBeActive != null) {
+ ProjectView.getInstance(project).select(shouldBeActive, shouldBeActive, false);
FileEditorManager.getInstance(project).openFile(shouldBeActive, true);
}
ToolWindow runToolWindow = ToolWindowManager.getInstance(project).getToolWindow(ToolWindowId.RUN);
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/projectView/StudyDirectoryNode.java b/python/edu/learn-python/src/com/jetbrains/python/edu/projectView/StudyDirectoryNode.java
index 2f80dba12695..d8faacd23946 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/projectView/StudyDirectoryNode.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/projectView/StudyDirectoryNode.java
@@ -1,8 +1,10 @@
package com.jetbrains.python.edu.projectView;
import com.intellij.ide.projectView.PresentationData;
+import com.intellij.ide.projectView.ProjectView;
import com.intellij.ide.projectView.ViewSettings;
import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode;
+import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
@@ -17,6 +19,7 @@ import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
+import java.util.Set;
public class StudyDirectoryNode extends PsiDirectoryNode {
private final PsiDirectory myValue;
@@ -110,4 +113,56 @@ public class StudyDirectoryNode extends PsiDirectoryNode {
data.addText(additionalName, new SimpleTextAttributes(Font.PLAIN, color));
data.setIcon(icon);
}
+
+ @Override
+ public boolean canNavigate() {
+ return true;
+ }
+
+ @Override
+ public boolean canNavigateToSource() {
+ return true;
+ }
+
+ @Override
+ public void navigate(boolean requestFocus) {
+ if (myValue.getName().contains(Task.TASK_DIR)) {
+ TaskFile taskFile = null;
+ VirtualFile virtualFile = null;
+ for (PsiElement child : myValue.getChildren()) {
+ VirtualFile childFile = child.getContainingFile().getVirtualFile();
+ taskFile = StudyTaskManager.getInstance(myProject).getTaskFile(childFile);
+ if (taskFile != null) {
+ virtualFile = childFile;
+ break;
+ }
+ }
+ if (taskFile != null) {
+ VirtualFile taskDir = virtualFile.getParent();
+ Task task = taskFile.getTask();
+ for (VirtualFile openFile : FileEditorManager.getInstance(myProject).getOpenFiles()) {
+ FileEditorManager.getInstance(myProject).closeFile(openFile);
+ }
+ VirtualFile child = null;
+ Set<String> fileNames = task.getTaskFiles().keySet();
+ for (String name : fileNames) {
+ child = taskDir.findChild(name);
+ if (child != null) {
+ FileEditorManager.getInstance(myProject).openFile(child, true);
+ }
+ }
+ if (child != null) {
+ ProjectView.getInstance(myProject).select(child, child, false);
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean expandOnDoubleClick() {
+ if (myValue.getName().contains(Task.TASK_DIR)) {
+ return false;
+ }
+ return super.expandOnDoubleClick();
+ }
}
diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyToolWindowFactory.java b/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyToolWindowFactory.java
index a553978c416a..0f8c5a53511a 100644
--- a/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyToolWindowFactory.java
+++ b/python/edu/learn-python/src/com/jetbrains/python/edu/ui/StudyToolWindowFactory.java
@@ -9,6 +9,7 @@ import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentFactory;
import com.intellij.util.ui.UIUtil;
import com.jetbrains.python.edu.StudyTaskManager;
+import com.jetbrains.python.edu.actions.StudyReloadCourseAction;
import com.jetbrains.python.edu.course.Course;
import com.jetbrains.python.edu.course.Lesson;
import com.jetbrains.python.edu.course.LessonInfo;
@@ -17,6 +18,8 @@ import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
import java.util.List;
public class StudyToolWindowFactory implements ToolWindowFactory, DumbAware {
@@ -41,7 +44,15 @@ public class StudyToolWindowFactory implements ToolWindowFactory, DumbAware {
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)));
+ JButton reloadCourseButton = new JButton("reload course");
+ reloadCourseButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ StudyReloadCourseAction.reloadCourse(project);
+ }
+ });
+ contentPanel.add(reloadCourseButton);
int taskNum = 0;
int taskSolved = 0;
int lessonsCompleted = 0;