Create super class for all toolbar action, so they provide action id and action shortcut to be added
<action id="Edu.NewScratchFile" class="com.intellij.ide.scratch.ScratchFileActions$NewFileAction" text="New Scratch File...">
<add-to-group group-id="FileOpenGroup" relative-to-action="OpenFile" anchor="before"/>
</action>
-
- <action id="CheckAction" class="com.jetbrains.edu.learning.actions.StudyCheckAction" text="Check Task"
- description="Check current task">
- </action>
<action id="PrevWindowAction" class="com.jetbrains.edu.learning.actions.StudyPrevWindowAction" text="Previous Answer Placeholder"
description="Navigate to the previous answer placeholder">
</action>
<extendWordSelectionHandler implementation="com.jetbrains.edu.learning.StudyAnswerPlaceholderExtendWordHandler"/>
<renameHandler implementation="com.jetbrains.edu.learning.StudyRenameHandler"/>
<refactoring.moveHandler implementation="com.jetbrains.edu.learning.StudyMoveDelegate" order="first"/>
- <applicationService serviceInterface="com.intellij.openapi.fileEditor.impl.EditorEmptyTextPainter"
- serviceImplementation="com.jetbrains.edu.learning.StudyInstructionPainter" overrides="true"/>
</extensions>
</idea-plugin>
\ No newline at end of file
+++ /dev/null
-package com.jetbrains.edu.learning;
-
-import com.intellij.openapi.actionSystem.KeyboardShortcut;
-import com.intellij.openapi.fileEditor.impl.EditorEmptyTextPainter;
-import com.intellij.openapi.keymap.KeymapUtil;
-import com.intellij.util.PlatformUtils;
-import com.intellij.util.ui.UIUtil;
-import com.jetbrains.edu.learning.actions.*;
-import com.jetbrains.edu.learning.ui.StudyProgressToolWindowFactory;
-import org.jetbrains.annotations.NotNull;
-
-import javax.swing.*;
-
-public class StudyInstructionPainter extends EditorEmptyTextPainter {
- private static final String separator = " / ";
- @Override
- protected void advertiseActions(@NotNull JComponent splitters, @NotNull UIUtil.TextPainter painter) {
- if (PlatformUtils.isPyCharmEducational()) {
- String shortcut = KeymapUtil.getShortcutText(new KeyboardShortcut(KeyStroke.getKeyStroke(StudyNextWindowAction.SHORTCUT2), null));
- appendAction(painter, "Navigate to the next answer placeholder", shortcut);
- appendAction(painter, "Navigate between answer placeholders", getActionShortcutText(StudyPrevWindowAction.ACTION_ID) + separator +
- getActionShortcutText(StudyNextWindowAction.ACTION_ID));
- appendAction(painter, "Navigate between tasks", getActionShortcutText(StudyPreviousStudyTaskAction.ACTION_ID) + separator +
- getActionShortcutText(StudyNextStudyTaskAction.ACTION_ID));
- appendAction(painter, "Reset current task file", getActionShortcutText(StudyRefreshTaskFileAction.ACTION_ID));
- appendAction(painter, "Check task", getActionShortcutText(StudyCheckAction.ACTION_ID));
- appendAction(painter, "Get hint for the answer placeholder", getActionShortcutText(StudyShowHintAction.ACTION_ID));
- appendLine(painter, "To see your progress open the '" + StudyProgressToolWindowFactory.ID + "' panel");
- } else {
- super.advertiseActions(splitters, painter);
- }
- }
-}
\ No newline at end of file
import com.jetbrains.edu.courseFormat.Lesson;
import com.jetbrains.edu.courseFormat.Task;
import com.jetbrains.edu.courseFormat.TaskFile;
-import com.jetbrains.edu.learning.actions.*;
+import com.jetbrains.edu.learning.actions.StudyToolbarAction;
import com.jetbrains.edu.learning.editor.StudyEditorFactoryListener;
import com.jetbrains.edu.learning.ui.StudyProgressToolWindowFactory;
+import com.jetbrains.edu.learning.ui.StudyToolWindow;
import com.jetbrains.edu.learning.ui.StudyToolWindowFactory;
import javafx.application.Platform;
import org.jetbrains.annotations.NotNull;
}
private void registerShortcuts() {
- addShortcut(StudyNextWindowAction.ACTION_ID, new String[]{StudyNextWindowAction.SHORTCUT, StudyNextWindowAction.SHORTCUT2});
- addShortcut(StudyPrevWindowAction.ACTION_ID, new String[]{StudyPrevWindowAction.SHORTCUT});
- addShortcut(StudyShowHintAction.ACTION_ID, new String[]{StudyShowHintAction.SHORTCUT});
- addShortcut(StudyCheckAction.ACTION_ID, new String[]{StudyCheckAction.SHORTCUT});
- addShortcut(StudyNextStudyTaskAction.ACTION_ID, new String[]{StudyNextStudyTaskAction.SHORTCUT});
- addShortcut(StudyPreviousStudyTaskAction.ACTION_ID, new String[]{StudyPreviousStudyTaskAction.SHORTCUT});
- addShortcut(StudyRefreshTaskFileAction.ACTION_ID, new String[]{StudyRefreshTaskFileAction.SHORTCUT});
+ StudyToolWindow window = StudyUtils.getStudyToolWindow(myProject);
+ if (window != null) {
+ List<AnAction> actionsOnToolbar = window.getActions(true);
+ if (actionsOnToolbar != null) {
+ for (AnAction action : actionsOnToolbar) {
+ if (action instanceof StudyToolbarAction) {
+ String id = ((StudyToolbarAction)action).getActionId();
+ String[] shortcuts = ((StudyToolbarAction)action).getShortcuts();
+ addShortcut(id, shortcuts);
+ }
+ }
+ }
+ else {
+ LOG.warn("Actions on toolbar are nulls");
+ }
+ }
}
private void registerToolWindows(@NotNull final ToolWindowManager toolWindowManager) {
+++ /dev/null
-package com.jetbrains.edu.learning.actions;
-
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.KeyboardShortcut;
-import com.intellij.openapi.actionSystem.Presentation;
-import com.intellij.openapi.keymap.KeymapUtil;
-import com.intellij.openapi.project.DumbAwareAction;
-import com.intellij.openapi.project.DumbService;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.MessageType;
-import com.intellij.openapi.util.Ref;
-import com.jetbrains.edu.learning.StudyUtils;
-import com.jetbrains.edu.learning.checker.StudyCheckUtils;
-import icons.InteractiveLearningIcons;
-import org.jetbrains.annotations.NotNull;
-
-import javax.swing.*;
-
-
-public class StudyCheckAction extends DumbAwareAction {
-
- public static final String ACTION_ID = "CheckAction";
- public static final String SHORTCUT = "ctrl alt pressed ENTER";
-
- protected Ref<Boolean> myCheckInProgress = new Ref<>(false);
-
- public StudyCheckAction() {
- super("Check Task (" + KeymapUtil.getShortcutText(new KeyboardShortcut(KeyStroke.getKeyStroke(SHORTCUT), null)) + ")", "Check current task", InteractiveLearningIcons.Resolve);
- }
-
- protected void check(@NotNull final Project project) {}
-
- @Override
- public void actionPerformed(@NotNull AnActionEvent e) {
- Project project = e.getProject();
- if (project == null) {
- return;
- }
- if (DumbService.isDumb(project)) {
- StudyCheckUtils.showTestResultPopUp("Checking is not available while indexing is in progress", MessageType.WARNING.getPopupBackground(), project);
- return;
- }
- check(project);
- }
-
- @Override
- public void update(AnActionEvent e) {
- final Presentation presentation = e.getPresentation();
- StudyUtils.updateAction(e);
- if (presentation.isEnabled()) {
- presentation.setEnabled(!myCheckInProgress.get());
- }
- }
-}
protected Task getTargetTask(@NotNull final Task sourceTask) {
return StudyNavigator.nextTask(sourceTask);
}
+
+ @Override
+ public String getActionId() {
+ return ACTION_ID;
+ }
+
+ @Override
+ public String[] getShortcuts() {
+ return new String[]{SHORTCUT};
+ }
}
\ No newline at end of file
}
return null;
}
+
+ @Override
+ public String getActionId() {
+ return ACTION_ID;
+ }
+
+ @Override
+ public String[] getShortcuts() {
+ return new String[]{SHORTCUT, SHORTCUT2};
+ }
}
}
return null;
}
+
+ @Override
+ public String getActionId() {
+ return ACTION_ID;
+ }
+
+ @Override
+ public String[] getShortcuts() {
+ return new String[]{SHORTCUT};
+ }
}
protected Task getTargetTask(@NotNull final Task sourceTask) {
return StudyNavigator.previousTask(sourceTask);
}
+
+ @Override
+ public String getActionId() {
+ return ACTION_ID;
+ }
+
+ @Override
+ public String[] getShortcuts() {
+ return new String[]{SHORTCUT};
+ }
}
\ No newline at end of file
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.keymap.KeymapUtil;
-import com.intellij.openapi.project.DumbAwareAction;
+import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.Messages;
import javax.swing.*;
-public class StudyRefreshTaskFileAction extends DumbAwareAction {
+public class StudyRefreshTaskFileAction extends StudyToolbarAction implements DumbAware {
public static final String ACTION_ID = "RefreshTaskAction";
public static final String SHORTCUT = "ctrl shift pressed X";
private static final Logger LOG = Logger.getInstance(StudyRefreshTaskFileAction.class.getName());
}
}
}
+
+ @Override
+ public String getActionId() {
+ return ACTION_ID;
+ }
+
+ @Override
+ public String[] getShortcuts() {
+ return new String[]{SHORTCUT};
+ }
}
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.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import javax.swing.*;
-public class StudyShowHintAction extends DumbAwareAction {
+public class StudyShowHintAction extends StudyToolbarAction implements DumbAware {
public static final String ACTION_ID = "ShowHintAction";
public static final String SHORTCUT = "ctrl pressed 7";
private static final String ourWarningMessage = "Put the caret in the answer placeholder to get hint";
public void update(@NotNull AnActionEvent e) {
StudyUtils.updateAction(e);
}
+
+ @Override
+ public String getActionId() {
+ return ACTION_ID;
+ }
+
+ @Override
+ public String[] getShortcuts() {
+ return new String[]{SHORTCUT};
+ }
}
import com.intellij.ide.projectView.ProjectView;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.fileEditor.FileEditorManager;
-import com.intellij.openapi.project.DumbAwareAction;
+import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.popup.Balloon;
import java.util.Map;
-abstract public class StudyTaskNavigationAction extends DumbAwareAction {
+abstract public class StudyTaskNavigationAction extends StudyToolbarAction implements DumbAware {
public StudyTaskNavigationAction(@Nullable String text, @Nullable String description, @Nullable Icon icon) {
super(text, description, icon);
}
--- /dev/null
+package com.jetbrains.edu.learning.actions;
+
+import com.intellij.openapi.actionSystem.AnAction;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+public abstract class StudyToolbarAction extends AnAction {
+ public StudyToolbarAction(@Nullable String text, @Nullable String description, @Nullable Icon icon) {
+ super(text, description, icon);
+ }
+
+ public abstract String getActionId();
+
+ public abstract String[] getShortcuts();
+}
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.LogicalPosition;
import com.intellij.openapi.fileEditor.FileDocumentManager;
-import com.intellij.openapi.project.DumbAwareAction;
+import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.jetbrains.edu.courseFormat.AnswerPlaceholder;
import javax.swing.*;
-abstract public class StudyWindowNavigationAction extends DumbAwareAction {
+abstract public class StudyWindowNavigationAction extends StudyToolbarAction implements DumbAware {
protected StudyWindowNavigationAction(String actionId, String description, Icon icon) {
super(actionId, description, icon);
<extensions defaultExtensionNs="com.intellij">
<directoryProjectGenerator implementation="com.jetbrains.edu.learning.PyStudyDirectoryProjectGenerator"/>
+ <applicationService serviceInterface="com.intellij.openapi.fileEditor.impl.EditorEmptyTextPainter"
+ serviceImplementation="com.jetbrains.edu.learning.PyStudyInstructionPainter" overrides="true"/>
</extensions>
<extensions defaultExtensionNs="Pythonid">
<inspectionExtension implementation="com.jetbrains.edu.learning.highlighting.PyStudyInspectionExtension"/>
<action id="StudyWatchTutorial" class="com.jetbrains.edu.learning.actions.PyStudyWatchTutorialAction">
<add-to-group group-id="HelpMenu" anchor="before" relative-to-action="HelpTopics"/>
</action>
+ <action class="com.jetbrains.edu.learning.PyStudyCheckAction" id="PyCheckAction"
+ />
</actions>
<project-components>
import com.intellij.execution.ExecutionException;
import com.intellij.openapi.actionSystem.ActionManager;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.KeyboardShortcut;
+import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
+import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.IdeFocusManager;
import com.jetbrains.edu.courseFormat.StudyStatus;
import com.jetbrains.edu.courseFormat.Task;
import com.jetbrains.edu.courseFormat.TaskFile;
-import com.jetbrains.edu.learning.actions.StudyCheckAction;
import com.jetbrains.edu.learning.actions.StudyRunAction;
+import com.jetbrains.edu.learning.actions.StudyToolbarAction;
import com.jetbrains.edu.learning.checker.StudyCheckTask;
import com.jetbrains.edu.learning.checker.StudyCheckUtils;
+import com.jetbrains.edu.learning.checker.StudyTestRunner;
import com.jetbrains.edu.learning.checker.StudyTestsOutputParser;
import com.jetbrains.edu.learning.editor.StudyEditor;
-import com.jetbrains.edu.learning.checker.StudyTestRunner;
+import icons.InteractiveLearningIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import javax.swing.*;
import java.util.Map;
-public class PyStudyCheckAction extends StudyCheckAction {
+public class PyStudyCheckAction extends StudyToolbarAction {
private static final Logger LOG = Logger.getInstance(PyStudyCheckAction.class);
+ public static final String ACTION_ID = "PyCheckAction";
+ public static final String SHORTCUT = "ctrl alt pressed ENTER";
+
+ protected Ref<Boolean> myCheckInProgress = new Ref<>(false);
+
+ public PyStudyCheckAction() {
+ super("Check Task (" + KeymapUtil.getShortcutText(new KeyboardShortcut(KeyStroke.getKeyStroke(SHORTCUT), null)) + ")", "Check current task", InteractiveLearningIcons.Resolve);
+ }
+
@Override
+ public void actionPerformed(@NotNull AnActionEvent e) {
+ Project project = e.getProject();
+ if (project == null) {
+ return;
+ }
+ if (DumbService.isDumb(project)) {
+ StudyCheckUtils.showTestResultPopUp("Checking is not available while indexing is in progress", MessageType.WARNING.getPopupBackground(), project);
+ return;
+ }
+ check(project);
+ }
+
protected void check(@NotNull Project project) {
ApplicationManager.getApplication().runWriteAction(() -> {
CommandProcessor.getInstance().runUndoTransparentAction(() -> {
}
return taskVirtualFile;
}
+
+
+
+ @Override
+ public String getActionId() {
+ return ACTION_ID;
+ }
+
+ @Override
+ public String[] getShortcuts() {
+ return new String[]{SHORTCUT};
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ final Presentation presentation = e.getPresentation();
+ StudyUtils.updateAction(e);
+ if (presentation.isEnabled()) {
+ presentation.setEnabled(!myCheckInProgress.get());
+ }
+ }
}
--- /dev/null
+package com.jetbrains.edu.learning;
+
+import com.intellij.openapi.actionSystem.KeyboardShortcut;
+import com.intellij.openapi.fileEditor.impl.EditorEmptyTextPainter;
+import com.intellij.openapi.keymap.KeymapUtil;
+import com.intellij.util.ui.UIUtil;
+import com.jetbrains.edu.learning.actions.*;
+import com.jetbrains.edu.learning.ui.StudyProgressToolWindowFactory;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+
+public class PyStudyInstructionPainter extends EditorEmptyTextPainter {
+ private static final String separator = " / ";
+ @Override
+ protected void advertiseActions(@NotNull JComponent splitters, @NotNull UIUtil.TextPainter painter) {
+ String shortcut = KeymapUtil.getShortcutText(new KeyboardShortcut(KeyStroke.getKeyStroke(StudyNextWindowAction.SHORTCUT2), null));
+ appendAction(painter, "Navigate to the next answer placeholder", shortcut);
+ appendAction(painter, "Navigate between answer placeholders", getActionShortcutText(StudyPrevWindowAction.ACTION_ID) + separator +
+ getActionShortcutText(StudyNextWindowAction.ACTION_ID));
+ appendAction(painter, "Navigate between tasks", getActionShortcutText(StudyPreviousStudyTaskAction.ACTION_ID) + separator +
+ getActionShortcutText(StudyNextStudyTaskAction.ACTION_ID));
+ appendAction(painter, "Reset current task file", getActionShortcutText(StudyRefreshTaskFileAction.ACTION_ID));
+ appendAction(painter, "Check task", getActionShortcutText(PyStudyCheckAction.ACTION_ID));
+ appendAction(painter, "Get hint for the answer placeholder", getActionShortcutText(StudyShowHintAction.ACTION_ID));
+ appendLine(painter, "To see your progress open the '" + StudyProgressToolWindowFactory.ID + "' panel");
+ }
+}
\ No newline at end of file