diff --git a/python/educational/interactive-learning/resources/META-INF/plugin.xml b/python/educational/interactive-learning/resources/META-INF/plugin.xml
index 6fdccd8fa81d..bb1adde38e47 100644
--- a/python/educational/interactive-learning/resources/META-INF/plugin.xml
+++ b/python/educational/interactive-learning/resources/META-INF/plugin.xml
@@ -61,9 +61,6 @@
text="Fill Answer Placeholders">
-
@@ -86,6 +83,7 @@
-
+
+
\ No newline at end of file
diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyRenameHandler.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyRenameHandler.java
new file mode 100644
index 000000000000..f550acb8f8f0
--- /dev/null
+++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyRenameHandler.java
@@ -0,0 +1,46 @@
+package com.jetbrains.edu.learning;
+
+import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.refactoring.rename.RenameHandler;
+import com.jetbrains.edu.courseFormat.Course;
+import org.jetbrains.annotations.NotNull;
+
+public class StudyRenameHandler implements RenameHandler {
+ @Override
+ public boolean isAvailableOnDataContext(DataContext dataContext) {
+ Project project = CommonDataKeys.PROJECT.getData(dataContext);
+ PsiElement element = CommonDataKeys.PSI_ELEMENT.getData(dataContext);
+ if (element == null || project == null) {
+ return false;
+ }
+ Course course = StudyTaskManager.getInstance(project).getCourse();
+ if (course == null) {
+ return false;
+ }
+ if (!StudyUtils.isRenameableOrMoveable(project, course, element)) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean isRenaming(DataContext dataContext) {
+ return isAvailableOnDataContext(dataContext);
+ }
+
+ @Override
+ public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) {
+ Messages.showWarningDialog("This rename operation can break the course", "Invalid Rename Operation");
+ }
+
+ @Override
+ public void invoke(@NotNull Project project, @NotNull PsiElement[] elements, DataContext dataContext) {
+ invoke(project, null, null, dataContext);
+ }
+}
diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyUtils.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyUtils.java
index 07dbaa86d7e9..09ea82ce9691 100644
--- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyUtils.java
+++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyUtils.java
@@ -25,6 +25,9 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.ToolWindowManager;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
import com.intellij.ui.JBColor;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.util.ui.UIUtil;
@@ -334,4 +337,37 @@ public class StudyUtils {
}
return FileDocumentManager.getInstance().getDocument(patternFile);
}
+
+ public static boolean isRenameableOrMoveable(@NotNull final Project project, @NotNull final Course course, @NotNull final PsiElement element) {
+ if (element instanceof PsiFile) {
+ VirtualFile virtualFile = ((PsiFile)element).getVirtualFile();
+ if (project.getBaseDir().equals(virtualFile.getParent())) {
+ return false;
+ }
+ TaskFile file = getTaskFile(project, virtualFile);
+ if (file != null) {
+ return false;
+ }
+ String name = virtualFile.getName();
+ return !isTestsFile(project, name) && !EduNames.TASK_HTML.equals(name);
+ }
+ if (element instanceof PsiDirectory) {
+ VirtualFile virtualFile = ((PsiDirectory)element).getVirtualFile();
+ VirtualFile parent = virtualFile.getParent();
+ if (parent == null) {
+ return true;
+ }
+ if (project.getBaseDir().equals(parent)) {
+ return false;
+ }
+ Lesson lesson = course.getLesson(parent.getName());
+ if (lesson != null) {
+ Task task = lesson.getTask(virtualFile.getName());
+ if (task != null) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
}
diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyRenameTaskFileAction.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyRenameTaskFileAction.java
deleted file mode 100644
index 9ece19124cc2..000000000000
--- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/actions/StudyRenameTaskFileAction.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.jetbrains.edu.learning.actions;
-
-import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.actionSystem.DataContext;
-import com.intellij.psi.PsiDirectory;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
-import com.intellij.refactoring.actions.RenameElementAction;
-import com.jetbrains.edu.learning.StudyUtils;
-import org.jetbrains.annotations.NotNull;
-
-public class StudyRenameTaskFileAction extends RenameElementAction {
- @Override
- protected boolean isEnabledOnDataContext(DataContext dataContext) {
- PsiElement element = CommonDataKeys.PSI_ELEMENT.getData(dataContext);
- return super.isEnabledOnDataContext(dataContext) && !isTaskFile(element);
- }
-
- private static boolean isTaskFile(PsiElement element) {
- if (element == null || element instanceof PsiDirectory) {
- return false;
- }
- PsiFile file = element.getContainingFile();
- return file != null && StudyUtils.getTaskFile(element.getProject(), file.getVirtualFile()) != null;
- }
-
- @Override
- public boolean isEnabledOnElements(@NotNull PsiElement[] elements){
- return !super.isEnabledOnElements(elements) && !isTaskFile(elements[0]);
- }
-}