/* * 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 sourceRoots = new HashSet(); 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() { 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(); } } }