diff --git a/python/educational/interactive-learning/resources/META-INF/plugin.xml b/python/educational/interactive-learning/resources/META-INF/plugin.xml
index 0c112e2e4bea..57adbc2196e7 100644
--- a/python/educational/interactive-learning/resources/META-INF/plugin.xml
+++ b/python/educational/interactive-learning/resources/META-INF/plugin.xml
@@ -50,9 +50,9 @@
description="Navigate to the next answer holder">
+ description="Navigate to the previous task"/>
+ description="Navigate to the next task"/>
-
+
blocks = documentImpl.getGuardedBlocks();
+ for (final RangeMarker block : blocks) {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ document.removeGuardedBlock(block);
+ }
+ });
+ }
+ });
+ }
+ }
+ }
}
diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyCheckAction.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyCheckAction.java
index 3b8e5f84e5ae..f92c883c9c92 100644
--- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyCheckAction.java
+++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyCheckAction.java
@@ -6,6 +6,7 @@ import com.intellij.execution.process.ProcessOutput;
import com.intellij.ide.projectView.ProjectView;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.KeyboardShortcut;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.diagnostic.Logger;
@@ -14,6 +15,7 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.TaskInfo;
@@ -43,9 +45,11 @@ import com.jetbrains.edu.learning.editor.StudyEditor;
import com.jetbrains.edu.learning.navigation.StudyNavigator;
import com.jetbrains.edu.learning.run.StudySmartChecker;
import com.jetbrains.edu.learning.run.StudyTestRunner;
+import icons.InteractiveLearningIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import javax.swing.*;
import java.awt.*;
import java.io.IOException;
import java.util.List;
@@ -58,6 +62,11 @@ public class StudyCheckAction extends DumbAwareAction {
public static final String ACTION_ID = "CheckAction";
public static final String SHORTCUT = "ctrl alt pressed ENTER";
+ boolean checkInProgress = false;
+
+ public StudyCheckAction() {
+ super("Check Task (" + KeymapUtil.getShortcutText(new KeyboardShortcut(KeyStroke.getKeyStroke(SHORTCUT), null)) + ")", "Check current task", InteractiveLearningIcons.Resolve);
+ }
private static void flushWindows(@NotNull final Task task, @NotNull final VirtualFile taskDir) {
for (Map.Entry entry : task.getTaskFiles().entrySet()) {
@@ -115,7 +124,7 @@ public class StudyCheckAction extends DumbAwareAction {
CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() {
@Override
public void run() {
- final StudyEditor selectedEditor = StudyEditor.getSelectedStudyEditor(project);
+ final StudyEditor selectedEditor = StudyUtils.getSelectedStudyEditor(project);
if (selectedEditor == null) return;
final StudyState studyState = new StudyState(selectedEditor);
if (!studyState.isValid()) {
@@ -158,7 +167,7 @@ public class StudyCheckAction extends DumbAwareAction {
if (testProcess == null) {
return;
}
- selectedEditor.getCheckButton().setEnabled(false);
+ checkInProgress = true;
ProgressManager.getInstance().run(getCheckTask(studyState, testRunner, testProcess, project, selectedEditor));
}
});
@@ -202,14 +211,14 @@ public class StudyCheckAction extends DumbAwareAction {
drawAllPlaceholders(project, task, taskDir);
ProjectView.getInstance(project).refresh();
deleteWindowDescriptions(task, taskDir);
- selectedEditor.getCheckButton().setEnabled(true);
+ checkInProgress = false;
}
@Override
public void onCancel() {
taskManager.setStatus(task, statusBeforeCheck);
deleteWindowDescriptions(task, taskDir);
- selectedEditor.getCheckButton().setEnabled(true);
+ checkInProgress = false;
}
@Override
@@ -382,7 +391,6 @@ public class StudyCheckAction extends DumbAwareAction {
StudyUtils.showCheckPopUp(project, balloon);
}
-
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
Project project = e.getProject();
@@ -390,4 +398,9 @@ public class StudyCheckAction extends DumbAwareAction {
check(project);
}
}
+
+ @Override
+ public void update(AnActionEvent e) {
+ e.getPresentation().setEnabled(!checkInProgress);
+ }
}
diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyEditInputAction.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyEditInputAction.java
index 24d6e31f3fb6..8b11fb42ffd5 100644
--- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyEditInputAction.java
+++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyEditInputAction.java
@@ -29,6 +29,7 @@ import com.jetbrains.edu.learning.StudyUtils;
import com.jetbrains.edu.learning.courseFormat.UserTest;
import com.jetbrains.edu.learning.editor.StudyEditor;
import com.jetbrains.edu.learning.ui.StudyTestContentPanel;
+import icons.InteractiveLearningIcons;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -46,8 +47,12 @@ public class StudyEditInputAction extends DumbAwareAction {
private JBEditorTabs tabbedPane;
private Map myEditableTabs = new HashMap();
+ public StudyEditInputAction() {
+ super("Watch Test Input", "Watch test input", InteractiveLearningIcons.WatchInput);
+ }
+
public void showInput(final Project project) {
- final Editor selectedEditor = StudyEditor.getSelectedEditor(project);
+ final Editor selectedEditor = StudyUtils.getSelectedEditor(project);
if (selectedEditor != null) {
FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance();
final VirtualFile openedFile = fileDocumentManager.getFile(selectedEditor.getDocument());
@@ -100,7 +105,7 @@ public class StudyEditInputAction extends DumbAwareAction {
.setMovable(true)
.setRequestFocus(true)
.createPopup();
- StudyEditor selectedStudyEditor = StudyEditor.getSelectedStudyEditor(project);
+ StudyEditor selectedStudyEditor = StudyUtils.getSelectedStudyEditor(project);
assert selectedStudyEditor != null;
hint.showInCenterOf(selectedStudyEditor.getComponent());
hint.addListener(new HintClosedListener(currentTask, studyTaskManager));
@@ -219,4 +224,19 @@ public class StudyEditInputAction extends DumbAwareAction {
}
}
}
+ @Override
+ public void update(final AnActionEvent e) {
+ EduUtils.enableAction(e, false);
+
+ final Project project = e.getProject();
+ if (project != null) {
+ StudyEditor studyEditor = StudyUtils.getSelectedStudyEditor(project);
+ if (studyEditor != null) {
+ final List userTests = StudyTaskManager.getInstance(project).getUserTests(studyEditor.getTaskFile().getTask());
+ if (!userTests.isEmpty()) {
+ EduUtils.enableAction(e, true);
+ }
+ }
+ }
+ }
}
diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyNextStudyTaskAction.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyNextStudyTaskAction.java
index 458039259122..d76308bac774 100644
--- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyNextStudyTaskAction.java
+++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyNextStudyTaskAction.java
@@ -1,7 +1,9 @@
package com.jetbrains.edu.learning.actions;
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.actionSystem.KeyboardShortcut;
+import com.intellij.openapi.keymap.KeymapUtil;
import com.jetbrains.edu.courseFormat.Task;
-import com.jetbrains.edu.learning.editor.StudyEditor;
import com.jetbrains.edu.learning.navigation.StudyNavigator;
import org.jetbrains.annotations.NotNull;
@@ -12,9 +14,8 @@ public class StudyNextStudyTaskAction extends StudyTaskNavigationAction {
public static final String ACTION_ID = "NextTaskAction";
public static final String SHORTCUT = "ctrl pressed PERIOD";
- @Override
- protected JButton getButton(@NotNull final StudyEditor selectedStudyEditor) {
- return selectedStudyEditor.getNextTaskButton();
+ public StudyNextStudyTaskAction() {
+ super("Next Task (" + KeymapUtil.getShortcutText(new KeyboardShortcut(KeyStroke.getKeyStroke(SHORTCUT), null)) + ")", "Navigate to the next task", AllIcons.Actions.Forward);
}
@Override
diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyPreviousStudyTaskAction.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyPreviousStudyTaskAction.java
index 35e8048f49ca..0c3d5b4088ce 100644
--- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyPreviousStudyTaskAction.java
+++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyPreviousStudyTaskAction.java
@@ -1,21 +1,22 @@
package com.jetbrains.edu.learning.actions;
+import com.intellij.openapi.actionSystem.KeyboardShortcut;
+import com.intellij.openapi.keymap.KeymapUtil;
import com.jetbrains.edu.courseFormat.Task;
-import com.jetbrains.edu.learning.editor.StudyEditor;
import com.jetbrains.edu.learning.navigation.StudyNavigator;
+import icons.InteractiveLearningIcons;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
public class StudyPreviousStudyTaskAction extends StudyTaskNavigationAction {
+ public StudyPreviousStudyTaskAction() {
+ super("Previous Task (" + KeymapUtil.getShortcutText(new KeyboardShortcut(KeyStroke.getKeyStroke(SHORTCUT), null)) + ")", "Navigate to the previous task", InteractiveLearningIcons.Prev);
+ }
public static final String ACTION_ID = "PreviousTaskAction";
public static final String SHORTCUT = "ctrl pressed COMMA";
- @Override
- protected JButton getButton(@NotNull final StudyEditor selectedStudyEditor) {
- return selectedStudyEditor.getPrevTaskButton();
- }
@Override
protected String getNavigationFinishedMessage() {
diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyRefreshTaskFileAction.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyRefreshTaskFileAction.java
index 9725e19043b4..151aec37dd85 100644
--- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyRefreshTaskFileAction.java
+++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyRefreshTaskFileAction.java
@@ -1,13 +1,16 @@
package com.jetbrains.edu.learning.actions;
+import com.intellij.icons.AllIcons;
import com.intellij.ide.projectView.ProjectView;
import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.KeyboardShortcut;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
@@ -35,6 +38,7 @@ import com.jetbrains.edu.learning.editor.StudyEditor;
import com.jetbrains.edu.learning.navigation.StudyNavigator;
import org.jetbrains.annotations.NotNull;
+import javax.swing.*;
import java.io.File;
public class StudyRefreshTaskFileAction extends DumbAwareAction {
@@ -42,6 +46,10 @@ public class StudyRefreshTaskFileAction extends DumbAwareAction {
public static final String SHORTCUT = "ctrl shift pressed X";
private static final Logger LOG = Logger.getInstance(StudyRefreshTaskFileAction.class.getName());
+ public StudyRefreshTaskFileAction() {
+ super("Reset Task File (" + KeymapUtil.getShortcutText(new KeyboardShortcut(KeyStroke.getKeyStroke(SHORTCUT), null)) + ")", "Refresh current task", AllIcons.Actions.Refresh);
+ }
+
public static void refresh(@NotNull final Project project) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
@@ -50,7 +58,7 @@ public class StudyRefreshTaskFileAction extends DumbAwareAction {
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
@Override
public void run() {
- StudyEditor studyEditor = StudyEditor.getSelectedStudyEditor(project);
+ StudyEditor studyEditor = StudyUtils.getSelectedStudyEditor(project);
StudyState studyState = new StudyState(studyEditor);
if (studyEditor == null || !studyState.isValid()) {
LOG.info("RefreshTaskFileAction was invoked outside of Study Editor");
@@ -101,9 +109,9 @@ public class StudyRefreshTaskFileAction extends DumbAwareAction {
BalloonBuilder balloonBuilder =
JBPopupFactory.getInstance().createHtmlTextBalloonBuilder(text, messageType, null);
final Balloon balloon = balloonBuilder.createBalloon();
- StudyEditor selectedStudyEditor = StudyEditor.getSelectedStudyEditor(project);
+ StudyEditor selectedStudyEditor = StudyUtils.getSelectedStudyEditor(project);
assert selectedStudyEditor != null;
- balloon.showInCenterOf(selectedStudyEditor.getRefreshButton());
+ balloon.show(StudyUtils.computeLocation(selectedStudyEditor.getEditor()), Balloon.Position.above);
Disposer.register(project, balloon);
}
@@ -120,7 +128,7 @@ public class StudyRefreshTaskFileAction extends DumbAwareAction {
@NotNull final Document document,
@NotNull final TaskFile taskFile,
String fileName) {
- StudyEditor.deleteGuardedBlocks(document);
+ StudyUtils.deleteGuardedBlocks(document);
taskFile.setTrackChanges(false);
clearDocument(document);
Task task = taskFile.getTask();
@@ -167,14 +175,14 @@ public class StudyRefreshTaskFileAction extends DumbAwareAction {
@Override
public void update(AnActionEvent event) {
+ EduUtils.enableAction(event, false);
final Project project = event.getProject();
if (project != null) {
- StudyEditor studyEditor = StudyEditor.getSelectedStudyEditor(project);
+ StudyEditor studyEditor = StudyUtils.getSelectedStudyEditor(project);
StudyState studyState = new StudyState(studyEditor);
if (studyState.isValid()) {
EduUtils.enableAction(event, true);
}
}
- EduUtils.enableAction(event, false);
}
}
diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyRunAction.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyRunAction.java
index 8bf70f564a7c..79b07c1453ed 100644
--- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyRunAction.java
+++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyRunAction.java
@@ -5,6 +5,7 @@ import com.intellij.execution.RunContentExecutor;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.process.OSProcessHandler;
import com.intellij.execution.process.ProcessHandler;
+import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
@@ -14,20 +15,29 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.VirtualFile;
+import com.jetbrains.edu.EduUtils;
import com.jetbrains.edu.courseFormat.Task;
import com.jetbrains.edu.courseFormat.TaskFile;
+import com.jetbrains.edu.learning.StudyTaskManager;
import com.jetbrains.edu.learning.StudyUtils;
+import com.jetbrains.edu.learning.courseFormat.UserTest;
import com.jetbrains.edu.learning.editor.StudyEditor;
import org.jetbrains.annotations.NotNull;
+import java.util.List;
+
public class StudyRunAction extends DumbAwareAction {
private static final Logger LOG = Logger.getInstance(StudyRunAction.class.getName());
public static final String ACTION_ID = "StudyRunAction";
private ProcessHandler myHandler;
+ public StudyRunAction() {
+ super("Run File With Tests", "Run your code with tests", AllIcons.General.Run);
+ }
+
public void run(@NotNull final Project project) {
if (myHandler != null && !myHandler.isProcessTerminated()) return;
- Editor selectedEditor = StudyEditor.getSelectedEditor(project);
+ Editor selectedEditor = StudyUtils.getSelectedEditor(project);
FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance();
assert selectedEditor != null;
VirtualFile openedFile = fileDocumentManager.getFile(selectedEditor.getDocument());
@@ -79,4 +89,20 @@ public class StudyRunAction extends DumbAwareAction {
run(project);
}
}
+
+ @Override
+ public void update(AnActionEvent e) {
+ EduUtils.enableAction(e, false);
+
+ final Project project = e.getProject();
+ if (project != null) {
+ StudyEditor studyEditor = StudyUtils.getSelectedStudyEditor(project);
+ if (studyEditor != null) {
+ final List userTests = StudyTaskManager.getInstance(project).getUserTests(studyEditor.getTaskFile().getTask());
+ if (!userTests.isEmpty()) {
+ EduUtils.enableAction(e, true);
+ }
+ }
+ }
+ }
}
diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyShowHintAction.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyShowHintAction.java
index ab3a25e10eef..a742ff0ae447 100644
--- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyShowHintAction.java
+++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyShowHintAction.java
@@ -3,8 +3,10 @@ package com.jetbrains.edu.learning.actions;
import com.intellij.codeInsight.documentation.DocumentationComponent;
import com.intellij.codeInsight.documentation.DocumentationManager;
import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.KeyboardShortcut;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.LogicalPosition;
+import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopup;
@@ -18,10 +20,11 @@ import com.jetbrains.edu.courseFormat.Course;
import com.jetbrains.edu.learning.StudyState;
import com.jetbrains.edu.learning.StudyTaskManager;
import com.jetbrains.edu.learning.StudyUtils;
-import com.jetbrains.edu.learning.editor.StudyEditor;
import icons.InteractiveLearningIcons;
import org.jetbrains.annotations.NotNull;
+import javax.swing.*;
+
public class StudyShowHintAction extends DumbAwareAction {
public static final String ACTION_ID = "ShowHintAction";
public static final String SHORTCUT = "ctrl pressed 7";
@@ -29,7 +32,7 @@ public class StudyShowHintAction extends DumbAwareAction {
public static final String HINT_NOT_AVAILABLE = "There is no hint for this answer placeholder";
public StudyShowHintAction() {
- super("Show hint", "Show hint", InteractiveLearningIcons.ShowHint);
+ super("Show hint (" + KeymapUtil.getShortcutText(new KeyboardShortcut(KeyStroke.getKeyStroke(SHORTCUT), null)) + ")", "Show hint", InteractiveLearningIcons.ShowHint);
}
public void actionPerformed(@NotNull AnActionEvent e) {
@@ -45,7 +48,7 @@ public class StudyShowHintAction extends DumbAwareAction {
if (course == null) {
return;
}
- StudyState studyState = new StudyState(StudyEditor.getSelectedStudyEditor(project));
+ StudyState studyState = new StudyState(StudyUtils.getSelectedStudyEditor(project));
if (!studyState.isValid()) {
return;
}
diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyTaskNavigationAction.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyTaskNavigationAction.java
index 015a18ff227d..eaa828be292a 100644
--- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyTaskNavigationAction.java
+++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyTaskNavigationAction.java
@@ -18,8 +18,10 @@ import com.jetbrains.edu.EduNames;
import com.jetbrains.edu.courseFormat.Task;
import com.jetbrains.edu.courseFormat.TaskFile;
import com.jetbrains.edu.learning.StudyState;
+import com.jetbrains.edu.learning.StudyUtils;
import com.jetbrains.edu.learning.editor.StudyEditor;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.tree.TreePath;
@@ -27,8 +29,12 @@ import java.util.Map;
abstract public class StudyTaskNavigationAction extends DumbAwareAction {
+ public StudyTaskNavigationAction(@Nullable String text, @Nullable String description, @Nullable Icon icon) {
+ super(text, description, icon);
+ }
+
public void navigateTask(@NotNull final Project project) {
- StudyEditor studyEditor = StudyEditor.getSelectedStudyEditor(project);
+ StudyEditor studyEditor = StudyUtils.getSelectedStudyEditor(project);
StudyState studyState = new StudyState(studyEditor);
if (!studyState.isValid()) {
return;
@@ -39,7 +45,7 @@ abstract public class StudyTaskNavigationAction extends DumbAwareAction {
JBPopupFactory.getInstance().createHtmlTextBalloonBuilder(getNavigationFinishedMessage(), MessageType.INFO, null);
Balloon balloon = balloonBuilder.createBalloon();
assert studyEditor != null;
- balloon.showInCenterOf(getButton(studyEditor));
+ balloon.show(StudyUtils.computeLocation(studyEditor.getEditor()), Balloon.Position.above);
return;
}
for (VirtualFile file : FileEditorManager.getInstance(project).getOpenFiles()) {
@@ -90,8 +96,6 @@ abstract public class StudyTaskNavigationAction extends DumbAwareAction {
}
}
- protected abstract JButton getButton(@NotNull final StudyEditor selectedStudyEditor);
-
@Override
public void actionPerformed(AnActionEvent e) {
Project project = e.getProject();
diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyWindowNavigationAction.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyWindowNavigationAction.java
index 6a00f0e22122..add5910357f0 100644
--- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyWindowNavigationAction.java
+++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyWindowNavigationAction.java
@@ -9,7 +9,6 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.jetbrains.edu.courseFormat.AnswerPlaceholder;
import com.jetbrains.edu.courseFormat.TaskFile;
import com.jetbrains.edu.learning.StudyUtils;
-import com.jetbrains.edu.learning.editor.StudyEditor;
import com.jetbrains.edu.learning.navigation.StudyNavigator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -23,7 +22,7 @@ abstract public class StudyWindowNavigationAction extends DumbAwareAction {
}
private void navigateToPlaceholder(@NotNull final Project project) {
- final Editor selectedEditor = StudyEditor.getSelectedEditor(project);
+ final Editor selectedEditor = StudyUtils.getSelectedEditor(project);
if (selectedEditor != null) {
final FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance();
final VirtualFile openedFile = fileDocumentManager.getFile(selectedEditor.getDocument());
diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/editor/StudyEditor.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/editor/StudyEditor.java
index 90b9afd9b60a..ae5366a50970 100644
--- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/editor/StudyEditor.java
+++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/editor/StudyEditor.java
@@ -1,405 +1,38 @@
package com.jetbrains.edu.learning.editor;
-import com.intellij.codeHighlighting.BackgroundEditorHighlighter;
-import com.intellij.icons.AllIcons;
-import com.intellij.ide.structureView.StructureViewBuilder;
-import com.intellij.openapi.actionSystem.ActionManager;
-import com.intellij.openapi.actionSystem.AnAction;
-import com.intellij.openapi.actionSystem.KeyboardShortcut;
-import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.editor.EditorFactory;
-import com.intellij.openapi.editor.RangeMarker;
-import com.intellij.openapi.editor.colors.EditorColorsManager;
-import com.intellij.openapi.editor.colors.EditorColorsScheme;
-import com.intellij.openapi.editor.impl.DocumentImpl;
-import com.intellij.openapi.fileEditor.*;
-import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
import com.intellij.openapi.fileEditor.impl.text.PsiAwareTextEditorImpl;
import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider;
-import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Disposer;
-import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.openapi.wm.IdeFocusManager;
-import com.intellij.openapi.wm.ToolWindow;
-import com.intellij.openapi.wm.ToolWindowId;
-import com.intellij.openapi.wm.ToolWindowManager;
-import com.intellij.pom.Navigatable;
-import com.intellij.ui.BrowserHyperlinkListener;
-import com.intellij.ui.HideableTitledPanel;
-import com.intellij.ui.JBColor;
-import com.intellij.util.ui.EmptyClipboardOwner;
-import com.intellij.util.ui.UIUtil;
import com.jetbrains.edu.EduDocumentListener;
-import com.jetbrains.edu.courseFormat.Task;
import com.jetbrains.edu.courseFormat.TaskFile;
-import com.jetbrains.edu.learning.StudyTaskManager;
import com.jetbrains.edu.learning.StudyUtils;
-import com.jetbrains.edu.learning.actions.*;
-import com.jetbrains.edu.learning.courseFormat.UserTest;
-import icons.InteractiveLearningIcons;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import javax.swing.*;
-import javax.swing.border.EmptyBorder;
-import javax.swing.text.MutableAttributeSet;
-import javax.swing.text.StyleConstants;
-import javax.swing.text.StyledDocument;
-import java.awt.*;
-import java.awt.datatransfer.StringSelection;
-import java.awt.event.*;
-import java.beans.PropertyChangeListener;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
/**
* Implementation of StudyEditor which has panel with special buttons and task text
* also @see {@link StudyFileEditorProvider}
*/
-public class StudyEditor implements TextEditor {
- private static final String TASK_TEXT_HEADER = "Task Text";
- private final FileEditor myDefaultEditor;
- private final JComponent myComponent;
+public class StudyEditor extends PsiAwareTextEditorImpl {
private final TaskFile myTaskFile;
- private JButton myCheckButton;
- private JButton myNextTaskButton;
- private JButton myPrevTaskButton;
- private JButton myRefreshButton;
private static final Map myDocumentListeners = new HashMap();
- private final Project myProject;
-
- public JButton getCheckButton() {
- return myCheckButton;
- }
-
- public JButton getPrevTaskButton() {
- return myPrevTaskButton;
- }
public TaskFile getTaskFile() {
return myTaskFile;
}
- private static JButton addButton(@NotNull final JComponent parentComponent, @NotNull final String actionID,
- @NotNull final Icon icon, @Nullable String defaultShortcutString) {
- final AnAction action = ActionManager.getInstance().getAction(actionID);
- String toolTipText = KeymapUtil.createTooltipText(action.getTemplatePresentation().getText(), action);
- if (!toolTipText.contains("(") && defaultShortcutString != null) {
- KeyboardShortcut shortcut = new KeyboardShortcut(KeyStroke.getKeyStroke(defaultShortcutString), null);
- toolTipText += " (" + KeymapUtil.getShortcutText(shortcut) + ")";
- }
- final JButton newButton = new JButton();
- newButton.setToolTipText(toolTipText);
- newButton.setIcon(icon);
- newButton.setSize(new Dimension(icon.getIconWidth(), icon.getIconHeight()));
- parentComponent.add(newButton);
- return newButton;
- }
-
public static void addDocumentListener(@NotNull final Document document, @NotNull final EduDocumentListener listener) {
document.addDocumentListener(listener);
myDocumentListeners.put(document, listener);
}
public StudyEditor(@NotNull final Project project, @NotNull final VirtualFile file) {
- myProject = project;
- myDefaultEditor = TextEditorProvider.getInstance().createEditor(myProject, file);
- myComponent = myDefaultEditor.getComponent();
- final JPanel studyPanel = new JPanel();
- studyPanel.setLayout(new BoxLayout(studyPanel, BoxLayout.Y_AXIS));
+ super(project, file, TextEditorProvider.getInstance());
myTaskFile = StudyUtils.getTaskFile(project, file);
- if (myTaskFile != null) {
- final Task currentTask = myTaskFile.getTask();
- final String taskText = currentTask.getText();
- //initializeTaskText(studyPanel, taskText);
- final JPanel studyButtonPanel = new JPanel(new GridLayout(1, 2));
- final JPanel taskActionsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
- studyButtonPanel.add(taskActionsPanel);
- studyButtonPanel.add(new JPanel());
- initializeButtons(taskActionsPanel, myTaskFile);
- studyPanel.add(studyButtonPanel);
- myComponent.add(studyPanel, BorderLayout.NORTH);
- }
- }
-
- class CopyListener extends MouseAdapter {
- final JTextPane myTextPane;
-
- public CopyListener(@NotNull final JTextPane textPane) {
- myTextPane = textPane;
- }
-
- @Override
- public void mouseReleased(MouseEvent e) {
- ApplicationManager.getApplication().invokeLater(new Runnable() {
- @Override
- public void run() {
- final ToolWindow projectView = ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PROJECT_VIEW);
- if (projectView == null) {
- return;
- }
- final Component focusComponent = projectView.getComponent();
- IdeFocusManager.getInstance(myProject).requestFocus(focusComponent, true);
- final String text = myTextPane.getSelectedText();
- if (text == null) {
- return;
- }
- KeyAdapter keyAdapter = new KeyAdapter() {
- @Override
- public void keyPressed(KeyEvent ev) {
- if (ev.getKeyCode() == KeyEvent.VK_C
- && ev.getModifiers() == InputEvent.CTRL_MASK) {
- final StringSelection selection = new StringSelection(text);
- Toolkit.getDefaultToolkit().getSystemClipboard().setContents(selection, EmptyClipboardOwner.INSTANCE);
- ApplicationManager.getApplication().invokeLater(new Runnable() {
- @Override
- public void run() {
- IdeFocusManager.getInstance(myProject).requestFocus(myDefaultEditor.getComponent(), true);
- }
- });
- }
- }
- };
- focusComponent.addKeyListener(keyAdapter);
- }
- });
- }
- }
-
- private void initializeTaskText(@NotNull final JPanel studyPanel, @Nullable final String taskText) {
- final JTextPane taskTextPane = new JTextPane();
- taskTextPane.addMouseListener(new CopyListener(taskTextPane));
- taskTextPane.setContentType("text/html");
- taskTextPane.setEditable(false);
- taskTextPane.setText(taskText);
- taskTextPane.addHyperlinkListener(BrowserHyperlinkListener.INSTANCE);
- final EditorColorsScheme editorColorsScheme = EditorColorsManager.getInstance().getGlobalScheme();
- int fontSize = editorColorsScheme.getEditorFontSize();
- final String fontName = editorColorsScheme.getEditorFontName();
- setJTextPaneFont(taskTextPane, new Font(fontName, Font.PLAIN, fontSize));
- taskTextPane.setBackground(UIUtil.getPanelBackground());
- taskTextPane.setBorder(new EmptyBorder(15, 20, 0, 100));
- final HideableTitledPanel taskTextPanel = new HideableTitledPanel(TASK_TEXT_HEADER, taskTextPane, true);
- taskTextPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
- studyPanel.add(taskTextPanel);
- }
-
- private static void setJTextPaneFont(@NotNull final JTextPane textPane, @NotNull final Font font) {
- final MutableAttributeSet attrs = textPane.getInputAttributes();
- StyleConstants.setFontFamily(attrs, font.getFamily());
- StyleConstants.setFontSize(attrs, font.getSize());
- StyleConstants.setItalic(attrs, (font.getStyle() & Font.ITALIC) != 0);
- StyleConstants.setBold(attrs, (font.getStyle() & Font.BOLD) != 0);
- StyleConstants.setForeground(attrs, JBColor.BLACK);
- StyledDocument doc = textPane.getStyledDocument();
- doc.setCharacterAttributes(0, doc.getLength() + 1, attrs, false);
- }
-
- private void initializeButtons(@NotNull final JPanel taskActionsPanel, @NotNull final TaskFile taskFile) {
- myCheckButton = addButton(taskActionsPanel, StudyCheckAction.ACTION_ID, InteractiveLearningIcons.Resolve, StudyCheckAction.SHORTCUT);
- myPrevTaskButton = addButton(taskActionsPanel, StudyPreviousStudyTaskAction.ACTION_ID, InteractiveLearningIcons.Prev, StudyPreviousStudyTaskAction.SHORTCUT);
- myNextTaskButton = addButton(taskActionsPanel, StudyNextStudyTaskAction.ACTION_ID, AllIcons.Actions.Forward, StudyNextStudyTaskAction.SHORTCUT);
- myRefreshButton = addButton(taskActionsPanel, StudyRefreshTaskFileAction.ACTION_ID, AllIcons.Actions.Refresh, StudyRefreshTaskFileAction.SHORTCUT);
- final JButton myShowHintButton = addButton(taskActionsPanel, StudyShowHintAction.ACTION_ID, InteractiveLearningIcons.ShowHint, StudyShowHintAction.SHORTCUT);
- final List userTests = StudyTaskManager.getInstance(myProject).getUserTests(taskFile.getTask());
- if (!userTests.isEmpty()) {
- final JButton runButton = addButton(taskActionsPanel, StudyRunAction.ACTION_ID, AllIcons.General.Run, null);
- runButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- StudyRunAction studyRunAction = (StudyRunAction)ActionManager.getInstance().getAction("StudyRunAction");
- studyRunAction.run(myProject);
- }
- });
- final JButton watchInputButton = addButton(taskActionsPanel, "WatchInputAction", InteractiveLearningIcons.WatchInput, null);
- watchInputButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- StudyEditInputAction studyEditInputAction =
- (StudyEditInputAction)ActionManager.getInstance().getAction("WatchInputAction");
- studyEditInputAction.showInput(myProject);
- }
- });
- }
- initializeButtonActions(myShowHintButton);
- }
-
- protected void initializeButtonActions(JButton myShowHintButton) {
- myCheckButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- StudyCheckAction studyCheckAction = (StudyCheckAction)ActionManager.getInstance().getAction("CheckAction");
- studyCheckAction.check(myProject);
- }
- });
-
- myNextTaskButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- StudyNextStudyTaskAction studyNextTaskAction =
- (StudyNextStudyTaskAction)ActionManager.getInstance().getAction("NextTaskAction");
- studyNextTaskAction.navigateTask(myProject);
- }
- });
- myPrevTaskButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- StudyPreviousStudyTaskAction
- prevTaskAction = (StudyPreviousStudyTaskAction)ActionManager.getInstance().getAction("PreviousTaskAction");
- prevTaskAction.navigateTask(myProject);
- }
- });
- myRefreshButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- StudyRefreshTaskFileAction.refresh(myProject);
- }
- });
-
- myShowHintButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- StudyShowHintAction.showHint(myProject);
- }
- });
- }
-
- public JButton getNextTaskButton() {
- return myNextTaskButton;
- }
-
- public JButton getRefreshButton() {
- return myRefreshButton;
- }
-
- private FileEditor getDefaultEditor() {
- return myDefaultEditor;
- }
-
- @NotNull
- @Override
- public JComponent getComponent() {
- return myComponent;
- }
-
- @Nullable
- @Override
- public JComponent getPreferredFocusedComponent() {
- return myDefaultEditor.getPreferredFocusedComponent();
- }
-
- @NotNull
- @Override
- public String getName() {
- return "Study Editor";
- }
-
- @NotNull
- @Override
- public FileEditorState getState(@NotNull FileEditorStateLevel level) {
- return myDefaultEditor.getState(level);
- }
-
- @Override
- public void setState(@NotNull FileEditorState state) {
- myDefaultEditor.setState(state);
- }
-
- @Override
- public boolean isModified() {
- return myDefaultEditor.isModified();
- }
-
- @Override
- public boolean isValid() {
- return myDefaultEditor.isValid();
- }
-
- @Override
- public void selectNotify() {
- myDefaultEditor.selectNotify();
- }
-
- @Override
- public void deselectNotify() {
- myDefaultEditor.deselectNotify();
- }
-
- @Override
- public void addPropertyChangeListener(@NotNull PropertyChangeListener listener) {
- myDefaultEditor.addPropertyChangeListener(listener);
- }
-
- @Override
- public void removePropertyChangeListener(@NotNull PropertyChangeListener listener) {
- myDefaultEditor.removePropertyChangeListener(listener);
- }
-
- @Nullable
- @Override
- public BackgroundEditorHighlighter getBackgroundHighlighter() {
- return myDefaultEditor.getBackgroundHighlighter();
- }
-
- @Nullable
- @Override
- public FileEditorLocation getCurrentLocation() {
- return myDefaultEditor.getCurrentLocation();
- }
-
- @Nullable
- @Override
- public StructureViewBuilder getStructureViewBuilder() {
- return myDefaultEditor.getStructureViewBuilder();
- }
-
- @Override
- public void dispose() {
- Disposer.dispose(myDefaultEditor);
- }
-
- @Nullable
- @Override
- public T getUserData(@NotNull Key key) {
- return myDefaultEditor.getUserData(key);
- }
-
- @Override
- public void putUserData(@NotNull Key key, @Nullable T value) {
- myDefaultEditor.putUserData(key, value);
- }
-
-
- @Nullable
- public static StudyEditor getSelectedStudyEditor(@NotNull final Project project) {
- try {
- final FileEditor fileEditor = FileEditorManagerEx.getInstanceEx(project).getSplitters().getCurrentWindow().
- getSelectedEditor().getSelectedEditorWithProvider().getFirst();
- if (fileEditor instanceof StudyEditor) {
- return (StudyEditor)fileEditor;
- }
- }
- catch (Exception e) {
- return null;
- }
- return null;
- }
-
- @Nullable
- public static Editor getSelectedEditor(@NotNull final Project project) {
- final StudyEditor studyEditor = getSelectedStudyEditor(project);
- if (studyEditor != null) {
- FileEditor defaultEditor = studyEditor.getDefaultEditor();
- if (defaultEditor instanceof PsiAwareTextEditorImpl) {
- return ((PsiAwareTextEditorImpl)defaultEditor).getEditor();
- }
- }
- return null;
}
public static void removeListener(Document document) {
@@ -409,48 +42,4 @@ public class StudyEditor implements TextEditor {
}
myDocumentListeners.remove(document);
}
-
- @NotNull
- @Override
- public Editor getEditor() {
- if (myDefaultEditor instanceof TextEditor) {
- return ((TextEditor)myDefaultEditor).getEditor();
- }
- return EditorFactory.getInstance().createViewer(new DocumentImpl(""), myProject);
- }
-
- @Override
- public boolean canNavigateTo(@NotNull Navigatable navigatable) {
- if (myDefaultEditor instanceof TextEditor) {
- ((TextEditor)myDefaultEditor).canNavigateTo(navigatable);
- }
- return false;
- }
-
- @Override
- public void navigateTo(@NotNull Navigatable navigatable) {
- if (myDefaultEditor instanceof TextEditor) {
- ((TextEditor)myDefaultEditor).navigateTo(navigatable);
- }
- }
-
- public static void deleteGuardedBlocks(@NotNull final Document document) {
- if (document instanceof DocumentImpl) {
- final DocumentImpl documentImpl = (DocumentImpl)document;
- List blocks = documentImpl.getGuardedBlocks();
- for (final RangeMarker block : blocks) {
- ApplicationManager.getApplication().invokeLater(new Runnable() {
- @Override
- public void run() {
- ApplicationManager.getApplication().runWriteAction(new Runnable() {
- @Override
- public void run() {
- document.removeGuardedBlock(block);
- }
- });
- }
- });
- }
- }
- }
}
diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/editor/StudyEditorFactoryListener.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/editor/StudyEditorFactoryListener.java
index 1a04083a612e..66b06933e321 100644
--- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/editor/StudyEditorFactoryListener.java
+++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/editor/StudyEditorFactoryListener.java
@@ -9,11 +9,14 @@ import com.intellij.openapi.editor.event.EditorFactoryListener;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.wm.ToolWindow;
+import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.problems.WolfTheProblemSolver;
import com.jetbrains.edu.EduDocumentListener;
import com.jetbrains.edu.courseFormat.TaskFile;
import com.jetbrains.edu.learning.StudyUtils;
import com.jetbrains.edu.learning.navigation.StudyNavigator;
+import com.jetbrains.edu.learning.ui.StudyToolWindowFactory;
import org.jetbrains.annotations.NotNull;
@@ -43,6 +46,13 @@ public class StudyEditorFactoryListener implements EditorFactoryListener {
StudyEditor.addDocumentListener(document, new EduDocumentListener(taskFile));
WolfTheProblemSolver.getInstance(project).clearProblems(openedFile);
StudyUtils.drawAllWindows(editor, taskFile);
+
+ final ToolWindow studyToolWindow = ToolWindowManager.getInstance(project).getToolWindow(StudyToolWindowFactory.STUDY_TOOL_WINDOW);
+ if (studyToolWindow != null) {
+ StudyUtils.updateStudyToolWindow(project);
+ studyToolWindow.show(null);
+ }
+
}
}
}
diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyCondition.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyCondition.java
index 46ac007e4dc7..4895bc04faf7 100644
--- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyCondition.java
+++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyCondition.java
@@ -1,26 +1,15 @@
package com.jetbrains.edu.learning.ui;
import com.intellij.openapi.project.DumbAware;
-import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
-import com.jetbrains.edu.learning.StudyTaskManager;
/**
* author: liana
* data: 7/29/14.
*/
public class StudyCondition implements Condition, DumbAware {
- public static boolean VALUE = false;
@Override
public boolean value(Object o) {
- if (o instanceof Project) {
- Project project = (Project) o;
- StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
- if (taskManager.getCourse() != null) {
- //noinspection AssignmentToStaticFieldFromInstanceMethod
- VALUE = true;
- }
- }
return false;
}
}
diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyToolWindow.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyToolWindow.java
new file mode 100644
index 000000000000..f31cfa98e28d
--- /dev/null
+++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyToolWindow.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2000-2015 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.edu.learning.ui;
+
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.actionSystem.ActionManager;
+import com.intellij.openapi.actionSystem.ActionToolbar;
+import com.intellij.openapi.actionSystem.DataProvider;
+import com.intellij.openapi.actionSystem.DefaultActionGroup;
+import com.intellij.openapi.editor.colors.EditorColorsManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.SimpleToolWindowPanel;
+import com.intellij.ui.BrowserHyperlinkListener;
+import com.intellij.util.ui.JBUI;
+import com.jetbrains.edu.courseFormat.Task;
+import com.jetbrains.edu.learning.StudyUtils;
+import com.jetbrains.edu.learning.actions.*;
+import com.jetbrains.edu.learning.editor.StudyEditor;
+
+import javax.swing.*;
+import javax.swing.border.EmptyBorder;
+
+public class StudyToolWindow extends SimpleToolWindowPanel implements DataProvider, Disposable {
+
+ private final JPanel myToolbarPanel;
+
+ public StudyToolWindow(final Project project) {
+ super(true, true);
+ myToolbarPanel = createToolbarPanel();
+ setToolbar(myToolbarPanel);
+
+ final StudyEditor studyEditor = StudyUtils.getSelectedStudyEditor(project);
+ if (studyEditor == null) return;
+ Task task = studyEditor.getTaskFile().getTask();
+
+ if (task != null) {
+ final String taskText = task.getText();
+
+ final JTextPane taskTextPane = new JTextPane();
+ taskTextPane.setContentType("text/html");
+ taskTextPane.setEditable(false);
+ taskTextPane.setText(taskText);
+ taskTextPane.addHyperlinkListener(BrowserHyperlinkListener.INSTANCE);
+ taskTextPane.setBackground(EditorColorsManager.getInstance().getGlobalScheme().getDefaultBackground());
+ taskTextPane.setBorder(new EmptyBorder(15, 20, 0, 100));
+ setContent(taskTextPane);
+ }
+ }
+
+ public void dispose() {
+ }
+
+ private static JPanel createToolbarPanel() {
+ final DefaultActionGroup group = new DefaultActionGroup();
+ group.add(new StudyCheckAction());
+ group.add(new StudyPreviousStudyTaskAction());
+ group.add(new StudyNextStudyTaskAction());
+ group.add(new StudyRefreshTaskFileAction());
+ group.add(new StudyShowHintAction());
+
+ group.add(new StudyRunAction());
+ group.add(new StudyEditInputAction());
+
+ final ActionToolbar actionToolBar = ActionManager.getInstance().createActionToolbar("Study", group, true);
+ return JBUI.Panels.simplePanel(actionToolBar.getComponent());
+ }
+
+}
diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyToolWindowFactory.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyToolWindowFactory.java
index 0539c68a9965..4522064be221 100644
--- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyToolWindowFactory.java
+++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyToolWindowFactory.java
@@ -2,90 +2,31 @@ package com.jetbrains.edu.learning.ui;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowFactory;
import com.intellij.ui.content.Content;
-import com.intellij.ui.content.ContentFactory;
-import com.intellij.util.ui.UIUtil;
+import com.intellij.ui.content.ContentManager;
import com.jetbrains.edu.courseFormat.Course;
-import com.jetbrains.edu.courseFormat.Lesson;
-import com.jetbrains.edu.courseFormat.Task;
import com.jetbrains.edu.learning.StudyTaskManager;
-import com.jetbrains.edu.learning.courseFormat.StudyStatus;
import org.jetbrains.annotations.NotNull;
-import javax.swing.*;
-import java.awt.*;
-import java.util.List;
-
public class StudyToolWindowFactory implements ToolWindowFactory, DumbAware {
- public static final String STUDY_TOOL_WINDOW = "Course Description";
+ public static final String STUDY_TOOL_WINDOW = "Task Description";
@Override
public void createToolWindowContent(@NotNull final Project project, @NotNull final ToolWindow toolWindow) {
- JPanel contentPanel = new JPanel();
StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
- if (taskManager.getCourse() != null) {
- contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.PAGE_AXIS));
- contentPanel.add(Box.createRigidArea(new Dimension(10, 0)));
+ final Course course = taskManager.getCourse();
+ if (course != null) {
+ final StudyToolWindow studyToolWindow = new StudyToolWindow(project);
+ final ContentManager contentManager = toolWindow.getContentManager();
+ final Content content = contentManager.getFactory().createContent(studyToolWindow, null, false);
+ contentManager.addContent(content);
+ Disposer.register(project, studyToolWindow);
- Course course = taskManager.getCourse();
- if (course == null) {
- return;
- }
- String courseName = UIUtil.toHtml("" + course.getName() + "
", 10);
- String description = UIUtil.toHtml(course.getDescription(), 5);
- String authorLabel = UIUtil.toHtml("Author: " + Course.getAuthorsString(course.getAuthors()), 5);
- 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;
- List lessons = course.getLessons();
- for (Lesson lesson : lessons) {
- StudyStatus status = taskManager.getStatus(lesson);
- if (status == StudyStatus.Solved) {
- lessonsCompleted++;
- }
- taskNum += lesson.getTaskList().size();
- taskSolved += getSolvedTasks(lesson, taskManager);
- }
- 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);
- contentPanel.add(Box.createVerticalStrut(10));
- addStatistics(completedLessons, contentPanel);
- addStatistics(completedTasks, contentPanel);
-
- double percent = (taskSolved * 100.0) / taskNum;
- contentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
- StudyProgressBar studyProgressBar = new StudyProgressBar(percent / 100, 40, 10);
- contentPanel.add(studyProgressBar);
- addStatistics(tasksLeft, contentPanel);
- ContentFactory contentFactory = ContentFactory.SERVICE.getInstance();
- Content content = contentFactory.createContent(contentPanel, "", true);
- toolWindow.getContentManager().addContent(content);
}
}
- private static int getSolvedTasks(@NotNull final Lesson lesson, StudyTaskManager taskManager) {
- int solved = 0;
- for (Task task : lesson.getTaskList()) {
- if (taskManager.getStatus(task) == StudyStatus.Solved) {
- solved += 1;
- }
- }
- return solved;
- }
-
- private static void addStatistics(String statistics, JPanel contentPanel) {
- String labelText = UIUtil.toHtml(statistics, 5);
- contentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
- JLabel statisticLabel = new JLabel(labelText);
- contentPanel.add(statisticLabel);
- }
}