Merge remote-tracking branch 'origin/master'

This commit is contained in:
Anna Kozlova
2014-09-10 16:04:13 +04:00
4 changed files with 267 additions and 90 deletions
@@ -67,6 +67,7 @@
<action id="WelcomeScreen.LearnPython" class="com.jetbrains.python.edu.actions.StudyNewProject" icon="StudyIcons.EducationalProjectType">
<add-to-group group-id="WelcomeScreen.QuickStart" relative-to-action="WelcomeScreen.PythonIntro" anchor="after"/>
</action>
<action id="ReloadCourseAction" class="com.jetbrains.python.edu.actions.StudyReloadCourseAction"/>
</actions>
@@ -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());
}
}
@@ -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);
}
}
}
});
}
});
}
}
@@ -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;