move via dnd in packages view: adjust target container (IDEA-61949)

This commit is contained in:
anna
2011-02-11 11:23:33 +01:00
parent fc96f928ed
commit 0b4bc546e0
9 changed files with 68 additions and 4 deletions
@@ -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)) {
@@ -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();
}
}
@@ -50,6 +50,7 @@ public class LangDataKeys extends PlatformDataKeys {
public static final DataKey<Condition<AnAction>> PRESELECT_NEW_ACTION_CONDITION = DataKey.create("newElementAction.preselect.id");
public static final DataKey<PsiElement> TARGET_PSI_ELEMENT = DataKey.create("psi.TargetElement");
public static final DataKey<Module> TARGET_MODULE = DataKey.create("module.TargetModule");
public static final DataKey<PsiElement> PASTE_TARGET_PSI_ELEMENT = DataKey.create("psi.pasteTargetElement");
public static final DataKey<ConsoleView> CONSOLE_VIEW = DataKey.create("consoleView");
@@ -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();
}
@@ -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();
@@ -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;
}
@@ -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);
}
@@ -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;
}
}
@@ -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;