blob: de16039b99b2863f9f3d3bc67b6dfcc68b715944 [file] [log] [blame]
/*
* Copyright 2000-2012 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.intellij.refactoring.move.moveClassesOrPackages;
import com.intellij.ide.util.DirectoryUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileChooser.FileChooser;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.refactoring.JavaRefactoringFactory;
import com.intellij.refactoring.JavaRefactoringSettings;
import com.intellij.refactoring.MoveDestination;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.move.MoveCallback;
import com.intellij.refactoring.move.MoveHandler;
import com.intellij.ui.DocumentAdapter;
import com.intellij.usageView.UsageViewUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashSet;
import java.util.Set;
/**
* @author ven
*/
public class MoveClassesOrPackagesToNewDirectoryDialog extends DialogWrapper {
private static final Logger LOG = Logger.getInstance("com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesToNewDirectoryDialog");
private final PsiDirectory myDirectory;
private final PsiElement[] myElementsToMove;
private final MoveCallback myMoveCallback;
public MoveClassesOrPackagesToNewDirectoryDialog(@NotNull final PsiDirectory directory, PsiElement[] elementsToMove,
final MoveCallback moveCallback) {
this(directory, elementsToMove, true, moveCallback);
}
public MoveClassesOrPackagesToNewDirectoryDialog(@NotNull final PsiDirectory directory, PsiElement[] elementsToMove,
boolean canShowPreserveSourceRoots,
final MoveCallback moveCallback) {
super(false);
setTitle(MoveHandler.REFACTORING_NAME);
myDirectory = directory;
myElementsToMove = elementsToMove;
myMoveCallback = moveCallback;
myDestDirectoryField.setText(FileUtil.toSystemDependentName(directory.getVirtualFile().getPath()));
final FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor();
myDestDirectoryField.getButton().addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
final VirtualFile file = FileChooser.chooseFile(descriptor, myDirectory.getProject(), directory.getVirtualFile());
if (file != null) {
myDestDirectoryField.setText(FileUtil.toSystemDependentName(file.getPath()));
}
}
});
if (elementsToMove.length == 1) {
PsiElement firstElement = elementsToMove[0];
myNameLabel.setText(RefactoringBundle.message("move.single.class.or.package.name.label", UsageViewUtil.getType(firstElement),
UsageViewUtil.getLongName(firstElement)));
}
else if (elementsToMove.length > 1) {
myNameLabel.setText(elementsToMove[0] instanceof PsiClass
? RefactoringBundle.message("move.specified.classes")
: RefactoringBundle.message("move.specified.packages"));
}
final JavaRefactoringSettings refactoringSettings = JavaRefactoringSettings.getInstance();
mySearchInCommentsAndStringsCheckBox.setSelected(refactoringSettings.MOVE_SEARCH_IN_COMMENTS);
mySearchForTextOccurrencesCheckBox.setSelected(refactoringSettings.MOVE_SEARCH_FOR_TEXT);
myDestDirectoryField.getTextField().getDocument().addDocumentListener(new DocumentAdapter() {
public void textChanged(DocumentEvent event) {
setOKActionEnabled(myDestDirectoryField.getText().length() > 0);
}
});
if (canShowPreserveSourceRoots) {
final Set<VirtualFile> sourceRoots = new HashSet<VirtualFile>();
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(directory.getProject()).getFileIndex();
final Module destinationModule = fileIndex.getModuleForFile(directory.getVirtualFile());
boolean sameModule = true;
for (PsiElement element : elementsToMove) {
if (element instanceof PsiPackage) {
for (PsiDirectory psiDirectory : ((PsiPackage)element).getDirectories()) {
final VirtualFile virtualFile = psiDirectory.getVirtualFile();
sourceRoots.add(fileIndex.getSourceRootForFile(virtualFile));
//sameModule &= destinationModule == fileIndex.getModuleForFile(virtualFile);
}
} else if (element instanceof PsiClass) {
final VirtualFile virtualFile = element.getContainingFile().getVirtualFile();
LOG.assertTrue(virtualFile != null);
sourceRoots.add(fileIndex.getSourceRootForFile(virtualFile));
sameModule &= destinationModule == fileIndex.getModuleForFile(virtualFile);
}
}
myPreserveSourceRoot.setVisible(sourceRoots.size() > 1);
myPreserveSourceRoot.setSelected(sameModule);
}
init();
}
private TextFieldWithBrowseButton myDestDirectoryField;
private JCheckBox mySearchForTextOccurrencesCheckBox;
private JCheckBox mySearchInCommentsAndStringsCheckBox;
private JPanel myRootPanel;
private JLabel myNameLabel;
private JCheckBox myPreserveSourceRoot;
private boolean isSearchInNonJavaFiles() {
return mySearchForTextOccurrencesCheckBox.isSelected();
}
private boolean isSearchInComments() {
return mySearchInCommentsAndStringsCheckBox.isSelected();
}
@Nullable
protected JComponent createCenterPanel() {
return myRootPanel;
}
protected void doOKAction() {
final String path = FileUtil.toSystemIndependentName(myDestDirectoryField.getText());
final Project project = myDirectory.getProject();
PsiDirectory directory = ApplicationManager.getApplication().runWriteAction(new Computable<PsiDirectory>() {
public PsiDirectory compute() {
try {
return DirectoryUtil.mkdirs(PsiManager.getInstance(project), path);
}
catch (IncorrectOperationException e) {
LOG.error(e);
return null;
}
}
});
if (directory == null) {
Messages.showErrorDialog(project, RefactoringBundle.message("cannot.find.or.create.destination.directory"),
RefactoringBundle.message("cannot.move"));
return;
}
super.doOKAction();
final PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(directory);
if (aPackage == null) {
Messages.showErrorDialog(project, RefactoringBundle.message("destination.directory.does.not.correspond.to.any.package"),
RefactoringBundle.message("cannot.move"));
return;
}
final JavaRefactoringSettings refactoringSettings = JavaRefactoringSettings.getInstance();
final boolean searchInComments = isSearchInComments();
final boolean searchForTextOccurences = isSearchInNonJavaFiles();
refactoringSettings.MOVE_SEARCH_IN_COMMENTS = searchInComments;
refactoringSettings.MOVE_SEARCH_FOR_TEXT = searchForTextOccurences;
performRefactoring(project, directory, aPackage, searchInComments, searchForTextOccurences);
}
@Override
public JComponent getPreferredFocusedComponent() {
return myDestDirectoryField.getTextField();
}
//for scala plugin
@NotNull
protected MoveClassesOrPackagesProcessor createMoveClassesOrPackagesProcessor(Project project,
PsiElement[] elements,
@NotNull final MoveDestination moveDestination,
boolean searchInComments,
boolean searchInNonJavaFiles,
MoveCallback moveCallback) {
return new MoveClassesOrPackagesProcessor(project, elements, moveDestination,
searchInComments, searchInNonJavaFiles, moveCallback);
}
protected void performRefactoring(Project project, PsiDirectory directory, PsiPackage aPackage,
boolean searchInComments,
boolean searchForTextOccurences) {
final VirtualFile sourceRoot = ProjectRootManager.getInstance(project).getFileIndex().getSourceRootForFile(directory.getVirtualFile());
if (sourceRoot == null) {
Messages.showErrorDialog(project, RefactoringBundle.message("destination.directory.does.not.correspond.to.any.package"),
RefactoringBundle.message("cannot.move"));
return;
}
final JavaRefactoringFactory factory = JavaRefactoringFactory.getInstance(project);
final MoveDestination destination = myPreserveSourceRoot.isSelected() && myPreserveSourceRoot.isVisible()
? factory.createSourceFolderPreservingMoveDestination(aPackage.getQualifiedName())
: factory.createSourceRootMoveDestination(aPackage.getQualifiedName(), sourceRoot);
MoveClassesOrPackagesProcessor processor = createMoveClassesOrPackagesProcessor(myDirectory.getProject(), myElementsToMove, destination,
searchInComments, searchForTextOccurences, myMoveCallback);
if (processor.verifyValidPackageName()) {
processor.setPrepareSuccessfulSwingThreadCallback(new Runnable() {
@Override
public void run() {
}
});
processor.run();
}
}
}