From 0b4bc546e00f62b5eb1e8cdaf650c9bc5fb54601 Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 11 Feb 2011 11:21:09 +0100 Subject: [PATCH] move via dnd in packages view: adjust target container (IDEA-61949) --- .../ide/projectView/impl/PackageViewPane.java | 8 +++++++ .../MoveClassesOrPackagesHandlerBase.java | 24 +++++++++++++++++++ .../openapi/actionSystem/LangDataKeys.java | 1 + .../com/intellij/ide/CopyPasteDelegator.java | 2 +- .../impl/AbstractProjectViewPane.java | 15 ++++++++++++ .../impl/ProjectViewDropTarget.java | 9 +++++++ .../ide/projectView/impl/PsiRetriever.java | 3 +++ .../refactoring/move/MoveHandler.java | 6 ++--- .../refactoring/move/MoveHandlerDelegate.java | 4 ++++ 9 files changed, 68 insertions(+), 4 deletions(-) diff --git a/java/java-impl/src/com/intellij/ide/projectView/impl/PackageViewPane.java b/java/java-impl/src/com/intellij/ide/projectView/impl/PackageViewPane.java index 89fd090a2461..da3018d5abea 100644 --- a/java/java-impl/src/com/intellij/ide/projectView/impl/PackageViewPane.java +++ b/java/java-impl/src/com/intellij/ide/projectView/impl/PackageViewPane.java @@ -92,6 +92,14 @@ public final class PackageViewPane extends AbstractProjectViewPSIPane { return super.getPSIElement(element); } + @Override + protected Module getNodeModule(@Nullable Object element) { + if (element instanceof PackageElement) { + return ((PackageElement)element).getModule(); + } + return super.getNodeModule(element); + } + @Override public Object getData(final String dataId) { if (PlatformDataKeys.DELETE_ELEMENT_PROVIDER.is(dataId)) { diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesHandlerBase.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesHandlerBase.java index 77dec22f9753..005ab5c7b057 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesHandlerBase.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesHandlerBase.java @@ -20,12 +20,15 @@ import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.impl.file.JavaDirectoryServiceImpl; import com.intellij.psi.impl.source.jsp.jspJava.JspClass; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.refactoring.JavaRefactoringSettings; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.move.MoveHandlerDelegate; @@ -147,11 +150,32 @@ public class MoveClassesOrPackagesHandlerBase extends MoveHandlerDelegate { MoveClassesOrPackagesImpl.doMove(project, elements, targetContainer, callback); } + @Override + public PsiElement adjustTargetForMove(DataContext dataContext, PsiElement targetContainer) { + if (targetContainer instanceof PsiPackage) { + final Module module = LangDataKeys.TARGET_MODULE.getData(dataContext); + if (module != null) { + final PsiDirectory[] directories = ((PsiPackage)targetContainer).getDirectories(GlobalSearchScope.moduleScope(module)); + if (directories.length > 0) { + return directories[0]; + } + } + } + return super.adjustTargetForMove(dataContext, targetContainer); + } + private static boolean tryDirectoryMove(Project project, final PsiElement[] sourceElements, final PsiElement targetElement, final MoveCallback callback) { if (targetElement instanceof PsiDirectory) { final PsiElement[] adjustedElements = MoveClassesOrPackagesImpl.adjustForMove(project, sourceElements, targetElement); if (adjustedElements != null) { if ( CommonRefactoringUtil.checkReadOnlyStatusRecursively(project, Arrays.asList(adjustedElements),true) ) { + final PsiPackage psiPackage = JavaDirectoryService.getInstance().getPackage((PsiDirectory)targetElement); + if (psiPackage != null) { + final Module module = ModuleUtil.findModuleForFile(((PsiDirectory)targetElement).getVirtualFile(), project); + if (module != null) { + if (psiPackage.getDirectories(GlobalSearchScope.moduleScope(module)).length > 1) return false; + } + } new MoveClassesOrPackagesToNewDirectoryDialog((PsiDirectory)targetElement, adjustedElements, callback).show(); } } diff --git a/platform/lang-api/src/com/intellij/openapi/actionSystem/LangDataKeys.java b/platform/lang-api/src/com/intellij/openapi/actionSystem/LangDataKeys.java index 4504cfbc42ec..a3177313d9fa 100644 --- a/platform/lang-api/src/com/intellij/openapi/actionSystem/LangDataKeys.java +++ b/platform/lang-api/src/com/intellij/openapi/actionSystem/LangDataKeys.java @@ -50,6 +50,7 @@ public class LangDataKeys extends PlatformDataKeys { public static final DataKey> PRESELECT_NEW_ACTION_CONDITION = DataKey.create("newElementAction.preselect.id"); public static final DataKey TARGET_PSI_ELEMENT = DataKey.create("psi.TargetElement"); + public static final DataKey TARGET_MODULE = DataKey.create("module.TargetModule"); public static final DataKey PASTE_TARGET_PSI_ELEMENT = DataKey.create("psi.pasteTargetElement"); public static final DataKey CONSOLE_VIEW = DataKey.create("consoleView"); diff --git a/platform/lang-impl/src/com/intellij/ide/CopyPasteDelegator.java b/platform/lang-impl/src/com/intellij/ide/CopyPasteDelegator.java index cfd449c6a4b9..5d32f8043413 100644 --- a/platform/lang-impl/src/com/intellij/ide/CopyPasteDelegator.java +++ b/platform/lang-impl/src/com/intellij/ide/CopyPasteDelegator.java @@ -142,7 +142,7 @@ public abstract class CopyPasteDelegator implements CopyPasteSupport { } } else if (MoveHandler.canMove(elements, target)) { - MoveHandler.doMove(myProject, elements, target, new MoveCallback() { + MoveHandler.doMove(myProject, elements, target, dataContext, new MoveCallback() { public void refactoringCompleted() { PsiCopyPasteManager.getInstance().clear(); } diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/AbstractProjectViewPane.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/AbstractProjectViewPane.java index 8bd4660eed16..66d20c3597df 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/AbstractProjectViewPane.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/AbstractProjectViewPane.java @@ -39,6 +39,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.util.*; @@ -321,6 +322,15 @@ public abstract class AbstractProjectViewPane implements DataProvider, Disposabl return null; } + @Nullable + protected Module getNodeModule(@Nullable final Object element) { + if (element instanceof PsiElement) { + PsiElement psiElement = (PsiElement)element; + return ModuleUtil.findModuleForPsiElement(psiElement); + } + return null; + } + @NotNull public final Object[] getSelectedElements() { TreePath[] paths = getSelectionPaths(); @@ -521,6 +531,11 @@ public abstract class AbstractProjectViewPane implements DataProvider, Disposabl public PsiElement getPsiElement(@Nullable TreeNode node) { return getPSIElement(getElement(node)); } + + @Override + public Module getModule(TreeNode treeNode) { + return getNodeModule(getElement(treeNode)); + } }, myProject); myDragSource = new MyDragSource(); myDndManager = DnDManager.getInstance(); diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewDropTarget.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewDropTarget.java index 9bb6edd27b0c..db5baf7bee80 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewDropTarget.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewDropTarget.java @@ -21,6 +21,7 @@ import com.intellij.ide.dnd.DnDNativeTarget; import com.intellij.ide.projectView.impl.nodes.DropTargetNode; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.vfs.LocalFileSystem; @@ -225,6 +226,10 @@ class ProjectViewDropTarget implements DnDNativeTarget { return myPsiRetriever.getPsiElement(treeNode); } + protected Module getModule(@Nullable final TreeNode treeNode) { + return myPsiRetriever.getModule(treeNode); + } + public abstract class MoveCopyDropHandler implements DropHandler { public boolean isValidSource(@NotNull final TreeNode[] sourceNodes, TreeNode targetNode) { @@ -306,10 +311,14 @@ class ProjectViewDropTarget implements DnDNativeTarget { private void doDrop(TreeNode targetNode, PsiElement[] sourceElements, final boolean externalDrop) { final PsiElement targetElement = getPsiElement(targetNode); if (targetElement == null) return; + final Module module = getModule(targetNode); final DataContext dataContext = DataManager.getInstance().getDataContext(myTree); getActionHandler().invoke(myProject, sourceElements, new DataContext() { @Nullable public Object getData(@NonNls String dataId) { + if (LangDataKeys.TARGET_MODULE.is(dataId)) { + if (module != null) return module; + } if (LangDataKeys.TARGET_PSI_ELEMENT.is(dataId)) { return targetElement; } diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/PsiRetriever.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/PsiRetriever.java index 0bb169585a9a..0c8dae2588f4 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/PsiRetriever.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/PsiRetriever.java @@ -16,6 +16,7 @@ package com.intellij.ide.projectView.impl; +import com.intellij.openapi.module.Module; import org.jetbrains.annotations.Nullable; import com.intellij.psi.PsiElement; @@ -24,4 +25,6 @@ import javax.swing.tree.TreeNode; public interface PsiRetriever { @Nullable PsiElement getPsiElement(@Nullable TreeNode node); + + Module getModule(TreeNode treeNode); } diff --git a/platform/lang-impl/src/com/intellij/refactoring/move/MoveHandler.java b/platform/lang-impl/src/com/intellij/refactoring/move/MoveHandler.java index 83fae915d0ca..3459025bc838 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/move/MoveHandler.java +++ b/platform/lang-impl/src/com/intellij/refactoring/move/MoveHandler.java @@ -113,18 +113,18 @@ public class MoveHandler implements RefactoringActionHandler { .doMove(project, filesOrDirs.toArray(new PsiElement[filesOrDirs.size()]), new PsiElement[]{targetContainer}, null); return; } - doMove(project, elements, targetContainer, null); + doMove(project, elements, targetContainer, dataContext, null); } /** * must be invoked in AtomicAction */ - public static void doMove(Project project, @NotNull PsiElement[] elements, PsiElement targetContainer, MoveCallback callback) { + public static void doMove(Project project, @NotNull PsiElement[] elements, PsiElement targetContainer, DataContext dataContext, MoveCallback callback) { if (elements.length == 0) return; for(MoveHandlerDelegate delegate: Extensions.getExtensions(MoveHandlerDelegate.EP_NAME)) { if (delegate.canMove(elements, targetContainer)) { - delegate.doMove(project, elements, targetContainer, callback); + delegate.doMove(project, elements, delegate.adjustTargetForMove(dataContext, targetContainer), callback); break; } } diff --git a/platform/lang-impl/src/com/intellij/refactoring/move/MoveHandlerDelegate.java b/platform/lang-impl/src/com/intellij/refactoring/move/MoveHandlerDelegate.java index 7181e2ae5863..2fb026e02501 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/move/MoveHandlerDelegate.java +++ b/platform/lang-impl/src/com/intellij/refactoring/move/MoveHandlerDelegate.java @@ -48,6 +48,10 @@ public abstract class MoveHandlerDelegate { @Nullable final PsiElement targetContainer, @Nullable final MoveCallback callback) { } + public PsiElement adjustTargetForMove(DataContext dataContext, PsiElement targetContainer) { + return targetContainer; + } + @Nullable public PsiElement[] adjustForMove(Project project, PsiElement[] sourceElements, PsiElement targetElement) { return sourceElements;