diff options
Diffstat (limited to 'python/edu/learn-python/src/com')
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; |