add cross-course links in format #lessonName#taskName#

This commit is contained in:
Ekaterina Tuzova
2016-07-18 18:55:50 +03:00
parent 012310f025
commit 33d7918a87
5 changed files with 117 additions and 41 deletions
@@ -114,6 +114,7 @@ public class StudyUtils {
return fileName.contains(".zip");
}
@Nullable
public static <T> T getFirst(@NotNull final Iterable<T> container) {
Iterator<T> iterator = container.iterator();
if (!iterator.hasNext()) {
@@ -15,6 +15,7 @@ import com.jetbrains.edu.learning.core.EduNames;
import com.jetbrains.edu.learning.courseFormat.Task;
import com.jetbrains.edu.learning.courseFormat.TaskFile;
import com.jetbrains.edu.learning.editor.StudyEditor;
import com.jetbrains.edu.learning.navigation.StudyNavigator;
import com.jetbrains.edu.learning.statistics.EduUsagesCollector;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -76,7 +77,7 @@ abstract public class StudyTaskNavigationAction extends StudyActionWithShortcut
}
}
private static void updateProjectView(@NotNull Project project, VirtualFile shouldBeActive) {
public static void updateProjectView(@NotNull Project project, VirtualFile shouldBeActive) {
JTree tree = ProjectView.getInstance(project).getCurrentProjectViewPane().getTree();
if (shouldBeActive != null) {
ProjectView.getInstance(project).selectCB(shouldBeActive, shouldBeActive, false).doWhenDone(() -> {
@@ -113,32 +114,7 @@ abstract public class StudyTaskNavigationAction extends StudyActionWithShortcut
@Nullable
protected VirtualFile getFileToActivate(@NotNull Project project, Map<String, TaskFile> nextTaskFiles, VirtualFile taskDir) {
VirtualFile shouldBeActive = null;
for (Map.Entry<String, TaskFile> entry : nextTaskFiles.entrySet()) {
String name = entry.getKey();
TaskFile taskFile = entry.getValue();
VirtualFile srcDir = taskDir.findChild(EduNames.SRC);
VirtualFile vf = srcDir == null ? taskDir.findChild(name) : srcDir.findChild(name);
if (vf != null) {
if (shouldBeActive != null) {
FileEditorManager.getInstance(project).openFile(vf, true);
}
if (shouldBeActive == null && !taskFile.getAnswerPlaceholders().isEmpty()) {
shouldBeActive = vf;
}
}
}
return shouldBeActive != null ? shouldBeActive : getFirstTaskFile(taskDir, project);
}
@Nullable
private static VirtualFile getFirstTaskFile(@NotNull final VirtualFile taskDir, @NotNull final Project project) {
for (VirtualFile virtualFile : taskDir.getChildren()) {
if (StudyUtils.getTaskFile(project, virtualFile) != null) {
return virtualFile;
}
}
return null;
return StudyNavigator.getFileToActivate(project, nextTaskFiles, taskDir);
}
@Override
@@ -1,13 +1,22 @@
package com.jetbrains.edu.learning.navigation;
import com.intellij.ide.projectView.ProjectView;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.jetbrains.edu.learning.StudyTaskManager;
import com.jetbrains.edu.learning.StudyUtils;
import com.jetbrains.edu.learning.core.EduNames;
import com.jetbrains.edu.learning.courseFormat.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Map;
import static com.jetbrains.edu.learning.actions.StudyTaskNavigationAction.updateProjectView;
public class StudyNavigator {
private StudyNavigator() {
@@ -41,19 +50,20 @@ public class StudyNavigator {
return prevLesson.getTaskList().get(prevLesson.getTaskList().size() - 1);
}
public static Lesson nextLesson(@NotNull final Lesson lesson) {
public static Lesson nextLesson(@NotNull final Lesson lesson) {
List<Lesson> lessons = lesson.getCourse().getLessons();
int nextLessonIndex = lesson.getIndex();
if (nextLessonIndex >= lessons.size()) {
return null;
}
final Lesson nextLesson = lessons.get(nextLessonIndex);
if (EduNames.PYCHARM_ADDITIONAL.equals(nextLesson.getName()))
if (EduNames.PYCHARM_ADDITIONAL.equals(nextLesson.getName())) {
return null;
}
return nextLesson;
}
public static Lesson previousLesson(@NotNull final Lesson lesson) {
public static Lesson previousLesson(@NotNull final Lesson lesson) {
int prevLessonIndex = lesson.getIndex() - 2;
if (prevLessonIndex < 0) {
return null;
@@ -73,7 +83,7 @@ public class StudyNavigator {
}
}
public static void navigateToAnswerPlaceholder(@NotNull final Editor editor, @NotNull final AnswerPlaceholder answerPlaceholder) {
public static void navigateToAnswerPlaceholder(@NotNull final Editor editor, @NotNull final AnswerPlaceholder answerPlaceholder) {
if (editor.isDisposed()) {
return;
}
@@ -81,11 +91,84 @@ public class StudyNavigator {
}
public static void navigateToFirstAnswerPlaceholder(@NotNull final Editor editor, @NotNull final TaskFile taskFile) {
public static void navigateToFirstAnswerPlaceholder(@NotNull final Editor editor, @NotNull final TaskFile taskFile) {
if (!taskFile.getAnswerPlaceholders().isEmpty()) {
AnswerPlaceholder firstAnswerPlaceholder = StudyUtils.getFirst(taskFile.getAnswerPlaceholders());
if (firstAnswerPlaceholder == null) return;
navigateToAnswerPlaceholder(editor, firstAnswerPlaceholder);
}
}
@Nullable
public static VirtualFile getFileToActivate(@NotNull Project project, Map<String, TaskFile> nextTaskFiles, VirtualFile taskDir) {
VirtualFile shouldBeActive = null;
for (Map.Entry<String, TaskFile> entry : nextTaskFiles.entrySet()) {
String name = entry.getKey();
TaskFile taskFile = entry.getValue();
VirtualFile srcDir = taskDir.findChild(EduNames.SRC);
VirtualFile vf = srcDir == null ? taskDir.findChild(name) : srcDir.findChild(name);
if (vf != null) {
if (shouldBeActive != null) {
FileEditorManager.getInstance(project).openFile(vf, true);
}
if (shouldBeActive == null && !taskFile.getAnswerPlaceholders().isEmpty()) {
shouldBeActive = vf;
}
}
}
return shouldBeActive != null ? shouldBeActive : getFirstTaskFile(taskDir, project);
}
@Nullable
private static VirtualFile getFirstTaskFile(@NotNull final VirtualFile taskDir, @NotNull final Project project) {
for (VirtualFile virtualFile : taskDir.getChildren()) {
if (StudyUtils.getTaskFile(project, virtualFile) != null) {
return virtualFile;
}
}
return null;
}
public static void navigateToTask(@NotNull final Project project, @NotNull final String lessonName, @NotNull final String taskName) {
final Course course = StudyTaskManager.getInstance(project).getCourse();
if (course == null) {
return;
}
final Lesson lesson = course.getLesson(lessonName);
if (lesson == null) {
return;
}
final Task task = lesson.getTask(taskName);
if (task == null) {
return;
}
ApplicationManager.getApplication().invokeLater(() -> {
for (VirtualFile file : FileEditorManager.getInstance(project).getOpenFiles()) {
FileEditorManager.getInstance(project).closeFile(file);
}
int nextTaskIndex = task.getIndex();
int lessonIndex = task.getLesson().getIndex();
Map<String, TaskFile> nextTaskFiles = task.getTaskFiles();
VirtualFile projectDir = project.getBaseDir();
String lessonDirName = EduNames.LESSON + String.valueOf(lessonIndex);
if (projectDir == null) {
return;
}
VirtualFile lessonDir = projectDir.findChild(lessonDirName);
if (lessonDir == null) {
return;
}
String taskDirName = EduNames.TASK + String.valueOf(nextTaskIndex);
VirtualFile taskDir = lessonDir.findChild(taskDirName);
if (taskDir == null) {
return;
}
if (nextTaskFiles.isEmpty()) {
ProjectView.getInstance(project).select(taskDir, taskDir, false);
}
VirtualFile toActivate = getFileToActivate(project, nextTaskFiles, taskDir);
updateProjectView(project, toActivate);
});
}
}
@@ -9,8 +9,10 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.StreamUtil;
import com.jetbrains.edu.learning.StudyPluginConfigurator;
import com.jetbrains.edu.learning.navigation.StudyNavigator;
import javafx.application.Platform;
import javafx.concurrent.Worker;
import javafx.embed.swing.JFXPanel;
@@ -34,20 +36,25 @@ import java.awt.event.MouseEvent;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class StudyBrowserWindow extends JFrame {
private static final Logger LOG = Logger.getInstance(StudyToolWindow.class);
private static final String EVENT_TYPE_CLICK = "click";
private static final Pattern IN_COURSE_LINK = Pattern.compile("#(\\w+)#(\\w+)#");
private JFXPanel myPanel;
private WebView myWebComponent;
private StackPane myPane;
private WebEngine myEngine;
private ProgressBar myProgressBar;
private final Project myProject;
private boolean myLinkInNewBrowser = true;
private boolean myShowProgress = false;
public StudyBrowserWindow(final boolean linkInNewWindow, final boolean showProgress) {
public StudyBrowserWindow(@NotNull final Project project, final boolean linkInNewWindow, final boolean showProgress) {
myProject = project;
myLinkInNewBrowser = linkInNewWindow;
myShowProgress = showProgress;
setSize(new Dimension(900, 800));
@@ -218,13 +225,22 @@ public class StudyBrowserWindow extends JFrame {
public void handleEvent(Event ev) {
String domEventType = ev.getType();
if (domEventType.equals(EVENT_TYPE_CLICK)) {
myEngine.setJavaScriptEnabled(true);
myEngine.getLoadWorker().cancel();
ev.preventDefault();
final String href = getLink((Element)ev.getTarget());
if (href == null) return;
BrowserUtil.browse(href);
Element target = (Element)ev.getTarget();
String hrefAttribute = target.getAttribute("href");
final Matcher matcher = IN_COURSE_LINK.matcher(hrefAttribute);
if (matcher.matches()) {
final String lessonName = matcher.group(1);
final String taskName = matcher.group(2);
StudyNavigator.navigateToTask(myProject, lessonName, taskName);
}
else {
myEngine.setJavaScriptEnabled(true);
myEngine.getLoadWorker().cancel();
ev.preventDefault();
final String href = getLink(target);
if (href == null) return;
BrowserUtil.browse(href);
}
}
}
@@ -31,7 +31,7 @@ public class StudyJavaFxToolWindow extends StudyToolWindow {
@Override
public JComponent createTaskInfoPanel(Project project) {
myBrowserWindow = new StudyBrowserWindow(true, false);
myBrowserWindow = new StudyBrowserWindow(project, true, false);
myBrowserWindow.addBackAndOpenButtons();
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));